Hello All,
I am not able to contribute much, due to a demanding home life, but I was messing around with some old DB Pro code today and was able to get it working in AGK.
It's pretty fast, as it is, but suggestions are most welcome.
Let me know what you think:
To change the Cell size, adjust the bSize variable.
To change the Maze size, change the mSize variable.
setVirtualResolution (960, 640)
GOSUB draw_init
GOSUB InitVariables
rem Main Loop
do
GOSUB GenerateMaze
SYNC()
loop
InitVariables:
True = 1
False = 0
bSize = 24 ` Cell Size
mSize = 16 ` Size of Maze in Cells (ex. 16x16, 20x20, 64x64 etc.)
tSize = mSize^2 ` Total Cells
mHeight = mSize * bSize ` Height of Maze
mWidth = mSize * bSize ` Width of Maze
ShowDraw = 1 ` 1 = Show Maze being drawn; 0 = Don't show Maze until complete
ShowRate = trunc(mSize/3) ` Number of cells to complete between redraws
cMaze = 0 ` Maze Completed Flag
type Blocks
X1 AS INTEGER ` X-coordinate for the top left corner of cell
Y1 AS INTEGER ` Y-coordinate for the top left corner of cell
X2 AS INTEGER ` X-coordinate for the bottom right corner of cell
Y2 AS INTEGER ` Y-coordinate for the bottom right corner of cell
SW AS INTEGER ` South Wall: True = exists; False = does not exist
EW AS INTEGER ` East Wall: True = exists; False = does not exist
Used AS INTEGER ` Has this Block been visited?
isBoundry AS INTEGER ` Checks to see if this cell is on the boundry of the maze
endtype
DIM Maze[tSize] AS Blocks ` Maze Block Array
DIM Track[tSize] AS INTEGER ` Maze Backtrack Array
RETURN
GenerateMaze:
bLeft = 0: q = 0: n = 0
GOSUB initialize
GOSUB StartPosition
repeat
TryAgain:
Track[bLeft] = s
q = q + 1
` Reached a dead end, backtrack along the existing path and find another route.
if q > 10
q = 0: n = n + 1: if n > bLeft then n = 0
s = Track[bLeft - n]
endif
x = RANDOM(0, 3)
` 0 = South
` 1 = East
` 2 = West
` 3 = North
if x = 0 ` South - Knock down the South Wall
if (s + 1) > tSize - 1 then GOTO Tryagain
if Maze[s].isBoundry = True AND Maze[s + 1].isBoundry = True then GOTO TryAgain
if Maze[s + 1].Used = False
Maze[s].SW = False
bLeft = bLeft + 1: q = 0: n = 0
s = s + 1: if s > tSize - 1 then s = tSize - 1
Maze[s].Used = True
else
GOTO TryAgain
endif
endif
if x = 1 ` East - Knock down the East Wall
if (s + mSize) > tSize - 1 then GOTO TryAgain
if Maze[s + mSize].Used = False
Maze[s].EW = False
bLeft = bLeft + 1: q = 0: n = 0
s = s + mSize: if s > tSize - 1 then s = tSize - 1
Maze[s].Used = True
else
GOTO TryAgain
endif
endif
if x = 2 ` West - Knock down the East Wall of adjacent block
if (s - mSize) < 0 then GOTO TryAgain
if Maze[s - mSize].Used = False
Maze[s - mSize].EW = False
bLeft = bLeft + 1: q = 0: n = 0
s = s - mSize: if s < 0 then s = 0
Maze[s].Used = True
else
GOTO TryAgain
endif
endif
if x = 3 ` North - Knock down the South Wall of adjacent block
if (s - 1) < 0 then GOTO TryAgain
if Maze[s].isBoundry = True AND Maze[s - 1].isBoundry = True then GOTO TryAgain
if Maze[s - 1].Used = False
Maze[s - 1].SW = False
bLeft = bLeft + 1: q = 0: n = 0
s = s - 1: if s < 0 then s = 0
Maze[s].Used = True
else
GOTO TryAgain
endif
endif
if ShowDraw = 1
if (bLeft mod ShowRate) = 0
GOSUB DrawMaze
Text(1, mHeight + 10, "Maze is: " + str(mSize) + " x " + str(mSize) + " Total Cells: " + str(tSize))
Text(1, mHeight + 50, "Press Space to draw another one.")
SYNC()
deleteDraw()
endif
endif
until bLeft = tSize - 1
if ShowDraw = 1
repeat: until GetRawKeyPressed(32) = 1
endif
cMaze = 1 ` Maze Complete
RETURN
initialize:
` Initialize the Maze
z = -bSize: x = 0
for y = 0 TO tSize - 1
z = z + bSize
if y <> 0 AND (y mod mSize) = 0
z = 0
x = x + bSize
endif
Maze[y].SW = True
Maze[y].EW = True
Maze[y].X1 = TRUNC(x)
Maze[y].Y1 = TRUNC(z)
Maze[y].X2 = TRUNC(x + bSize)
Maze[y].Y2 = TRUNC(z + bSize)
Maze[y].Used = False
if (y mod mSize) = 0 OR (y mod mSize) = mSize - 1
Maze[y].isBoundry = True
else
Maze[y].isBoundry = False
endif
next y
RETURN
StartPosition:
` Pick a random starting place to generate the Maze
Restart:
s = RANDOM(0, tSize - 1)
if (s - mSize) < 0 then GOTO Restart
if (s - 1) < 0 then GOTO Restart
if (s + 1) > tSize - 1 then GOTO Restart
if (s + mSize) > tSize - 1 then GOTO Restart
if Maze[s].Used = True then GOTO Restart
Maze[s].Used = True
RETURN
DrawMaze:
for y = 0 TO tSize - 1
` Draw the South Walls
if Maze[y].SW = True
drawLine(Maze[y].X1, Maze[y].Y2, Maze[y].X2, Maze[y].Y2, 255, 255, 255, 255)
endif
` Draw the East Walls
if Maze[y].EW = True
drawLine(Maze[y].X2, Maze[y].Y1, Maze[y].X2, Maze[y].Y2, 255, 255, 255, 255)
endif
next y
` Draw Boundries
drawLine(0, 0, mWidth, 0, 255, 255, 255, 255) ` North Boundry
drawLine(0, 0, 0, mHeight, 255, 255, 255, 255) ` West Boundry
sync()
RETURN
`######## DRAW COMMANDS by Steven Holding ########
draw_init:
rem set up some draw constants
global aspect as float
aspect = getDisplayAspect()
#constant pw (1.0/getDeviceWidth())*getVirtualWidth()
#constant ph (1.0/getDeviceHeight())*getVirtualHeight()
if pw=1.0 and ph=1.0
aspect=1.0
endif
dim draw[0] as integer
draw[0] = 0
return
function deleteDraw()
num = draw[0]
for i=1 to num
deleteSprite(draw[i])
next
dim draw[0] as integer
draw[0]=0
endfunction
function drawLine(x1 as float, y1 as float, x2 as float, y2 as float, red as float, green as float, blue as float, alpha as float)
DS = createSprite(0)
setSpriteDepth(DS,0)
dx#=x2-x1
dy#=(y2-y1)/aspect
l# = sqrt(dx#*dx#+dy#*dy#)
setSpriteSize(DS,l#,ph)
a# = atanfull(dx#,dy#)-90.0
setSpriteAngle(DS,a#)
setSpriteOffset(DS,0,ph*0.5)
setSpritePosition(DS,x1,y1)
setSpriteColor(DS,red,green,blue,alpha)
num = draw[0]+1
draw[0]=num
dim draw[num] as integer
draw[num] = DS
endfunction DS
Function Text( X#, Y#, txt$ )
Dim T_NumText[0] as integer
Dim T_Texts[T_NumText[0]] as integer
Dim OldSync[0] as float
Dim NewSync[0] as float
NewSync[0] = ScreenFPS()
// if a sync has occured then delete all text
Temp = T_NumText[0]
If NewSync[0] <> OldSync[0]
For n = 0 to Temp
if GetTextExists(T_Texts[n]) = 1
DeleteText(T_Texts[n])
T_NumText[0] = T_NumText[0] - 1
endif
Next n
Endif
T_NumText[0] = T_NumText[0] + 1
Dim T_Texts[T_NumText[0]] as integer
T_Texts[T_NumText[0]] = CreateText( txt$ )
SetTextPosition( T_Texts[T_NumText[0]], X#, Y# )
If GetVirtualWidth() > 100
SetTextSize(T_Texts[T_NumText[0]], (4.0 / 100.0) * 480)
Endif
OldSync[0] = ScreenFPS()
Endfunction
Thanks to baxslash for the drawing functions and to Hodgey for the Text command function!!
Thank you,
JHA