## Code Doodles!

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Trystan
Prole
Posts: 8
Joined: Fri Nov 24, 2023 9:30 am

### Re: Code Doodles!

Fairly new to löve but saw this thread and thought I'd try my hand at a quick doodle. Nothing too fancy, just some colourful lines around a square grid but I was quite happy with the result.

To add in an icon that draws in the middle and changes colour just uncomment the iconImg lines in load and draw.
Doodle.png (161.32 KiB) Viewed 3761 times

Code: Select all

function love.load()
windowHeight = love.graphics.getHeight()
windowWidth = love.graphics.getWidth()
frameSize = 400
frameX = (windowWidth / 2) - (frameSize / 2)
frameY = (windowHeight / 2) - (frameSize / 2)
linesPerSide = 40 -- lines per side (i.e. total / 4)
drawLines = math.floor(linesPerSide * 3.8) -- number of lines to draw each frame
firstLine = 1
delayTimer = 0
delayTime = 0.03 -- seconds per update
generateLines()
-- iconImg = love.graphics.newImage("Cham.png")
end

function HSV(h, s, v)
if s <= 0 then return v,v,v end
h = h*6
local c = v*s
local x = (1-math.abs((h%2)-1))*c
local m,r,g,b = (v-c), 0, 0, 0
if h < 1 then r, g, b = c, x, 0
elseif h < 2 then r, g, b = x, c, 0
elseif h < 3 then r, g, b = 0, c, x
elseif h < 4 then r, g, b = 0, x, c
elseif h < 5 then r, g, b = x, 0, c
else r, g, b = c, 0, x end
return r+m, g+m, b+m
end

function generateLines()
lines = {}
local delta = frameSize / linesPerSide
for i = 1, linesPerSide do
lines[i] = {frameX, frameY + i * delta, frameX + frameSize - i * delta, frameY} -- top left
lines[linesPerSide + i] = {frameX, frameY + i * delta, frameX + i * delta, frameY + frameSize} -- bottom left
lines[linesPerSide * 2 + i] = {frameX + i * delta, frameY + frameSize, frameX + frameSize, frameY + frameSize - i * delta} -- bottom right
lines[linesPerSide * 3 + i] = {frameX + frameSize, frameY + frameSize - i * delta, frameX + frameSize - i * delta, frameY} -- top right
end
end

function love.update(dt)
delayTimer = delayTimer + dt
if delayTimer > delayTime then
firstLine = firstLine + 1
if firstLine > #lines then
firstLine = 1
end
delayTimer = 0
end
end

