1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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,
}
|