From f01ff866c53237a05d892af3a6c9d87f19599ba2 Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 17:39:06 +0200 Subject: [PATCH 01/10] starting bot md --- Bot.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Bot.md diff --git a/Bot.md b/Bot.md new file mode 100644 index 000000000..868f2646e --- /dev/null +++ b/Bot.md @@ -0,0 +1,19 @@ +# Bot documentation + +A bot in this bomberman is using a lua script as way to choose what to do +So you can make your own with some helper functions given from C++ + +## Registered functions + +```lua +"getMap" +"getDanger" +"getPath" +"getPlayer" +"getPlayerRound" +"getDangerLevelPlayer" +"getDangerLevel" +"getBlockType" +"getClosestSafeSpace" +"canPutBombSafe" +``` \ No newline at end of file From 1255ca8b8e074338a748188291d45044ed240323 Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 17:49:36 +0200 Subject: [PATCH 02/10] functions --- Bot.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/Bot.md b/Bot.md index 868f2646e..fa7423c53 100644 --- a/Bot.md +++ b/Bot.md @@ -3,17 +3,55 @@ A bot in this bomberman is using a lua script as way to choose what to do So you can make your own with some helper functions given from C++ +## Map Blocks + +```lua +nothing = 0 +breakable = 1 +hole = 2 +bumper = 4 +unbreakable = 7 +bomb = 10 +``` + ## Registered functions ```lua -"getMap" -"getDanger" -"getPath" -"getPlayer" -"getPlayerRound" -"getDangerLevelPlayer" -"getDangerLevel" -"getBlockType" -"getClosestSafeSpace" -"canPutBombSafe" +-- getMap returns a table of the blocks of the map +-- From 1 to 17 {{0, 1, 2 ..}, ..} +function getMap(); + +-- getDanger returns a table of the danger zone on the map +-- From 1 to 17 {{0, 1, 2 ..}, ..} +-- value is number of seconds before explosion +function getDanger(); + +-- getPath returns a table of nodes of a path from A to B +-- @param x1 should be int +-- @param y1 should be int +-- @param x2 should be int +-- @param y2 should be int +function getPath(x1, y1, x2, y2); + +-- getPlayer returns player pos as {x = xPlayer, y = yPlayer} +function getPlayer(); + +-- getPlayerRound returns player pos with rounded value {x = xPlayer, y = yPlayer} +function getPlayerRound(); + +-- getDangerLevel returns danger level at [xpos, ypos] +function getDangerLevel(xpos, ypos); + +-- getDangerLevelPlayer get danger level on the position of the player +function getDangerLevelPlayer(); + +-- getBlockType returns block type at [xpos, ypos] +function getBlockType(); + +-- getClosestSafeSpace returns the block next to player where the player should go to to the closest safe space +-- returns player pos if no path is found +function getClosestSafeSpace(); + +-- canPutBombSafe returns true if player can put a bomb and find a path to safe space if bomb is put +function canPutBombSafe(); ``` \ No newline at end of file From fca2c7137f934e2714e2b20dc26e41e904969c2d Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 17:50:33 +0200 Subject: [PATCH 03/10] functions --- Bot.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Bot.md b/Bot.md index fa7423c53..9c04ca050 100644 --- a/Bot.md +++ b/Bot.md @@ -26,7 +26,7 @@ function getMap(); -- value is number of seconds before explosion function getDanger(); --- getPath returns a table of nodes of a path from A to B +-- getPath returns a table of nodes of a path from A to B {{x = X, y = Y}, ...} -- @param x1 should be int -- @param y1 should be int -- @param x2 should be int @@ -46,7 +46,7 @@ function getDangerLevel(xpos, ypos); function getDangerLevelPlayer(); -- getBlockType returns block type at [xpos, ypos] -function getBlockType(); +function getBlockType(xpos, ypos); -- getClosestSafeSpace returns the block next to player where the player should go to to the closest safe space -- returns player pos if no path is found From 8f081e53ab873ab8170172aad67c929bd36ac205 Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 21:28:42 +0200 Subject: [PATCH 04/10] get radius, get enemies get enemies round --- assets/ai_scripts/john.lua | 16 +++++++ sources/Map/LuaMap.cpp | 48 +++++++++++++++++++ sources/Map/LuaMap.hpp | 12 +++++ .../IAControllable/IAControllableSystem.cpp | 9 +++- 4 files changed, 83 insertions(+), 2 deletions(-) diff --git a/assets/ai_scripts/john.lua b/assets/ai_scripts/john.lua index f0a01d064..a77ad6f00 100644 --- a/assets/ai_scripts/john.lua +++ b/assets/ai_scripts/john.lua @@ -137,6 +137,22 @@ function Update() end end + local enemies = getEnemies() + local enemiesRound = getEnemiesRound() + + log("enemies") + for i, v in ipairs(enemies) do + log("enemy") + log(v.x) + log(v.y) + end + log("enemies ROUND") + for i, v in ipairs(enemiesRound) do + log("enemy ROUND") + log(v.x) + log(v.y) + end + log("player") log(player.x) log(player.y) diff --git a/sources/Map/LuaMap.cpp b/sources/Map/LuaMap.cpp index 33ffdc3b3..04232bd1a 100644 --- a/sources/Map/LuaMap.cpp +++ b/sources/Map/LuaMap.cpp @@ -319,6 +319,54 @@ namespace BBM return 1; } + int LuaMap::getRadius(lua_State *L) + { + LuaG::State state(L); + const LuaMap *map = reinterpret_cast(state.getPointer(state.getFirstUpValueIdx())); + state.push(map->currRadius); + return 1; + } + + int LuaMap::getEnemies(lua_State *L) + { + LuaG::State state(L); + const LuaMap *map = reinterpret_cast(state.getPointer(state.getFirstUpValueIdx())); + int index = 1; + state.newTable(); + for (auto &r : map->_enemies) { + state.push(index++); + state.newTable(); + state.push("x"); + state.push(r.x); + state.setTable(); + state.push("y"); + state.push(r.y); + state.setTable(); + state.setTable(); + } + return 1; + } + + int LuaMap::getEnemiesRound(lua_State *L) + { + LuaG::State state(L); + const LuaMap *map = reinterpret_cast(state.getPointer(state.getFirstUpValueIdx())); + int index = 1; + state.newTable(); + for (auto &r : map->_enemies) { + state.push(index++); + state.newTable(); + state.push("x"); + state.push(std::round(r.x)); + state.setTable(); + state.push("y"); + state.push(std::round(r.y)); + state.setTable(); + state.setTable(); + } + return 1; return 1; + } + int LuaMap::canPutBomb(lua_State *L) { LuaG::State state(L); diff --git a/sources/Map/LuaMap.hpp b/sources/Map/LuaMap.hpp index 43719e394..46765d20a 100644 --- a/sources/Map/LuaMap.hpp +++ b/sources/Map/LuaMap.hpp @@ -63,6 +63,15 @@ namespace BBM //! @brief Check if current player can put a bomb with an escape static int canPutBomb(lua_State *L); + //! @brief Get current explosion radius of the player + static int getRadius(lua_State *L); + + //! @brief Get enemies position + static int getEnemies(lua_State *L); + + //! @brief Get enemies position rounded + static int getEnemiesRound(lua_State *L); + //! @brief map blocks in 2D grid std::vector> _map; @@ -72,6 +81,9 @@ namespace BBM //! @brief player position Vector2f _player; + //! @brief other players position + std::vector _enemies; + //! @brief rounded player position Vector2f _roundedPlayer; diff --git a/sources/System/IAControllable/IAControllableSystem.cpp b/sources/System/IAControllable/IAControllableSystem.cpp index 6d67c3bb1..55056b3e4 100644 --- a/sources/System/IAControllable/IAControllableSystem.cpp +++ b/sources/System/IAControllable/IAControllableSystem.cpp @@ -19,11 +19,13 @@ namespace BBM void IAControllableSystem::UpdateMapInfos(WAL::ViewEntity &entity) { - _players.clear(); + _luamap._enemies.clear(); if (!_wal.getScene()) return; for (auto &[other, pos, _] : _wal.getScene()->view()) { - _players.push_back(MapInfo(pos.position, MapGenerator::NOTHING)); + if (other == entity) + continue; + _luamap._enemies.push_back(Vector2f(pos.position.x, pos.position.z)); } if (_cached) return; @@ -86,6 +88,9 @@ namespace BBM state.registerClosure(&_luamap, "getBlockType", LuaMap::getBlockType); state.registerClosure(&_luamap, "getClosestSafeSpace", LuaMap::getClosestSafeSpace); state.registerClosure(&_luamap, "canPutBombSafe", LuaMap::canPutBomb); + state.registerClosure(&_luamap, "getRadius", LuaMap::getRadius); + state.registerClosure(&_luamap, "getEnemies", LuaMap::getEnemies); + state.registerClosure(&_luamap, "getEnemiesRound", LuaMap::getEnemiesRound); } void IAControllableSystem::onFixedUpdate(WAL::ViewEntity &entity) From 605a795f338df6f3581e04b7a4ec2ee087731c04 Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 21:42:20 +0200 Subject: [PATCH 05/10] update bot.md --- Bot.md | 16 ++++++++++ assets/ai_scripts/john.lua | 65 -------------------------------------- 2 files changed, 16 insertions(+), 65 deletions(-) diff --git a/Bot.md b/Bot.md index 9c04ca050..1d1d08acc 100644 --- a/Bot.md +++ b/Bot.md @@ -3,6 +3,13 @@ A bot in this bomberman is using a lua script as way to choose what to do So you can make your own with some helper functions given from C++ +## Update function + +Each frame, the game will call the "Update" function in the script. +This is the same lua state as the last call so this means you can set global variables to keep data between frames + +Update function should take no arguments. + ## Map Blocks ```lua @@ -54,4 +61,13 @@ function getClosestSafeSpace(); -- canPutBombSafe returns true if player can put a bomb and find a path to safe space if bomb is put function canPutBombSafe(); + +-- getRadius returns the explosion radius of the current player +function getRadius(); + +-- getEnemies returns a table with enemies position {{x = X, y = Y}, ...} +function getEnemies(); + +-- getEnemies returns a table with enemies position rounded {{x = X, y = Y}, ...} +function getEnemiesRound(); ``` \ No newline at end of file diff --git a/assets/ai_scripts/john.lua b/assets/ai_scripts/john.lua index a77ad6f00..f3a6522e1 100644 --- a/assets/ai_scripts/john.lua +++ b/assets/ai_scripts/john.lua @@ -41,71 +41,6 @@ function PrintMap(map, MaxX, maxZ) end end -function getNeighborsDefend(node) - local neighbors = {} - for _, dir in ipairs(Dirs) do - local neighborX = node.x + dir.x - local neighborY = node.y + dir.y - if neighborY <= MaxY and neighborX <= MaxX then - if neighborY >= 0 and neighborX >= 0 then - if Map[neighborX][neighborY] == 0 and Danger[neighborX][neighborY] ~= 1 then - table.insert(neighbors, {x = neighborX, y = neighborY}) - end - end - end - end - if #neighbors == 0 and Danger[node.x][node.y] <= 1 then - for _, dir in ipairs(Dirs) do - local neighborX = node.x + dir.x - local neighborY = node.y + dir.y - if neighborY <= MaxY and neighborX <= MaxX then - if neighborY >= 0 and neighborX >= 0 then - if Map[neighborX][neighborY] == 0 then - table.insert(neighbors, {x = neighborX, y = neighborY}) - end - end - end - end - end - return neighbors -end - -function dist(nodeA, nodeB) - return math.sqrt(math.pow(nodeB.x - nodeA.x, 2) + math.pow(nodeB.y - nodeA.y, 2)) -end - -function getNeighborAttack(node) - log("atta") - local neighbors = {} - for _, dir in ipairs(Dirs) do - local neighborX = node.x + dir.x - local neighborY = node.y + dir.y - if neighborY <= MaxY and neighborX <= MaxX then - if neighborY >= 0 and neighborX >= 0 then - if Map[neighborX][neighborY] <= 1 and Danger[neighborX][neighborY] ~= 1 then - table.insert(neighbors, {x = neighborX, y = neighborY}) - end - end - end - end - return neighbors -end - -function getPathToEnemy(player, enemies) - local minDist = 100000 - local res = {} - for _, enemy in ipairs(enemies) do - local currDist = dist(player, enemy) - if currDist < minDist and enemy.x ~= player.x and enemy.y ~= player.y then - minDist, res = currDist, enemy - end - end - local path = pathfind(player, res, getNeighborAttack) - return path -end - - - function getPathToSafeSpace(player) local res = getClosestSafeSpace() log("run to") From 5d9fb5b09cc23f843c51ce1766ce839b0822b70e Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 22:00:51 +0200 Subject: [PATCH 06/10] check if script has Update function --- .../Component/IAControllable/IAControllableComponent.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sources/Component/IAControllable/IAControllableComponent.cpp b/sources/Component/IAControllable/IAControllableComponent.cpp index c91a75d92..dcfc30693 100644 --- a/sources/Component/IAControllable/IAControllableComponent.cpp +++ b/sources/Component/IAControllable/IAControllableComponent.cpp @@ -20,6 +20,12 @@ namespace BBM { if (std::filesystem::exists(scriptPath)) { _state.dofile(scriptPath); + _state.getGlobal("Update"); + if (lua_isfunction(_state.getState(), -1)) { + _state.popLast(); + } else { + throw Error("Lua script doesn't have Update function"); + } } else { throw Error("Couldn't load lua script: " + scriptPath); From 14e1e2a6b36f3bdcfce285985eb02cc33a00533b Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 22:09:27 +0200 Subject: [PATCH 07/10] added through breakable --- assets/ai_scripts/john.lua | 2 +- lib/LuaGate/sources/LuaGate.cpp | 5 +++++ lib/LuaGate/sources/LuaGate.hpp | 3 +++ sources/Map/LuaMap.cpp | 23 +++++++++++++---------- sources/Map/LuaMap.hpp | 4 ++-- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/assets/ai_scripts/john.lua b/assets/ai_scripts/john.lua index f3a6522e1..bc9e8cdf8 100644 --- a/assets/ai_scripts/john.lua +++ b/assets/ai_scripts/john.lua @@ -58,7 +58,7 @@ LastTarget = nil math.randomseed(os.time()) function Update() log("NEW FRAME") - --local path = getPath(0, 0, 16, 16); + local path = getPath(0, 0, 16, 16, true); local player = getPlayer() if LastTarget ~= nil then diff --git a/lib/LuaGate/sources/LuaGate.cpp b/lib/LuaGate/sources/LuaGate.cpp index 5e6a3584c..04347a6dd 100644 --- a/lib/LuaGate/sources/LuaGate.cpp +++ b/lib/LuaGate/sources/LuaGate.cpp @@ -70,6 +70,11 @@ namespace LuaG return res; } + bool State::getBool(int idx) + { + return lua_toboolean(_state, idx); + } + float State::getNumber(int idx) { return lua_tonumber(_state, idx); diff --git a/lib/LuaGate/sources/LuaGate.hpp b/lib/LuaGate/sources/LuaGate.hpp index 30305fe22..ee067a89b 100644 --- a/lib/LuaGate/sources/LuaGate.hpp +++ b/lib/LuaGate/sources/LuaGate.hpp @@ -52,6 +52,9 @@ namespace LuaG //! @brief Get return Number bool getReturnBool(void); + //! @brief Get bool at index in the stack + bool getBool(int index); + //! @brief Get Number at index in the stack float getNumber(int index); diff --git a/sources/Map/LuaMap.cpp b/sources/Map/LuaMap.cpp index 04232bd1a..49523696a 100644 --- a/sources/Map/LuaMap.cpp +++ b/sources/Map/LuaMap.cpp @@ -56,7 +56,7 @@ namespace BBM return path; } - std::vector LuaMap::getNeighbors(Vector2f node) const + std::vector LuaMap::getNeighbors(Vector2f node, bool throughBreakable) const { std::vector neighbors; for (auto &dir : _dirs) { @@ -65,7 +65,8 @@ namespace BBM continue; if (neighbor.y >= 17 || neighbor.x >= 17) continue; - if (_map[neighbor.y][neighbor.x] == 0 && + if ((_map[neighbor.y][neighbor.x] == 0 || + _map[neighbor.y][neighbor.x] == throughBreakable) && _danger[neighbor.y][neighbor.x] != 1) neighbors.push_back(neighbor); } @@ -83,7 +84,7 @@ namespace BBM return neighbors; } - std::vector LuaMap::pathfind(Vector2f root, Vector2f target) const + std::vector LuaMap::pathfind(Vector2f root, Vector2f target, bool throughBreakable) const { std::vector closed; std::vector open; @@ -117,7 +118,7 @@ namespace BBM } open.erase(std::remove(open.begin(), open.end(), current), open.end()); closed.push_back(current); - auto neighbors = getNeighbors(current); + auto neighbors = getNeighbors(current, throughBreakable); for (auto &neighbor : neighbors) { if (std::find(closed.begin(), closed.end(), neighbor) != closed.end()) continue; @@ -224,14 +225,16 @@ namespace BBM int LuaMap::getPath(lua_State *L) { LuaG::State state(L); - auto y2 = state.getNumber(-1); - auto x2 = state.getNumber(-2); - auto y1 = state.getNumber(-3); - auto x1 = state.getNumber(-4); - const LuaMap *map = reinterpret_cast(state.getPointer(state.getFirstUpValueIdx())); + auto throughBreakable = state.getBool(-1); + auto y2 = state.getNumber(-2); + auto x2 = state.getNumber(-3); + auto y1 = state.getNumber(-4); + auto x1 = state.getNumber(-5); + + const LuaMap *map = reinterpret_cast(state.getPointer(state.getFirstUpValueIdx())); Vector2f fst(x1, y1); Vector2f snd(x2, y2); - auto path = map->pathfind(fst, snd); + auto path = map->pathfind(fst, snd, throughBreakable); int index = 1; state.newTable(); for (auto &r : path) { diff --git a/sources/Map/LuaMap.hpp b/sources/Map/LuaMap.hpp index 46765d20a..ee53c3a03 100644 --- a/sources/Map/LuaMap.hpp +++ b/sources/Map/LuaMap.hpp @@ -28,7 +28,7 @@ namespace BBM void setPlayer(Vector3f pos); //! @brief A star pathfinding between two points - std::vector pathfind(Vector2f, Vector2f) const; + std::vector pathfind(Vector2f root, Vector2f target, bool throughBreakable) const; //! @brief find a safe space for current player Vector2f findSafeSpace(const std::vector> &dangerMap) const; @@ -95,7 +95,7 @@ namespace BBM std::unordered_map &cameFrom, Vector2f node) const; //! @brief get neighbors of node for a_star - std::vector getNeighbors(Vector2f node) const; + std::vector getNeighbors(Vector2f node, bool throughBreakable) const; std::vector _dirs = { Vector2f(1, 0), Vector2f(-1, 0), Vector2f(0, 1), Vector2f(0, -1) From 08229aba5fcb9409145e31941015c56431e724d2 Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 22:10:20 +0200 Subject: [PATCH 08/10] john is not doing this --- assets/ai_scripts/john.lua | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/assets/ai_scripts/john.lua b/assets/ai_scripts/john.lua index bc9e8cdf8..f73dff4ed 100644 --- a/assets/ai_scripts/john.lua +++ b/assets/ai_scripts/john.lua @@ -58,7 +58,6 @@ LastTarget = nil math.randomseed(os.time()) function Update() log("NEW FRAME") - local path = getPath(0, 0, 16, 16, true); local player = getPlayer() if LastTarget ~= nil then @@ -72,22 +71,6 @@ function Update() end end - local enemies = getEnemies() - local enemiesRound = getEnemiesRound() - - log("enemies") - for i, v in ipairs(enemies) do - log("enemy") - log(v.x) - log(v.y) - end - log("enemies ROUND") - for i, v in ipairs(enemiesRound) do - log("enemy ROUND") - log(v.x) - log(v.y) - end - log("player") log(player.x) log(player.y) From d751c9fb0e62fc0229ed8baa40e07483c49d6b5b Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 22:11:38 +0200 Subject: [PATCH 09/10] update md --- Bot.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Bot.md b/Bot.md index 1d1d08acc..71f85f804 100644 --- a/Bot.md +++ b/Bot.md @@ -38,7 +38,8 @@ function getDanger(); -- @param y1 should be int -- @param x2 should be int -- @param y2 should be int -function getPath(x1, y1, x2, y2); +-- @param throughBreakable bool path is going through breakables blocks or not +function getPath(x1, y1, x2, y2, throughBreakable); -- getPlayer returns player pos as {x = xPlayer, y = yPlayer} function getPlayer(); From 982f09cf8dec2e4d73faf99d657983e0bf680d31 Mon Sep 17 00:00:00 2001 From: Bluub Date: Sun, 20 Jun 2021 22:14:11 +0200 Subject: [PATCH 10/10] remove overpowered double return --- sources/Map/LuaMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/Map/LuaMap.cpp b/sources/Map/LuaMap.cpp index 49523696a..cd3967cde 100644 --- a/sources/Map/LuaMap.cpp +++ b/sources/Map/LuaMap.cpp @@ -367,7 +367,7 @@ namespace BBM state.setTable(); state.setTable(); } - return 1; return 1; + return 1; } int LuaMap::canPutBomb(lua_State *L)