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