Hey I like mazeit.bas, it nicely illustrates how the maze making business takes place and why any point can be reached from any other in a proper maze.

If you like that, here is the mazeit with cell size override:

Code:

OPTION _EXPLICIT
_DEFINE A-Z AS _FLOAT

TYPE Cells
i AS _FLOAT
j AS _FLOAT
walls AS STRING * 4
visited AS _BYTE
END TYPE

CONST True = -1
CONST False = NOT True

DIM m$
DIM SHARED cols, rows
DIM SHARED w, j, i
DIM SHARED current
DIM SHARED stack AS STRING
DIM SHARED Ended
DIM SHARED Limit, k, IconSet AS _BYTE
REDIM SHARED grid(0) AS Cells
' size of square
CLS
DO
PRINT "Enter number of squares(10,25,50,100)";
INPUT w: w = INT(w)
IF w = 10 OR w = 25 OR w = 50 OR w = 100 THEN EXIT DO
LOOP

_TITLE "MAZEGEN"
SCREEN _NEWIMAGE(601, 601, 32)
_PRINTMODE _KEEPBACKGROUND
RANDOMIZE TIMER
DO
Setup
Limit = 10
DO
DrawIt
IF NOT IconSet THEN
_ICON _DEST
IconSet = True
END IF
k = _KEYHIT
IF k = 27 THEN
IF Limit > 0 THEN Limit = 0 ELSE EXIT DO
END IF
_DISPLAY
IF Limit > 0 THEN
_LIMIT Limit
END IF
LOOP UNTIL Ended
m$ = "Restart (y/n)?"
COLOR _RGB32(0, 0, 0)
_PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2 + 2, _HEIGHT / 2 - _FONTHEIGHT / 2 + _FONTHEIGHT + 2), m$
COLOR _RGB32(255, 255, 255)
_PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2, _HEIGHT / 2 - _FONTHEIGHT / 2 + _FONTHEIGHT), m$
_DISPLAY
DO
m$ = LCASE$(INPUT$(1))
LOOP UNTIL m$ = "y" OR m$ = "n"
LOOP WHILE m$ = "y"
SYSTEM

'------------------------------------------------------------------------------------------------------
SUB Setup
cols = INT(_WIDTH / w)
rows = INT(_HEIGHT / w)
REDIM grid(rows * cols) AS Cells
FOR j = 0 TO rows - 1
FOR i = 0 TO cols - 1
grid(index(i, j)).i = i
grid(index(i, j)).j = j
grid(index(i, j)).walls = "1111"
grid(index(i, j)).visited = False
NEXT
NEXT
current = 0
Ended = False
END SUB

'------------------------------------------------------------------------------------------------------
SUB DrawIt
DIM it, nextCell AS Cells, nextCellIndex
CLS , _RGB32(51, 51, 51)
FOR it = 0 TO UBOUND(grid)
Show grid(it)
NEXT
grid(current).visited = True
Highlight grid(current)

'Step 1
CheckNeighbors grid(current), nextCell

IF nextCell.i > -1 THEN
nextCellIndex = index(nextCell.i, nextCell.j)
grid(nextCellIndex).visited = True

'Step 4
current = nextCellIndex
ELSE
IF LEN(stack) > 0 THEN
current = CVI(RIGHT$(stack, 2))
stack = LEFT$(stack, LEN(stack) - 2)
ELSE
'Maze is finished, we're back at 0, 0
DIM m$
m$ = "Maze Generator: DONE!"
COLOR _RGB32(0, 0, 0)
_PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2 + 2, _HEIGHT / 2 - _FONTHEIGHT / 2 + 2), m$
COLOR _RGB32(255, 255, 255)
_PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2, _HEIGHT / 2 - _FONTHEIGHT / 2), m$
Ended = True
END IF
END IF
END SUB

'------------------------------------------------------------------------------------------------------
SUB RemoveWalls (a AS Cells, b AS Cells)
DIM x, y

x = a.i - b.i
IF x = 1 THEN
MID$(a.walls, 4, 1) = "0"
MID$(b.walls, 2, 1) = "0"
ELSEIF x = -1 THEN
MID$(a.walls, 2, 1) = "0"
MID$(b.walls, 4, 1) = "0"
END IF

y = a.j - b.j
IF y = 1 THEN
MID$(a.walls, 1, 1) = "0"
MID$(b.walls, 3, 1) = "0"
ELSEIF y = -1 THEN
MID$(a.walls, 3, 1) = "0"
MID$(b.walls, 1, 1) = "0"
END IF
END SUB

