Tuesday, September 2, 2025

Maze generator in GW-BASIC

 A while back I was looking at maze making algorithms written in Basic. I was not very happy with any of the ones I could find at the time, they where quite dumb and inefficient. So I decided to write my own. The geometry of the maze is controlled by the MAPX, MAPY and MAPZ variables. The code below is set to generate just one floor.

10 REM Maze Generator in GW-BASIC
11 REM Uses bits for walls: 1=West, 2=North, 4=East, 8=South, 16=Up
12 REM 0 means no walls (connected to all adjacent rooms)
13 REM by Conradtrout 2025

20 DEFINT A-Z
30 MAPX = 5: MAPY = 5: MAPZ = 1
40 DIM MAZE(MAPX,MAPY,MAPZ)
50 DIM CURPATH(MAPX*MAPY, 2)
60 RANDOMIZE TIMER

70 REM Initialize/reset maze
80 FOR TZ = 1 TO MAPZ
90 FOR TY = 1 TO MAPY
100 FOR TX = 1 TO MAPX: MAZE(TX,TY,TZ) = 0: NEXT TX
110 NEXT TY
120 NEXT TZ
130 GOSUB 900 ' Generate map
140 FLOOR=1
150 GOSUB 1100 ' Print map
160 PRINT "FINISHED ON X:";X;"Y:";Y
170 PRINT "PRESS ANY KEY...": AKEY$ = INPUT$(1)
180 IF FLOOR = MAPZ THEN 499
190 FLOOR = FLOOR + 1: GOTO 150

499 END

500 REM Maze Generator start sub-routine
510 CURSTEP = 0
520 REM Jumps back here.
530 CURDIRS = 0
540 IF X > 1 THEN IF MAZE(X-1,Y,FLOOR) = 0 THEN CURDIRS = CURDIRS OR 1
550 IF X < MAPX THEN IF MAZE(X+1,Y,FLOOR) = 0 THEN CURDIRS = CURDIRS OR 4
560 IF Y > 1 THEN IF MAZE(X,Y-1,FLOOR) = 0 THEN CURDIRS = CURDIRS OR 2
570 IF Y < MAPY THEN IF MAZE(X,Y+1,FLOOR) = 0 THEN CURDIRS = CURDIRS OR 8
580 IF CURDIRS = 0 THEN GOSUB 800: IF EMPTYROOMS = 0 THEN RETURN ' Finished!

600 REM Randomly choosing where to go. Steps backward if we must.
610 REM Reserved for a cond. stop. Never mind this line. :-)
620 HEADING = 2 ^ INT(RND * 4)
630 IF (CURDIRS AND HEADING) <> 0 THEN GOSUB 700: GOTO 520 ' Moved cursor forward.
640 CURDIRS = CURDIRS AND (NOT HEADING)
650 IF CURDIRS > 0 THEN 620 ' If not true then move cursor back.
660 CURSTEP = CURSTEP - 1: X = CURPATH(CURSTEP, 1): Y = CURPATH(CURSTEP, 2)
670 GOTO 520

700 REM Move cursor forward (into unvisited room)
710 CURPATH(CURSTEP, 1) = X: CURPATH(CURSTEP, 2) = Y: OLDX = X: OLDY = Y
720 IF HEADING = 1 THEN X = X-1: RHEADING = 4: GOTO 760
730 IF HEADING = 2 THEN Y = Y-1: RHEADING = 8: GOTO 760
740 IF HEADING = 4 THEN X = X+1: RHEADING = 1: GOTO 760
750 IF HEADING = 8 THEN Y = Y+1: RHEADING = 2: GOTO 760
751 STOP ' Should never happen. Hopefully. :-)
760 CURSTEP = CURSTEP+1
770 MAZE(X,Y,FLOOR) = MAZE(X,Y,FLOOR) OR RHEADING
780 MAZE(OLDX,OLDY,FLOOR) = MAZE(OLDX,OLDY,FLOOR) OR HEADING
790 RETURN

800 REM Check for unvisited rooms
810 EMPTYROOMS = 0
820 FOR TY = 1 TO MAPY
830 FOR TX = 1 TO MAPX
840 IF MAZE(TX,TY,FLOOR) = 0 THEN EMPTYROOMS = -1: RETURN
850 NEXT TX
860 NEXT TY
870 RETURN

900 REM Start of map gen.
910 X=1+INT(RND*MAPX): Y=1+INT(RND*MAPY)
920 FOR FLOOR = 1 TO MAPZ
930 PRINT "GENERATING FLOOR"; FLOOR; "..."
940 GOSUB 500: REM Run Mazegen sub-routine
950 FOR TY = 1 TO MAPY
960 FOR TX = 1 TO MAPX: MAZE(TX,TY,FLOOR) = 15 AND NOT MAZE(TX,TY,FLOOR): NEXT TX
970 NEXT TY
980 IF FLOOR < MAPZ THEN MAZE(X,Y,FLOOR) = MAZE(X,Y,FLOOR) OR 16
990 NEXT FLOOR
1000 RETURN

1100 REM Print the maze
1110 CLS: PRINT "+";
1120 FOR TX = 1 TO MAPX: PRINT "---+";: NEXT TX
1130 PRINT
1140 FOR TY = 1 TO MAPY
1150 PRINT "|";
1160 FOR TX = 1 TO MAPX
1170 IF (MAZE(TX,TY,FLOOR) AND 16) <> 0 THEN R$="U" ELSE R$=" "
1180 IF FLOOR > 1 THEN IF (MAZE(TX,TY,FLOOR-1) AND 16) <> 0 THEN R$="D"
1190 IF (MAZE(TX,TY,FLOOR) AND 4) = 0 THEN PRINT " ";R$;"  "; ELSE PRINT " ";R$;" |";
1200 NEXT TX
1210 PRINT
1220 PRINT "+";
1230 FOR TX = 1 TO MAPX
1240 IF (MAZE(TX,TY,FLOOR) AND 8) = 0 THEN PRINT "   +"; ELSE PRINT "---+";
1250 NEXT TX
1260 PRINT
1270 NEXT TY
1280 PRINT
1290 REM RETURN
1300 PRINT "Maze Array (Bit Values):"
1310 FOR TY = 1 TO MAPY
1320 FOR TX = 1 TO MAPX
1330 PRINT TAB(2+(TX-1)*4); MID$(STR$(MAZE(TX,TY,FLOOR)),2);
1340 NEXT TX
1350 PRINT
1360 NEXT TY
1370 RETURN

No comments:

Post a Comment

Maze generator in GW-BASIC

 A while back I was looking at maze making algorithms written in Basic. I was not very happy with any of the ones I could find at the time, ...