diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/algs.lua | 100 | ||||
| -rw-r--r-- | include/constants.lua | 6 | ||||
| -rw-r--r-- | include/defaults.lua (renamed from include/default_proc.lua) | 29 | ||||
| -rw-r--r-- | include/queue.lua | 29 | 
4 files changed, 156 insertions, 8 deletions
| diff --git a/include/algs.lua b/include/algs.lua new file mode 100644 index 0000000..ad0016a --- /dev/null +++ b/include/algs.lua @@ -0,0 +1,100 @@ +require "include.constants" +local Queue = require "include.queue" + +local function can_move(x, y, map) +    return map[y][x] == MAP_SPACE +end + +---@param x number +---@param y number +---@param origin table +---@param map table +---@param queue table +local function push_moves(x, y, origin, map, queue) +    -- UP +    if can_move(x, y -1, map) then +        queue:push({ +            x = x, +            y = y - 1, +            origin = origin +        }) +        map[y-1][x] = MAP_VISITED +    end +    -- DOWN +    if can_move(x, y +1, map) then +        queue:push({ +            x = x, +            y = y + 1, +            origin = origin +        }) +        map[y+1][x] = MAP_VISITED +    end +    -- LEFT +    if can_move(x - 1, y, map) then +        queue:push({ +            x = x - 1, +            y = y, +            origin = origin +        }) +        map[y][x - 1] = MAP_VISITED +    end +    -- RIGHT +    if can_move(x + 1, y, map) then +        queue:push({ +            x = x + 1, +            y = y, +            origin = origin +        }) +        map[y][x+1] = MAP_VISITED +    end +end + +--- +---@param start_pos table [x, y] +---@param target_pos table [x, y] +---@param map table 2D map array +---@return table best move to target [x, y] +--- +local function pathfind(start_pos, target_pos, map) +    local queue = Queue:new() +    local visit_map = {} +    for k, v in ipairs(map) do +        row = {} +        for ik, iv in ipairs(v) do +            row[ik] = iv +        end +        visit_map[k] = row +    end + +    push_moves(start_pos.x, start_pos.y, nil, visit_map, queue) +    while queue:empty() ~= true do +        local pos = queue:pop() +        if (pos.x == target_pos.x and pos.y == target_pos.y) then +            return { dx = pos.origin.x - start_pos.x, dy = pos.origin.y - start_pos.y } +        end +        origin = pos.origin or { x = pos.x, y = pos.y } +        push_moves(pos.x, pos.y, origin, map, queue) +    end +    return { dx = 0, dy = 0 } +end + +---@param map table +local function print_map(map) +    for i = 1, #map do +        row = map[i] +        line = "" +        for j = 1, #row do +            if row[j] == MAP_WALL then +                line = line .. "# " +            else +                line = line .. "  " +            end +        end +        print(line) +    end +end + +return { +    pathfind = pathfind, +    print_map = print_map, +} diff --git a/include/constants.lua b/include/constants.lua index 5d8e860..922a35b 100644 --- a/include/constants.lua +++ b/include/constants.lua @@ -5,6 +5,6 @@ KEY_D = 100  KEY_SPACE = ' ' -TILE_WALL = 'w' -TILE_SPACE = ' ' -TILE_ENEMY = 'e'
\ No newline at end of file +MAP_WALL = 1 +MAP_SPACE = 0 +MAP_VISITED = -1 diff --git a/include/default_proc.lua b/include/defaults.lua index 13ef15d..a6cefe5 100644 --- a/include/default_proc.lua +++ b/include/defaults.lua @@ -14,8 +14,11 @@ c_trigger_loss(msg)  c_fatal(msg)  --]] -  require "include.constants"; +local algs = require "include.algs"; + +--- setup random +--math.randomseed(os.time())  ---@param pressedKey number  function onKeyPress(pressedKey) @@ -32,11 +35,27 @@ function onKeyPress(pressedKey)          dx = 1      end -    if c_player_can_move(dx, dy) then -        c_update_player_pos(dx, dy) -    end +    c_move_player(dx, dy)  end  function onUpdate() +    enemies = c_get_enemies() -- external +    assert(type(enemies) == "table", "Enemies not a table") + +    player = c_get_player_position() -- external +    assert(type(player) == "table", "Player is not a table") + +    map = c_get_map(); +    assert(type(map) == "table", "map is not a table") + +    for _, v in ipairs(enemies) do +        local next = algs.pathfind(v, player, map) +        c_move_enemy(v.id, next.dx, next.dy) +    end +end -end
\ No newline at end of file +--- allow for requiring in other files for usage +return { +    onKeyPress = onKeyPress, +    onUpdate = onUpdate, +}
\ No newline at end of file diff --git a/include/queue.lua b/include/queue.lua new file mode 100644 index 0000000..2eb77c6 --- /dev/null +++ b/include/queue.lua @@ -0,0 +1,29 @@ +Queue = {} + +function Queue:new() +    o = { first = 1, top = 0, data = {} } +    self.__index = self +    return setmetatable(o, self) +end + +function Queue:push(val) +    local top = self.top + 1 +    self.top = top +    self.data[top] = val +end + +function Queue:pop() +    if self:empty() then +        return nil +    end +    local val = self.data[self.first] +    self.data[self.first] = nil +    self.first = self.first + 1 +    return val +end + +function Queue:empty() +    return self.top < self.first +end + +return Queue |