'------------------------------------------------------------------------------------------------------
SUB Show (This AS Cells)
DIM x, y
x = This.i * w
y = This.j * w
IF This.visited THEN
LINE (x, y)-STEP(w - 1, w - 1), _RGBA32(255, 0, 255, 50), BF
END IF
IF MID$(This.walls, 1, 1) = "1" THEN
LINE (x, y)-(x + w - 1, y), _RGBA32(255, 255, 255, 100)
END IF
IF MID$(This.walls, 2, 1) = "1" THEN
LINE (x + w - 1, y)-(x + w - 1, y + w - 1), _RGBA32(255, 255, 255, 100)
END IF
IF MID$(This.walls, 3, 1) = "1" THEN
LINE (x, y + w - 1)-(x + w - 1, y + w - 1), _RGBA32(255, 255, 255, 100)
END IF
IF MID$(This.walls, 4, 1) = "1" THEN
LINE (x, y)-(x, y + w - 1), _RGBA32(255, 255, 255, 100)
END IF
END SUB

'------------------------------------------------------------------------------------------------------
SUB Highlight (This AS Cells)
DIM x, y
x = This.i * w
y = This.j * w
LINE (x + 1, y + 1)-STEP(w - 2, w - 2), _RGBA32(0, 255, 0, 100), BF
END SUB

'------------------------------------------------------------------------------------------------------
SUB CheckNeighbors (This AS Cells, Result AS Cells)
DIM Neighbors(3) AS Cells, TotalNeighbors, Selected, Check
DIM FoundNeighbors AS STRING

IF index(This.i, This.j - 1) > -1 THEN
IF grid(index(This.i, This.j - 1)).visited = False THEN
Neighbors(0) = grid(index(This.i, This.j - 1))
TotalNeighbors = TotalNeighbors + 1
FoundNeighbors = MKI$(0)
END IF
END IF
IF index(This.i + 1, This.j) > -1 THEN
IF grid(index(This.i + 1, This.j)).visited = False THEN
Neighbors(1) = grid(index(This.i + 1, This.j))
TotalNeighbors = TotalNeighbors + 1
FoundNeighbors = FoundNeighbors + MKI$(1)
END IF
END IF
IF index(This.i, This.j + 1) > -1 THEN
IF grid(index(This.i, This.j + 1)).visited = False THEN
Neighbors(2) = grid(index(This.i, This.j + 1))
TotalNeighbors = TotalNeighbors + 1
FoundNeighbors = FoundNeighbors + MKI$(2)
END IF
END IF
IF index(This.i - 1, This.j) > -1 THEN
IF grid(index(This.i - 1, This.j)).visited = False THEN
Neighbors(3) = grid(index(This.i - 1, This.j))
TotalNeighbors = TotalNeighbors + 1
FoundNeighbors = FoundNeighbors + MKI$(3)
END IF
END IF

IF TotalNeighbors = 0 THEN
Result.i = -1
ELSE
Selected = _CEIL(RND * TotalNeighbors)
Result = Neighbors(CVI(MID$(FoundNeighbors, Selected * 2 - 1, 2)))
END IF
END SUB

'------------------------------------------------------------------------------------------------------
FUNCTION index (i, j)
IF i < 0 OR j < 0 OR i > cols - 1 OR j > rows - 1 THEN
index = -1
ELSE
index = i + j * cols
END IF
END FUNCTION

DO
PRINT "Enter number of squares(10,25,50,100)";
INPUT w: w = INT(w)
IF w = 10 OR w = 25 OR w = 50 OR w = 100 THEN EXIT DO
LOOP

What you are doing with w is calculating cols = _width/w and rows =_height/w
st rows * cols = number of squares.

Code:

SUB Setup
cols = INT(_WIDTH / w)
rows = INT(_HEIGHT / w)
REDIM grid(rows * cols) AS Cells
FOR j = 0 TO rows - 1

So w = 10, 25, 50, 100 is really the number of pixels per side of each cell, such that 10 yields the most number of squares and likewise 100 yields the least number of squares.

One of the things I have been studying over the years is the science of "User Interface" or "UI", so I could learn how to make my demos (and other projects) easier on the user.

While the maze generation demo you created was awesome, to say the least, I did, however, shriek at the thought of asking the user to type in a number from a list at the beginning. If they didn't enter exactly what you had listed, then they had to do over and over again until they did it right, which isn't very "user-friendly".

While this may not be a big project where you would need to focus on UI, it would still be cool to have a better way of allowing the user to select one of the quantities instead of typing something in. What would also be cool is if the user gets to see the grid before they choose quantity.

However, I will not ask you to make these changes yourself, since I seem to be the only one who has an issue with the UI. So, I decided to take it upon myself to add a semi-decent UI to allow the user to select the pixel size of the cells and to show what the grid will look like before the demo starts generating the maze.

Here is a screenshot:

Here is the code:

Code:

OPTION _EXPLICIT
_DEFINE A-Z AS _FLOAT

TYPE Cells
i AS _FLOAT
j AS _FLOAT
walls AS STRING * 4
visited AS _BYTE
END TYPE

