2019-08-09 16:34:49 +02:00
|
|
|
local function coord_string(x, y)
|
2021-03-24 17:46:00 +02:00
|
|
|
local str = tostring(x) .. '_'
|
|
|
|
str = str .. tostring(y)
|
|
|
|
return str
|
2019-08-09 16:34:49 +02:00
|
|
|
end
|
|
|
|
|
2019-08-09 18:01:07 +02:00
|
|
|
local function draw_cell(surface, cell, cell_size, wall_entity_name, force_name)
|
2021-03-24 17:46:00 +02:00
|
|
|
local r = math.floor(cell_size * 0.5)
|
|
|
|
local entities = {}
|
|
|
|
if cell.north then
|
|
|
|
for x = r * -1, r, 1 do
|
|
|
|
entities[#entities + 1] = {position = {cell.position.x + x, cell.position.y - r}, name = wall_entity_name, force = force_name}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if cell.south then
|
|
|
|
for x = r * -1, r, 1 do
|
|
|
|
entities[#entities + 1] = {position = {cell.position.x + x, cell.position.y + r}, name = wall_entity_name, force = force_name}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if cell.east then
|
|
|
|
for y = r * -1, r, 1 do
|
|
|
|
entities[#entities + 1] = {position = {cell.position.x + r, cell.position.y + y}, name = wall_entity_name, force = force_name}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if cell.west then
|
|
|
|
for y = r * -1, r, 1 do
|
|
|
|
entities[#entities + 1] = {position = {cell.position.x - r, cell.position.y - y}, name = wall_entity_name, force = force_name}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
for _, e in pairs(entities) do
|
|
|
|
if surface.can_place_entity(e) then
|
|
|
|
surface.create_entity(e)
|
|
|
|
end
|
|
|
|
end
|
2019-08-09 16:34:49 +02:00
|
|
|
end
|
|
|
|
|
2019-08-09 18:01:07 +02:00
|
|
|
local function draw_maze(surface, position, size, cell_size, wall_entity_name, force_name)
|
2021-03-24 17:46:00 +02:00
|
|
|
for _, cell in pairs(maze_cells) do
|
|
|
|
draw_cell(surface, cell, cell_size, wall_entity_name, force_name)
|
|
|
|
end
|
2019-08-09 16:34:49 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local function get_random_occupied_cell()
|
2021-03-24 17:46:00 +02:00
|
|
|
local occupied_cells = {}
|
|
|
|
for c, cell in pairs(maze_cells) do
|
|
|
|
if cell.occupied then
|
|
|
|
if not cell.dead then
|
|
|
|
occupied_cells[#occupied_cells + 1] = c
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if not occupied_cells[1] then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
return occupied_cells[math.random(1, #occupied_cells)]
|
2019-08-09 16:34:49 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local function set_dead_cells()
|
2021-03-24 17:46:00 +02:00
|
|
|
local directions = {
|
|
|
|
{0, -1},
|
|
|
|
{0, 1},
|
|
|
|
{1, 0},
|
|
|
|
{-1, 0}
|
|
|
|
}
|
|
|
|
|
|
|
|
for c, cell in pairs(maze_cells) do
|
|
|
|
if not cell.dead then
|
|
|
|
maze_cells[c].dead = true
|
|
|
|
for i = 1, 4, 1 do
|
|
|
|
local cell_string = coord_string(cell.cell_position.x + directions[i][1], cell.cell_position.y + directions[i][2])
|
|
|
|
if maze_cells[cell_string] then
|
|
|
|
if not maze_cells[cell_string].occupied then
|
|
|
|
maze_cells[c].dead = false
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-08-09 16:34:49 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local function expand_cell(current_cell)
|
2021-03-24 17:46:00 +02:00
|
|
|
local expansion_raffle = {
|
|
|
|
{0, -1, 'north', 'south'},
|
|
|
|
{0, 1, 'south', 'north'},
|
|
|
|
{1, 0, 'east', 'west'},
|
|
|
|
{-1, 0, 'west', 'east'}
|
|
|
|
}
|
|
|
|
table.shuffle_table(expansion_raffle)
|
|
|
|
for i = 1, 4, 1 do
|
|
|
|
local direction = expansion_raffle[i]
|
|
|
|
local cell_canditate = coord_string(current_cell.cell_position.x + direction[1], current_cell.cell_position.y + direction[2])
|
|
|
|
if maze_cells[cell_canditate] then
|
|
|
|
if not maze_cells[cell_canditate].occupied then
|
|
|
|
maze_cells[cell_canditate].occupied = true
|
|
|
|
current_cell[direction[3]] = false
|
|
|
|
maze_cells[cell_canditate][direction[4]] = false
|
|
|
|
return maze_cells[cell_canditate]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return false
|
2019-08-09 16:34:49 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local function expand(size)
|
2021-03-24 17:46:00 +02:00
|
|
|
local current_cell = maze_cells[get_random_occupied_cell()]
|
|
|
|
while true do
|
|
|
|
current_cell = expand_cell(current_cell)
|
|
|
|
if not current_cell then
|
|
|
|
set_dead_cells()
|
|
|
|
current_cell = maze_cells[get_random_occupied_cell()]
|
|
|
|
end
|
|
|
|
if not current_cell then
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
2019-08-09 16:34:49 +02:00
|
|
|
end
|
|
|
|
|
2019-08-24 14:23:36 +02:00
|
|
|
local function disable_borders(size)
|
2021-03-24 17:46:00 +02:00
|
|
|
for s = size * -1, size, 1 do
|
|
|
|
maze_cells[coord_string(s, size * -1)].north = false
|
|
|
|
maze_cells[coord_string(s, size)].south = false
|
|
|
|
maze_cells[coord_string(size, s)].east = false
|
|
|
|
maze_cells[coord_string(size * -1, s)].west = false
|
|
|
|
end
|
2019-08-24 14:23:36 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
function create_maze(surface, position, size, cell_size, wall_entity_name, force_name, borderless)
|
2021-03-24 17:46:00 +02:00
|
|
|
if not surface then
|
|
|
|
game.print('No surface given.')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if not position then
|
|
|
|
game.print('No position given.')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if not size then
|
|
|
|
game.print('No size given.')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if not cell_size then
|
|
|
|
game.print('No cell_size given.')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if not wall_entity_name then
|
|
|
|
game.print('No wall_entity_name given.')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
maze_cells = {}
|
|
|
|
|
|
|
|
for x = size * -1, size, 1 do
|
|
|
|
for y = size * -1, size, 1 do
|
|
|
|
maze_cells[coord_string(x, y)] = {
|
|
|
|
position = {x = position.x + x * (cell_size - 1), y = position.y + y * (cell_size - 1)},
|
|
|
|
cell_position = {x = x, y = y},
|
|
|
|
occupied = false,
|
|
|
|
dead = false,
|
|
|
|
north = true,
|
|
|
|
south = true,
|
|
|
|
east = true,
|
|
|
|
west = true
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
maze_cells[coord_string(size * -1, 0)].occupied = true
|
|
|
|
maze_cells[coord_string(size * -1, 0)].west = false
|
|
|
|
maze_cells[coord_string(size, 0)].east = false
|
|
|
|
|
|
|
|
if borderless then
|
|
|
|
disable_borders(size)
|
|
|
|
end
|
|
|
|
|
|
|
|
expand(size)
|
|
|
|
|
|
|
|
draw_maze(surface, position, size, cell_size, wall_entity_name, force_name)
|
|
|
|
end
|