function love.draw()
love.graphics.setLineWidth(1)
local j, r, g, b
-- draw the lines, rearmost first
for i = 1, drawLines do
j = (firstLine + i) % #lines + 1 -- set current line, starting at firstLine and wrapping
r, g, b = HSV(j/#lines, 1, 1)
love.graphics.setColor(r, g, b, i / drawLines) -- make early lines more transparent
love.graphics.line(lines[j])
end
-- draw the icon, colour should still be the same as the foremost line
-- love.graphics.draw(iconImg, windowWidth / 2, windowHeight / 2, 0, 1, 1, iconImg:getWidth() / 2, iconImg:getHeight() / 2)
-- draw the frame
love.graphics.setColor(1, 1, 1)
love.graphics.setLineWidth(4)
love.graphics.rectangle("line", frameX, frameY, frameSize, frameSize)
end
Last edited by Trystan on Fri Nov 24, 2023 9:45 am, edited 1 time in total.
Trystan
Prole
Posts: 8
Joined: Fri Nov 24, 2023 9:30 am

### Re: Code Doodles!

Another quick doodle. This is just a simple BSP generator but after 9 or 10 generations it creates quite a nice city grid like pattern. The partitions are stored in terms of percentage of the screen so it should resize gracefully.

Press 1 to reset the BSP tree
Press 2 to add new branches to the tree
Grid.jpg (133.41 KiB) Viewed 3738 times

Code: Select all

function love.load()
love.window.setTitle("BSP")
love.window.setMode(800, 600, {resizable = true})
math.randomseed(os.time()) -- get the random warmed up
math.random(); math.random(); math.random(); math.random()
resetTree()
end

function love.resize(w, h)
createTreeCoords()
end

function love.keypressed(key)
if key == "1" then
resetTree()
elseif key == "2" then
end
end

function resetTree()
tree = {}
tree[1] = {0, 0, 1, 1} -- add the root (the full area from 0,0 to 1,1)
numGenerations = 1
lastGenStart = 1
createTreeCoords()
end

local leaf, split, ratio
for i = lastGenStart, #tree do -- go through the last generation and adds children to them
leaf= tree[i]
ratio = ((leaf[3] - leaf[1]) / (leaf[4] - leaf[2])) - 0.5 -- set horiz/vert split probability based on ratio of parent container
if math.random() >= ratio then -- vertical split
split = math.random(35, 65) / 100 -- random between 0.35 and 0.65
split = leaf[2] + ((leaf[4] - leaf[2]) * split)
table.insert(tree, {leaf[1], leaf[2], leaf[3], split})
table.insert(tree, {leaf[1], split, leaf[3], leaf[4]})
else -- horizontal split
split = math.random(35, 65) / 100 -- random between 0.35 and 0.65
split = leaf[1] + ((leaf[3] - leaf[1]) * split)
table.insert(tree, {leaf[1], leaf[2], split, leaf[4]})
table.insert(tree, {split, leaf[2], leaf[3], leaf[4]})
end
table.insert(leaf, {#tree - 1, #tree}) -- register children with leaf
end
numGenerations = numGenerations + 1
lastGenStart = 2 ^ (numGenerations - 1)
createTreeCoords()
end

function createTreeCoords()
treeCoords = {}
local leaf, x1, y1, x2, y2
local w = love.graphics.getWidth()
local h = love.graphics.getHeight()
for i = lastGenStart, #tree do -- only put the last generation in the draw table
leaf = tree[i]
x1 = math.floor((leaf[1] * w) + 0.5)
y1 = math.floor((leaf[2] * h) + 0.5)
x2 = math.floor((leaf[3] * w) + 0.5)
y2 = math.floor((leaf[4] * h) + 0.5)
table.insert(treeCoords, {x1, y1, x2, y1}) -- top line
table.insert(treeCoords, {x1, y1, x1, y2}) -- left line
end
end

function love.draw()
for i = 1, #treeCoords do -- draw the last generation's top and left borders
love.graphics.line(treeCoords[i])
end
end
darkfrei
Party member
Posts: 1155
Joined: Sat Feb 08, 2020 11:09 pm

### Re: Code Doodles!

From here: viewtopic.php?p=258462#p258462

Code: Select all

-- Z-sections with T-crossings

love.window.setTitle ('Z-sections with T-crossings; press SPACE for one or X-C-V-B to make alot; Q to new')

function insertZ (x1,y1, x2,y2, x3,y3, x4,y4)
local xmin, ymin, xmax, ymax = math.min(x1, x2),math.min(y1, y2), math.max(x1, x2),math.max(y1, y2)
table.insert (lines, {xmin, ymin, xmax, ymax})
xmin, ymin, xmax, ymax = math.min(x2, x3),math.min(y2, y3), math.max(x2, x3),math.max(y2, y3)
table.insert (lines, {xmin, ymin, xmax, ymax})
xmin, ymin, xmax, ymax = math.min(x3, x4),math.min(y3, y4), math.max(x3, x4),math.max(y3, y4)
table.insert (lines, {xmin, ymin, xmax, ymax})
end

function createFirstZ ()
if h > w then
-- two horizontal
local x = math.random (1,w-1)
local y1 = math.random (1,h-2)
local y2 = math.random (2,h-1)
print (y1, y2)
if y1 == y2 then
y2 = y1+1
end
if math.random () > 0.5 then
insertZ (0,y1, x,y1, x, y2, w,y2)
else
insertZ (0,y2, x,y2, x, y1, w,y1)
end
else
local x1 = math.random (1,w-2)
local x2 = math.random (2,w-1)
local y = math.random (1,h-2)
if x1 == x2 then
x2 = x1+1
end
if math.random () > 0.5 then
insertZ (x1,0, x1,y, x2, y, x2,h)
else
insertZ (x1,0, x1,y, x2, y, x2,h)
end
end
end

function isPointFree (x, y)
for i, line in ipairs (lines) do
if x >= line[1] and x <= line[3] and y >= line[2] and y <= line[4] then
return false
end
end
return true
end

function isPointEnd (x, y)
for i, line in ipairs (lines) do
if (x == line[1] and y == line[2]) or (x == line[3] and y == line[4]) then
return true
end
end
return false
end

function getCrossingH (x, y, side)
local x1 = x
while true do
x1 = x1+side
if x1 == 0 then return 0, false end
if x1 == w then return w, false end
local pointFree = isPointFree (x1, y)
local isEnd = isPointEnd (x1, y)
if not pointFree then
if isEnd then
return nil
else
return x1, true -- position
end
end
end
end

function getCrossingV (x, y, side)
local y1 = y
while true do
y1 = y1+side
if y1 == 0 then return 0, false end
if y1 == h then return h, false end
local pointFree = isPointFree (x, y1)
local isEnd = isPointEnd (x, y1)
if not pointFree then
if isEnd then
return nil
else
return y1, true -- position
end
end
end
end

function getRandomFreeY (x, y)
local list = {}
local y1 = y
while true do
y1 = y1 + 1
if y1 == h then break end
if not isPointFree (x, y1) then break end
table.insert (list, y1)
end
y1 = y
while true do
y1 = y1 - 1
if y1 == 0 then break end
if not isPointFree (x, y1) then break end
table.insert (list, y1)
end
if #list > 0 then
return list[math.random(#list)]
end
end

function getRandomFreeX (x, y)
local list = {}
local x1 = x
while true do
x1 = x1 + 1
if x1 == w then break end
if not isPointFree (x1, y) then break end
table.insert (list, x1)
end
x1 = x
while true do
x1 = x1 - 1
if x1 == 0 then break end
if not isPointFree (x1, y) then break end
table.insert (list, x1)
end
if #list > 0 then
return list[math.random(#list)]
end
end

function tryCreateNewZ ()
local x = math.random (1,w-1)
local y = math.random (1,h-1)
if isPointFree (x, y) then
if math.random () < 0.5 then
-- two horizontal
local x1, onLineA = getCrossingH (x, y, -1)
if x1 then
local y1 = getRandomFreeY (x, y)
if y1 then
local x2, onLineB = getCrossingH (x, y1, 1)
if x2 and (onLineA or onLineB) then
insertZ (x1,y, x,y, x, y1, x2,y1)
end
end
end
else
-- two vertical
local y1, onLineA = getCrossingV (x, y, -1)
if y1 then
local x1 = getRandomFreeX (x, y)
if x1 then
local y2, onLineB = getCrossingV (x1, y, 1)
if y2 and (onLineA or onLineB) then
insertZ (x,y1, x,y, x1, y, x1,y2)
end
end
end
end
end
end

w, h = 79, 59
lines = {}
createFirstZ ()
end

function love.draw ()
local gridSize = 10
love.graphics.translate (5,5)
love.graphics.scale (gridSize)
love.graphics.setLineWidth (2/gridSize)
love.graphics.rectangle ('line', 0,0, w,h)
for i, line in ipairs (lines) do
love.graphics.line (line)
end
end

function love.keypressed (key, scancode, isrepeat)
if key == 'escape' then love.event.quit () end
if key == 'space' then
tryCreateNewZ ()
elseif scancode == 'x' then
for i = 1, 10 do
tryCreateNewZ ()
end
elseif scancode == 'c' then
for i = 1, 100 do
tryCreateNewZ ()
end
elseif scancode == 'v' then
for i = 1, 1000 do
tryCreateNewZ ()
end
elseif scancode == 'b' then
for i = 1, 10000 do
tryCreateNewZ ()
end
elseif scancode == 'q' then
lines = {}
createFirstZ ()
end

end
Screenshot 2024-01-23 170823.png (32.96 KiB) Viewed 1869 times
in Lua we Löve
Platformer Guide
freebies
glitchapp
Party member
Posts: 231
Joined: Tue Oct 05, 2021 10:34 am
Contact:

### Re: Code Doodles!

beautiful! a pity there is not a path to the exit, a nice procedural generated maze based game could be made out of it...
Trystan
Prole
Posts: 8
Joined: Fri Nov 24, 2023 9:30 am

### Re: Code Doodles!

I was toying around with mazes the other day and found the recursive backtracker to be pretty easy to implement and generally nice to look at. It guarantees a maze where every spot is filled in and all spots are on a single network.

f1 to generates a new maze.
RecursiveBacktracker.png (8.76 KiB) Viewed 859 times

Code: Select all

function love.load()
love.window.setTitle("Recursive Backtracking Maze")
math.randomseed(os.time())
math.random(); math.random(); math.random()
-- set map width and height, should be odd numbers
mapWidth = 131
mapHeight = 81
tileSize = 8
-- resize window to maze
love.window.setMode((mapWidth+2)*tileSize,(mapHeight+2)*tileSize)
generateMap()
end

function love.keypressed(key)
if key=="f1" then
generateMap()
end
end

function generateMap()
-- make a map full of walls
map = {}
for x = 1, mapWidth do
map[x] = {}
for y = 1, mapHeight do
map[x][y] = 0
end
end
-- make the maze
generateMaze()
end

function generateMaze()
-- make maze using the recursive backtracker algorithm
-- set and dig the starting space
local sx, sy = math.random(1,math.floor(mapWidth/2)) * 2, math.random(1, math.floor(mapHeight/2)) * 2
stack = {{sx, sy}}
map[sx][sy] = 1
local neighbours, tx, ty
while #stack > 0 do
tx, ty = stack[#stack][1], stack[#stack][2]
neighbours = getEligibleNeighbours(tx, ty)
if #neighbours > 0 then
-- we've got moves, take the first and dig!
-- first the intermediate space
tx = tx + neighbours[1][1]
ty = ty + neighbours[1][2]
map[tx][ty] = 1
-- then the destination space
tx = tx + neighbours[1][1]
ty = ty + neighbours[1][2]
map[tx][ty] = 1
-- add the tile to the end of the stack
table.insert(stack, {tx, ty})
else
-- no moves, remove the last entry on the stack
table.remove(stack)
end
end
end

function getEligibleNeighbours(x, y)
-- gets if a space two spaces away is legal and if it's a wall
-- if both adds a dx, dy to neighbours (only +/-1 as we'll use it twice when we dig)
local neighbours = {}
-- north
if y > 2 then
if map[x][y-2] == 0 then
table.insert(neighbours, {0, -1})
end
end
-- east
if x < mapWidth - 1 then
if map[x+2][y] == 0 then
table.insert(neighbours, {1, 0})
end
end
-- south
if y < mapHeight - 1 then
if map[x][y+2] == 0 then
table.insert(neighbours, {0, 1})
end
end
-- west
if x > 2 then
if map[x-2][y] == 0 then
table.insert(neighbours, {-1, 0})
end
end
-- shuffle the array if we have more than one elgible
-- five times should be fine we're only going to have 2 or 3 entries at most
if #neighbours > 1 then
shuffleArray(neighbours, 5)
end
return neighbours
end

-- quick and dirty array shuffle
function shuffleArray(array, num)
local s1, s2
for _ = 1, num do
s1 = math.random(#array)
s2 = math.random(#array)
array[s1], array[s2] = array[s2], array[s1]
end
end

function love.draw()
for x = 1, mapWidth do
for y = 1, mapHeight do
if map[x][y] == 1 then
love.graphics.setColor(0.7, 0.7, 0.7)
else
love.graphics.setColor(0.2, 0.2, 0.2)
end
love.graphics.rectangle("fill", x * tileSize, y * tileSize, tileSize, tileSize)
end
end
end
Edit: Just for fun I made a version that shows the process of creating the maze, instead of just drawing it all at once.

Code: Select all

function love.load()
love.window.setTitle("Recursive Backtracking Maze")
math.randomseed(os.time())
math.random(); math.random(); math.random()
-- set map width and height, should be odd numbers
mapWidth = 81
mapHeight = 61
tileSize = 8
love.window.setMode((mapWidth+2)*tileSize,(mapHeight+2)*tileSize)
generateMap()
end

function love.keypressed(key)
if key=="f1" then
generateMap()
end
end

function generateMap()
-- make a map full of walls
finished = false
map = {}
for x = 1, mapWidth do
map[x] = {}
for y = 1, mapHeight do
map[x][y] = 0
end
end
-- set and dig the starting space
cx, cy = math.random(1,math.floor(mapWidth/2)) * 2, math.random(1, math.floor(mapHeight/2)) * 2
stack = {{cx, cy}}
map[cx][cy] = 1
end

function love.update()
if finished == false then
generateMaze()
end
end

function generateMaze()
-- make maze using the recursive backtracker algorithm
local neighbours, tx, ty
cx, cy = stack[#stack][1], stack[#stack][2]
neighbours = getEligibleNeighbours(cx, cy)
if #neighbours > 0 then
-- we've got moves, take the first and dig!
-- first the intermediate space
cx = cx + neighbours[1][1]
cy = cy + neighbours[1][2]
map[cx][cy] = 1
-- then the destination space
cx = cx + neighbours[1][1]
cy = cy + neighbours[1][2]
map[cx][cy] = 1
-- add the tile to the end of the stack
cx, cy = cx, cy
table.insert(stack, {cx, cy})
else
-- no moves, remove the last entry on the stack
table.remove(stack)
if #stack == 0 then
finished = true
cx, cy = -1, -1
else
cx, cy = stack[#stack][1], stack[#stack][2]
end
end
end

function getEligibleNeighbours(x, y)
-- gets if a space two spaces away is legal and if it's a wall
-- if both adds a dx, dy to neighbours (only +/-1 as we'll use it twice when we dig)
local neighbours = {}
-- north
if y > 2 then
if map[x][y-2] == 0 then
table.insert(neighbours, {0, -1})
end
end
-- east
if x < mapWidth - 1 then
if map[x+2][y] == 0 then
table.insert(neighbours, {1, 0})
end
end
-- south
if y < mapHeight - 1 then
if map[x][y+2] == 0 then
table.insert(neighbours, {0, 1})
end
end
-- west
if x > 2 then
if map[x-2][y] == 0 then
table.insert(neighbours, {-1, 0})
end
end
-- shuffle the array if we have more than one elgible
-- five times should be fine we're only going to have 2 or 3 entries at most
if #neighbours > 1 then
shuffleArray(neighbours, 5)
end
return neighbours
end

-- quick and dirty array shuffle
function shuffleArray(array, num)
local s1, s2
for _ = 1, num do
s1 = math.random(#array)
s2 = math.random(#array)
array[s1], array[s2] = array[s2], array[s1]
end
end

function love.draw()
for x = 1, mapWidth do
for y = 1, mapHeight do
if x == cx and y == cy then
love.graphics.setColor(0.7, 0.2, 0.2)
elseif map[x][y] == 1 then
love.graphics.setColor(0.7, 0.7, 0.7)
else
love.graphics.setColor(0.2, 0.2, 0.2)
end
love.graphics.rectangle("fill", x * tileSize, y * tileSize, tileSize, tileSize)
end
end
end
dusoft
Party member
Posts: 466
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

### Re: Code Doodles!

Good job! The maze creator works well and is something to look at.
pgimeno
Party member
Posts: 3533
Joined: Sun Oct 18, 2015 2:58 pm

### Re: Code Doodles!

Trystan wrote: Mon Feb 12, 2024 2:58 pm I was toying around with mazes the other day and found the recursive backtracker to be pretty easy to implement and generally nice to look at. It guarantees a maze where every spot is filled in and all spots are on a single network.
There's a thread expressly dedicated to mazes:

viewtopic.php?t=19873

In fact I recently wrote an implementation of Kruskal's algorithm and was going to post it there.
glitchapp
Party member
Posts: 231
Joined: Tue Oct 05, 2021 10:34 am
Contact:

### Re: Code Doodles!

Trystan wrote: Mon Feb 12, 2024 2:58 pm I was toying around with mazes the other day and found the recursive backtracker to be pretty easy to implement and generally nice to look at. It guarantees a maze where every spot is filled in and all spots are on a single network.

f1 to generates a new maze.

RecursiveBacktracker.png

Code: Select all

function love.load()
love.window.setTitle("Recursive Backtracking Maze")
math.randomseed(os.time())
math.random(); math.random(); math.random()
-- set map width and height, should be odd numbers
mapWidth = 131
mapHeight = 81
tileSize = 8
-- resize window to maze
love.window.setMode((mapWidth+2)*tileSize,(mapHeight+2)*tileSize)
generateMap()
end

function love.keypressed(key)
if key=="f1" then
generateMap()
end
end

function generateMap()
-- make a map full of walls
map = {}
for x = 1, mapWidth do
map[x] = {}
for y = 1, mapHeight do
map[x][y] = 0
end
end
-- make the maze
generateMaze()
end

function generateMaze()
-- make maze using the recursive backtracker algorithm
-- set and dig the starting space
local sx, sy = math.random(1,math.floor(mapWidth/2)) * 2, math.random(1, math.floor(mapHeight/2)) * 2
stack = {{sx, sy}}
map[sx][sy] = 1
local neighbours, tx, ty
while #stack > 0 do
tx, ty = stack[#stack][1], stack[#stack][2]
neighbours = getEligibleNeighbours(tx, ty)
if #neighbours > 0 then
-- we've got moves, take the first and dig!
-- first the intermediate space
tx = tx + neighbours[1][1]
ty = ty + neighbours[1][2]
map[tx][ty] = 1
-- then the destination space
tx = tx + neighbours[1][1]
ty = ty + neighbours[1][2]
map[tx][ty] = 1
-- add the tile to the end of the stack
table.insert(stack, {tx, ty})
else
-- no moves, remove the last entry on the stack
table.remove(stack)
end
end
end

function getEligibleNeighbours(x, y)
-- gets if a space two spaces away is legal and if it's a wall
-- if both adds a dx, dy to neighbours (only +/-1 as we'll use it twice when we dig)
local neighbours = {}
-- north
if y > 2 then
if map[x][y-2] == 0 then
table.insert(neighbours, {0, -1})
end
end
-- east
if x < mapWidth - 1 then
if map[x+2][y] == 0 then
table.insert(neighbours, {1, 0})
end
end
-- south
if y < mapHeight - 1 then
if map[x][y+2] == 0 then
table.insert(neighbours, {0, 1})
end
end
-- west
if x > 2 then
if map[x-2][y] == 0 then
table.insert(neighbours, {-1, 0})
end
end
-- shuffle the array if we have more than one elgible
-- five times should be fine we're only going to have 2 or 3 entries at most
if #neighbours > 1 then
shuffleArray(neighbours, 5)
end
return neighbours
end

-- quick and dirty array shuffle
function shuffleArray(array, num)
local s1, s2
for _ = 1, num do
s1 = math.random(#array)
s2 = math.random(#array)
array[s1], array[s2] = array[s2], array[s1]
end
end

function love.draw()
for x = 1, mapWidth do
for y = 1, mapHeight do
if map[x][y] == 1 then
love.graphics.setColor(0.7, 0.7, 0.7)
else
love.graphics.setColor(0.2, 0.2, 0.2)
end
love.graphics.rectangle("fill", x * tileSize, y * tileSize, tileSize, tileSize)
end
end
end
Edit: Just for fun I made a version that shows the process of creating the maze, instead of just drawing it all at once.

Code: Select all

function love.load()
love.window.setTitle("Recursive Backtracking Maze")
math.randomseed(os.time())
math.random(); math.random(); math.random()
-- set map width and height, should be odd numbers
mapWidth = 81
mapHeight = 61
tileSize = 8
love.window.setMode((mapWidth+2)*tileSize,(mapHeight+2)*tileSize)
generateMap()
end

function love.keypressed(key)
if key=="f1" then
generateMap()
end
end

function generateMap()
-- make a map full of walls
finished = false
map = {}
for x = 1, mapWidth do
map[x] = {}
for y = 1, mapHeight do
map[x][y] = 0
end
end
-- set and dig the starting space
cx, cy = math.random(1,math.floor(mapWidth/2)) * 2, math.random(1, math.floor(mapHeight/2)) * 2
stack = {{cx, cy}}
map[cx][cy] = 1
end

function love.update()
if finished == false then
generateMaze()
end
end

function generateMaze()
-- make maze using the recursive backtracker algorithm
local neighbours, tx, ty
cx, cy = stack[#stack][1], stack[#stack][2]
neighbours = getEligibleNeighbours(cx, cy)
if #neighbours > 0 then
-- we've got moves, take the first and dig!
-- first the intermediate space
cx = cx + neighbours[1][1]
cy = cy + neighbours[1][2]
map[cx][cy] = 1
-- then the destination space
cx = cx + neighbours[1][1]
cy = cy + neighbours[1][2]
map[cx][cy] = 1
-- add the tile to the end of the stack
cx, cy = cx, cy
table.insert(stack, {cx, cy})
else
-- no moves, remove the last entry on the stack
table.remove(stack)
if #stack == 0 then
finished = true
cx, cy = -1, -1
else
cx, cy = stack[#stack][1], stack[#stack][2]
end
end
end

function getEligibleNeighbours(x, y)
-- gets if a space two spaces away is legal and if it's a wall
-- if both adds a dx, dy to neighbours (only +/-1 as we'll use it twice when we dig)
local neighbours = {}
-- north
if y > 2 then
if map[x][y-2] == 0 then
table.insert(neighbours, {0, -1})
end
end
-- east
if x < mapWidth - 1 then
if map[x+2][y] == 0 then
table.insert(neighbours, {1, 0})
end
end
-- south
if y < mapHeight - 1 then
if map[x][y+2] == 0 then
table.insert(neighbours, {0, 1})
end
end
-- west
if x > 2 then
if map[x-2][y] == 0 then
table.insert(neighbours, {-1, 0})
end
end
-- shuffle the array if we have more than one elgible
-- five times should be fine we're only going to have 2 or 3 entries at most
if #neighbours > 1 then
shuffleArray(neighbours, 5)
end
return neighbours
end

-- quick and dirty array shuffle
function shuffleArray(array, num)
local s1, s2
for _ = 1, num do
s1 = math.random(#array)
s2 = math.random(#array)
array[s1], array[s2] = array[s2], array[s1]
end
end

function love.draw()
for x = 1, mapWidth do
for y = 1, mapHeight do
if x == cx and y == cy then
love.graphics.setColor(0.7, 0.2, 0.2)
elseif map[x][y] == 1 then
love.graphics.setColor(0.7, 0.7, 0.7)
else
love.graphics.setColor(0.2, 0.2, 0.2)
end
love.graphics.rectangle("fill", x * tileSize, y * tileSize, tileSize, tileSize)
end
end
end
I love it! I though of making a game out of this and here it is: play it with gamepad(thumbstick), keys needs to be tweaked and do not work as expected.

I'm not sure if the maze is always solvable... let me know if you manage to get to the exit...
Attachments
playable-maze.love
glitchapp
Party member
Posts: 231
Joined: Tue Oct 05, 2021 10:34 am
Contact:

### Re: Code Doodles!

I added touch controls and set the maze to horizontal layout to fit on mobiles just in case anyone want to play with it on mobiles.
Attachments
screenshot.jpg (153.26 KiB) Viewed 481 times
Recursive-Maze-Game-v0.1.love