CONST True = -1
CONST False = NOT True

DIM m$
DIM SHARED cols, rows
DIM SHARED w, j, i
DIM SHARED current
DIM SHARED stack AS STRING
DIM SHARED Ended
DIM SHARED Limit, k, IconSet AS _BYTE
REDIM SHARED grid(0) AS Cells
' size of square

DIM Keycode AS LONG
DIM SampleGridWidth AS _UNSIGNED INTEGER
DIM SampleGridHeight AS _UNSIGNED INTEGER
DIM SampleGridXStep AS _FLOAT
DIM SampleGridYStep AS _FLOAT

LOCATE 2, 2
COLOR 14
PRINT "Please use the "; CHR$(24); " & "; CHR$(25); " arrow keys to select the cell size of the grid:"

FOR i = 0 TO UBOUND(NumberOfSquaresList) - 1

LOCATE i + 4, 3

IF i = CurrentSelection THEN
COLOR 15, 2
ELSE
COLOR 15, 0
END IF

PRINT NumberOfSquaresList(i); " Pixels Per Side ";

NEXT

COLOR 15, 0

LINE (100, 150)-(100 + SampleGridWidth, 150 + SampleGridHeight), _RGB(51, 51, 51), BF
LINE (100, 150)-(100 + SampleGridWidth, 150 + SampleGridHeight), 7, B

FOR X = 1 TO SampleGridWidth STEP SampleGridXStep * NumberOfSquaresList(CurrentSelection)
X1 = X + 99
Y1 = 150
Y2 = 150 + SampleGridHeight
LINE (X1, Y1)-(X1, Y2), 7
NEXT

FOR Y = 1 TO SampleGridHeight STEP SampleGridYStep * NumberOfSquaresList(CurrentSelection)
X1 = 100
X2 = X1 + SampleGridWidth
Y1 = Y + 149
LINE (X1, Y1)-(X2, Y1), 7
NEXT

Keycode = _KEYHIT

SELECT CASE Keycode

CASE 18432 ' UP ARROW KEY

CurrentSelection = CurrentSelection - 1

IF CurrentSelection < 0 THEN CurrentSelection = UBOUND(NumberOfSquaresList) - 1

CASE 20480 ' DOWN ARROW KEY

CurrentSelection = CurrentSelection + 1

IF CurrentSelection > UBOUND(NumberOfSquaresList) - 1 THEN CurrentSelection = 0

Limit = 10
DO
DrawIt
IF NOT IconSet THEN
_ICON _DEST
IconSet = True
END IF
k = _KEYHIT
IF k = 27 THEN
IF Limit > 0 THEN Limit = 0 ELSE EXIT DO
END IF
_DISPLAY
IF Limit > 0 THEN
_LIMIT Limit
END IF
LOOP UNTIL Ended
m$ = "Restart (y/n)?"
COLOR _RGB32(0, 0, 0)
_PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2 + 2, _HEIGHT / 2 - _FONTHEIGHT / 2 + _FONTHEIGHT + 2), m$
COLOR _RGB32(255, 255, 255)
_PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2, _HEIGHT / 2 - _FONTHEIGHT / 2 + _FONTHEIGHT), m$
_DISPLAY
DO
m$ = LCASE$(INPUT$(1))
LOOP UNTIL m$ = "y" OR m$ = "n"
LOOP WHILE m$ = "y"
SYSTEM

'------------------------------------------------------------------------------------------------------
SUB Setup
cols = INT(_WIDTH / w)
rows = INT(_HEIGHT / w)
REDIM grid(rows * cols) AS Cells
FOR j = 0 TO rows - 1
FOR i = 0 TO cols - 1
grid(index(i, j)).i = i
grid(index(i, j)).j = j
grid(index(i, j)).walls = "1111"
grid(index(i, j)).visited = False
NEXT
NEXT
current = 0
Ended = False
END SUB

'------------------------------------------------------------------------------------------------------
SUB DrawIt
DIM it, nextCell AS Cells, nextCellIndex
CLS , _RGB32(51, 51, 51)
FOR it = 0 TO UBOUND(grid)
Show grid(it)
NEXT
grid(current).visited = True
Highlight grid(current)

'Step 1
CheckNeighbors grid(current), nextCell

IF nextCell.i > -1 THEN
nextCellIndex = index(nextCell.i, nextCell.j)
grid(nextCellIndex).visited = True

'Step 4
current = nextCellIndex
ELSE
IF LEN(stack) > 0 THEN
current = CVI(RIGHT$(stack, 2))
stack = LEFT$(stack, LEN(stack) - 2)
ELSE
'Maze is finished, we're back at 0, 0
DIM m$
m$ = "Maze Generator: DONE!"
COLOR _RGB32(0, 0, 0)
_PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2 + 2, _HEIGHT / 2 - _FONTHEIGHT / 2 + 2), m$
COLOR _RGB32(255, 255, 255)
_PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2, _HEIGHT / 2 - _FONTHEIGHT / 2), m$
Ended = True
END IF
END IF
END SUB

