Start work on autoexplore

This commit is contained in:
Juhani Krekelä 2019-06-30 13:21:49 +03:00
parent 15d9aa5dab
commit 15be546152
1 changed files with 75 additions and 2 deletions

View File

@ -27,7 +27,7 @@ local move_repeat_counter = nil
local gamemodes = {normal = 0, won = 1, lost = 2, config = 3}
local game_mode = nil
local configuration_steps = {quit = -3, restart = -2, configure = -1}
local configuration_steps = {quit = -4, restart = -3, configure = -2, autoexplore = -1}
local configuration_step = nil
local direction_keys = {}
@ -40,10 +40,12 @@ direction_keys['.'] = directions.downright
direction_keys['l'] = directions.right
direction_keys['o'] = directions.upright
direction_keys['space'] = directions.inplace
local control_keys = {quit = 'q', restart = 'r', configure = 'c'}
local control_keys = {quit = 'q', restart = 'r', configure = 'c', autoexplore = 'a'}
local win_image = nil
local distances = {} --debg
-- ------------------------------------------------------------------
-- Cavern generation
-- ------------------------------------------------------------------
@ -713,6 +715,66 @@ function step(direction)
end
end
-- ------------------------------------------------------------------
-- Autoexplore
-- ------------------------------------------------------------------
function autoexplore()
-- Use a pathfinding algo where each unknown but accessible space gets labelled 0, and
-- then each known accessible space gets labelled with min(neighbours) + 1. Once we have
-- computed that table, we can then move towards closest unknown accessible space by
-- moving to our neighbouring space with lowest score
--local distances = {}
distances = {} --debg
for x = 1, cavern.width do
local list = {}
for y = 1, cavern.height do
table.insert(list, {value = nil, direction = directions.inplace})
end
table.insert(distances, list)
end
local queue = {}
function enqueue(queue, x, y, value, direction)
if 1 < x and x < cavern.width and
1 < y and y < cavern.height and
cavern[x][y] ~= tiletypes.wall then
table.insert(queue, {x = x, y = y, value = value, direction = direction})
end
end
function neighbors(q, x, y, v)
-- The directions are reversed, because they tell where to go to get to the
-- unexplored areas
enqueue(q, x, y - 1, v, directions.down)
enqueue(q, x - 1, y, v, directions.right)
enqueue(q, x, y + 1, v, directions.up)
enqueue(q, x + 1, y, v, directions.left)
end
for x, list in ipairs(visibility_map) do
for y, visible in ipairs(list) do
if not visible and remembered_cavern[x][y] == nil then
distances[x][y] = {value = 0, direction = directions.inplace}
neighbors(queue, x, y, 1)
end
end
end
repeat
local new_queue = {}
for i, item in ipairs(queue) do
-- Write the lowest distance to each tile
if distances[item.x][item.y].value == nil or distances[item.x][item.y].value > item.value then
distances[item.x][item.y] = {value = item.value, direction = item.direction}
neighbors(new_queue, item.x, item.y, item.value + 1)
end
end
queue = new_queue
until #queue == 0
step(distances[player_x][player_y].direction)
end
-- ------------------------------------------------------------------
-- Drawing
-- ------------------------------------------------------------------
@ -790,6 +852,11 @@ function drawCavern()
love.graphics.setColor(1, 1, 0)
love.graphics.rectangle('fill', x + 0.5 * scale, y + 0.5 * scale, scale/2, scale/2)
end
if distances[tile_x] ~= nil and distances[tile_x][tile_y].value ~= nil then --debg
love.graphics.setColor(0.5, 0.5, 0.5) --debg
love.graphics.print(distances[tile_x][tile_y].value, x, y) --debg
end --debg
end
end
end
@ -925,6 +992,8 @@ function drawConfig()
text = "Restart"
elseif configuration_step == configuration_steps.configure then
text = "Button configuration"
elseif configuration_step == configuration_steps.autoexplore then
text = "Autoexplore"
elseif configuration_step == directions.up then
text = "Up"
elseif configuration_step == directions.upleft then
@ -994,6 +1063,8 @@ function love.keypressed(key)
control_keys.restart = key
elseif configuration_step == configuration_steps.configure then
control_keys.configure = key
elseif configuration_step == configuration_steps.autoexplore then
control_keys.autoexplore = key
end
configuration_step = configuration_step + 1
@ -1011,6 +1082,8 @@ function love.keypressed(key)
love.event.quit()
elseif key == control_keys.restart then
newGame()
elseif key == control_keys.autoexplore then
autoexplore()
elseif direction_keys[key] ~= nil then
step(direction_keys[key])
elseif key == 'pause' then