Skip to content

Commit

Permalink
Merge pull request #263 from AnonymusRaccoon/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Octopus773 authored Jun 20, 2021
2 parents 2d17eff + 1a2734e commit 0982c28
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 80 deletions.
74 changes: 74 additions & 0 deletions Bot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# 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++

## 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
nothing = 0
breakable = 1
hole = 2
bumper = 4
unbreakable = 7
bomb = 10
```

## Registered functions

```lua
-- 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 {{x = X, y = Y}, ...}
-- @param x1 should be int
-- @param y1 should be int
-- @param x2 should be int
-- @param y2 should be int
-- @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();

-- 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(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
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();
```
66 changes: 0 additions & 66 deletions assets/ai_scripts/john.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -123,7 +58,6 @@ LastTarget = nil
math.randomseed(os.time())
function Update()
log("NEW FRAME")
--local path = getPath(0, 0, 16, 16);

local player = getPlayer()
if LastTarget ~= nil then
Expand Down
5 changes: 5 additions & 0 deletions lib/LuaGate/sources/LuaGate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions lib/LuaGate/sources/LuaGate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
6 changes: 6 additions & 0 deletions sources/Component/IAControllable/IAControllableComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
71 changes: 61 additions & 10 deletions sources/Map/LuaMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace BBM
return path;
}

std::vector<Vector2f> LuaMap::getNeighbors(Vector2f node) const
std::vector<Vector2f> LuaMap::getNeighbors(Vector2f node, bool throughBreakable) const
{
std::vector<Vector2f> neighbors;
for (auto &dir : _dirs) {
Expand All @@ -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);
}
Expand All @@ -83,7 +84,7 @@ namespace BBM
return neighbors;
}

std::vector<Vector2f> LuaMap::pathfind(Vector2f root, Vector2f target) const
std::vector<Vector2f> LuaMap::pathfind(Vector2f root, Vector2f target, bool throughBreakable) const
{
std::vector<Vector2f> closed;
std::vector<Vector2f> open;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<const LuaMap *>(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<const LuaMap *>(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) {
Expand Down Expand Up @@ -319,6 +322,54 @@ namespace BBM
return 1;
}

int LuaMap::getRadius(lua_State *L)
{
LuaG::State state(L);
const LuaMap *map = reinterpret_cast<const LuaMap *>(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<const LuaMap *>(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<const LuaMap *>(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;
}

int LuaMap::canPutBomb(lua_State *L)
{
LuaG::State state(L);
Expand Down
16 changes: 14 additions & 2 deletions sources/Map/LuaMap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace BBM
void setPlayer(Vector3f pos);

//! @brief A star pathfinding between two points
std::vector<Vector2f> pathfind(Vector2f, Vector2f) const;
std::vector<Vector2f> pathfind(Vector2f root, Vector2f target, bool throughBreakable) const;

//! @brief find a safe space for current player
Vector2f findSafeSpace(const std::vector<std::vector<int>> &dangerMap) const;
Expand Down Expand Up @@ -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<std::vector<int>> _map;

Expand All @@ -72,6 +81,9 @@ namespace BBM
//! @brief player position
Vector2f _player;

//! @brief other players position
std::vector<Vector2f> _enemies;

//! @brief rounded player position
Vector2f _roundedPlayer;

Expand All @@ -83,7 +95,7 @@ namespace BBM
std::unordered_map<Vector2f, Vector2f> &cameFrom, Vector2f node) const;

//! @brief get neighbors of node for a_star
std::vector<Vector2f> getNeighbors(Vector2f node) const;
std::vector<Vector2f> getNeighbors(Vector2f node, bool throughBreakable) const;

std::vector<Vector2f> _dirs = {
Vector2f(1, 0), Vector2f(-1, 0), Vector2f(0, 1), Vector2f(0, -1)
Expand Down
9 changes: 7 additions & 2 deletions sources/System/IAControllable/IAControllableSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ namespace BBM

void IAControllableSystem::UpdateMapInfos(WAL::ViewEntity<PositionComponent, ControllableComponent, IAControllableComponent, BombHolderComponent> &entity)
{
_players.clear();
_luamap._enemies.clear();
if (!_wal.getScene())
return;
for (auto &[other, pos, _] : _wal.getScene()->view<PositionComponent, ScoreComponent>()) {
_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;
Expand Down Expand Up @@ -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<PositionComponent, ControllableComponent, IAControllableComponent, BombHolderComponent> &entity)
Expand Down

0 comments on commit 0982c28

Please sign in to comment.