'------------------------------------------------------------------------------------------------------
SUB RemoveWalls (a AS Cells, b AS Cells)
DIM x, y

x = a.i - b.i
IF x = 1 THEN
MID$(a.walls, 4, 1) = "0"
MID$(b.walls, 2, 1) = "0"
ELSEIF x = -1 THEN
MID$(a.walls, 2, 1) = "0"
MID$(b.walls, 4, 1) = "0"
END IF

y = a.j - b.j
IF y = 1 THEN
MID$(a.walls, 1, 1) = "0"
MID$(b.walls, 3, 1) = "0"
ELSEIF y = -1 THEN
MID$(a.walls, 3, 1) = "0"
MID$(b.walls, 1, 1) = "0"
END IF
END SUB

'------------------------------------------------------------------------------------------------------
SUB Show (This AS Cells)
DIM x, y
x = This.i * w
y = This.j * w
IF This.visited THEN
LINE (x, y)-STEP(w - 1, w - 1), _RGBA32(255, 0, 255, 50), BF
END IF
IF MID$(This.walls, 1, 1) = "1" THEN
LINE (x, y)-(x + w - 1, y), _RGBA32(255, 255, 255, 100)
END IF
IF MID$(This.walls, 2, 1) = "1" THEN
LINE (x + w - 1, y)-(x + w - 1, y + w - 1), _RGBA32(255, 255, 255, 100)
END IF
IF MID$(This.walls, 3, 1) = "1" THEN
LINE (x, y + w - 1)-(x + w - 1, y + w - 1), _RGBA32(255, 255, 255, 100)
END IF
IF MID$(This.walls, 4, 1) = "1" THEN
LINE (x, y)-(x, y + w - 1), _RGBA32(255, 255, 255, 100)
END IF
END SUB

'------------------------------------------------------------------------------------------------------
SUB Highlight (This AS Cells)
DIM x, y
x = This.i * w
y = This.j * w
LINE (x + 1, y + 1)-STEP(w - 2, w - 2), _RGBA32(0, 255, 0, 100), BF
END SUB

'------------------------------------------------------------------------------------------------------
SUB CheckNeighbors (This AS Cells, Result AS Cells)
DIM Neighbors(3) AS Cells, TotalNeighbors, Selected, Check
DIM FoundNeighbors AS STRING

IF index(This.i, This.j - 1) > -1 THEN
IF grid(index(This.i, This.j - 1)).visited = False THEN
Neighbors(0) = grid(index(This.i, This.j - 1))
TotalNeighbors = TotalNeighbors + 1
FoundNeighbors = MKI$(0)
END IF
END IF
IF index(This.i + 1, This.j) > -1 THEN
IF grid(index(This.i + 1, This.j)).visited = False THEN
Neighbors(1) = grid(index(This.i + 1, This.j))
TotalNeighbors = TotalNeighbors + 1
FoundNeighbors = FoundNeighbors + MKI$(1)
END IF
END IF
IF index(This.i, This.j + 1) > -1 THEN
IF grid(index(This.i, This.j + 1)).visited = False THEN
Neighbors(2) = grid(index(This.i, This.j + 1))
TotalNeighbors = TotalNeighbors + 1
FoundNeighbors = FoundNeighbors + MKI$(2)
END IF
END IF
IF index(This.i - 1, This.j) > -1 THEN
IF grid(index(This.i - 1, This.j)).visited = False THEN
Neighbors(3) = grid(index(This.i - 1, This.j))
TotalNeighbors = TotalNeighbors + 1
FoundNeighbors = FoundNeighbors + MKI$(3)
END IF
END IF

IF TotalNeighbors = 0 THEN
Result.i = -1
ELSE
Selected = _CEIL(RND * TotalNeighbors)
Result = Neighbors(CVI(MID$(FoundNeighbors, Selected * 2 - 1, 2)))
END IF
END SUB

'------------------------------------------------------------------------------------------------------
FUNCTION index (i, j)
IF i < 0 OR j < 0 OR i > cols - 1 OR j > rows - 1 THEN
index = -1
ELSE
index = i + j * cols
END IF
END FUNCTION

For some reason, the version of QB64 I have (qb64-1.2-20180202.85-win) forces me to declare variables before I use them. I don't like it, but I don't know how to change it at the moment. So, I DIM'd all variables I used.

I'm on my lunch break, so I took a moment to make these modifications.

Have fun!

Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.

But... I’ve been flexing a little bit of programming muscle lately. A little PHP, MySQL, JavaScript, CSS, HTML5, and a little C++. That is all on the side though. That’s all while I am packing and moving, as well as all the planning out the new project site.

Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.