!*************************** AMUS Program Label ****************************** ! Filename: MAZE2.BAS Date: 24Jan1991 ! Category: GAME Hash Code: 311-410-345-712 Version: 1.0(101) ! Initials: ARCH/US Name: STEVE ARCHULETA ! Company: ALPHA MICRO USERS SOCIETY Telephone #: 3034496917 ! Related Files: NONE ! Min. Op. Sys.: Expertise Level: BEG ! Special: ! Description: Generates random maze using proper TAB(-1,??) calls - see ! notes below. ! !***************************************************************************** ! ! This "maze generator" is the start of a game. What that game is, ! I don't know. Perhaps someone can use this to come up with something ! fun. In itself, I have tried to keep the program flexible. You can ! adjust the size of the maze by changing the initial value of SIZE (values ! from 4 to 13 will work). You can also change the position of the maze ! on the screen by adjusting the initial values of SROW and SCOL. I did not ! include the option to change the size of the maze cells. ! ! If you do try to use this for a game, you can keep track of what the ! maze "looks like" in memory by adding some code to the DRAW routines. ! Also, all generated mazes have the same general property: there is always ! a path from any one corner to any other corner. ! Steve Archuleta ! ARCH/US ! This version uses proper TCRT calls. rrm. (MCMA/AM) !========================================================================== PROGRAM MAZE2,1.0(101) ! Change these 3 values to alter size and ! position of maze. MAP1 SIZE,F,,13 ! Size of one side of grid MAP1 SROW,F,,1 ! Row (upper left corner of maze) MAP1 SCOL,F,,16 ! Column (upper left corner of maze) ! Use DIM for arrays so we can use SIZE DIM GRID(SIZE^2) ! Grid of cells represented by array DIM POS'ARRAY(SIZE^2) ! Keep track of cell positions MAP1 NUM'CELLS,F,,SIZE^2 ! Total number of cells MAP1 CELL,F ! Current cell location MAP1 NEW'CELL,F ! New cell location MAP1 SCRMAP(25,80),B,1 ! Screen map of maze MAP1 N'COUNT,F ! Neighbor cell counter MAP1 START'NUM,F ! Starting cell location MAP1 COUNT,F ! Generic counter MAP1 INDEX,F ! Generic array index MAP1 X,F ! X coordinate (column) MAP1 Y,F ! Y coordinate (row) RANDOMIZE !*************************************************************** ! Initialize squares around main grid (represented by array) to ! a value of 50. This set of cells acts as a buffer zone for the ! main maze grid. !*************************************************************** INIT: FOR COUNT = 1 TO SIZE GRID(COUNT) = 50 NEXT COUNT FOR COUNT = SIZE + 1 TO (NUM'CELLS - 2 * SIZE) + 1 STEP SIZE GRID(COUNT) = 50 GRID(COUNT + SIZE - 1) = 50 NEXT COUNT FOR COUNT = (NUM'CELLS - SIZE + 1) TO NUM'CELLS GRID(COUNT) = 50 NEXT COUNT !************************************************************** ! This is where the various cells of the grid (as represented ! by the GRID array) are filled in. Each cell will contain a ! number representing how it should be displayed on the screen. ! First we randomly choose a cell to start with. Since it is ! the first cell, there is some initialization to do before we ! can start looping. We exit the loop when the STRAY'CELLS ! routine does not find any more empty cells. !*************************************************************** START: START'NUM = (NUM'CELLS - SIZE + 1) - (SIZE + 2) CELL = INT(START'NUM * RND(0) + (SIZE + 2)) IF GRID(CELL) = 50 THEN GOTO START & ELSE GRID(CELL) = 1 CALL NEIGHBORS CALL NEXT'CELL GRID(CELL) = GRID(CELL) - 1 CELL = NEW'CELL NEXT'ELEMENT: ! start of loop CALL NEIGHBORS IF N'COUNT = 0 THEN GOTO STRAY'CELLS CALL NEXT'CELL CELL = NEW'CELL GOTO NEXT'ELEMENT !************************************************************ ! GRID array has been set up so we're ready to blast ! out the maze to the screen. First draw the initial ! maze grid, next overlay each individual cell on top ! of this, and finally draw a border around the whole thing. !************************************************************ DISPLAY'MAZE: ? TAB(-1,23); ! Turn on graphics mode CALL GRID'DRAW CALL DISPLAY CALL OUTLINE ? TAB(-1,24); ! Turn off graphics mode ? TAB(1,1); END !******************************************************* ! Randomly choose one of the neighbor cells and set ! value of current cell and this chosen neighbor cell ! so that the barrier between the cells is removed. ! Finally, make the neighbor cell the new current cell. !******************************************************* NEXT'CELL: INDEX = INT(N'COUNT * RND(0)) + 1 NEW'CELL = POS'ARRAY(INDEX) IF (NEW'CELL - CELL) = SIZE THEN & GRID(CELL) = GRID(CELL) + 4 :& GRID(NEW'CELL) = 1 IF (NEW'CELL - CELL) = -SIZE THEN & GRID(CELL) = GRID(CELL) + 1 :& GRID(NEW'CELL) = 4 IF (NEW'CELL - CELL) = 1 THEN & GRID(CELL) = GRID(CELL) + 2 :& GRID(NEW'CELL) = 8 IF (NEW'CELL - CELL) = -1 THEN & GRID(CELL) = GRID(CELL) + 8 :& GRID(NEW'CELL) = 2 RETURN !***************************************************************** ! Based on current cell location, mark four neighbor cells (no ! diagonal neighbors) with a -1, and keep track of neighbor ! locations in position array. !***************************************************************** NEIGHBORS: N'COUNT = 0 IF GRID(CELL + SIZE) <= 0 THEN & GRID(CELL + SIZE) = -1 :& N'COUNT = N'COUNT + 1 :& POS'ARRAY(N'COUNT) = CELL + SIZE IF GRID(CELL - SIZE) <= 0 THEN & GRID(CELL - SIZE) = -1 :& N'COUNT = N'COUNT + 1 :& POS'ARRAY(N'COUNT) = CELL - SIZE IF GRID(CELL + 1) <= 0 THEN & GRID(CELL + 1) = -1 :& N'COUNT = N'COUNT + 1 :& POS'ARRAY(N'COUNT) = CELL + 1 IF GRID(CELL - 1) <= 0 THEN & GRID(CELL - 1) = -1 :& N'COUNT = N'COUNT + 1 :& POS'ARRAY(N'COUNT) = CELL - 1 RETURN !*********************************************************** ! If there weren't any neighbor cells found, then scan ! through entire element list and find all the "stray" ! neighbor cells (marked with -1). If there are none, then ! we're ready to display the maze. If we do find some, then ! randomly choose one of them and make it the current cell. ! Finally, knock down any barriers between this new cell and ! its current neighbors. !*********************************************************** STRAY'CELLS: INDEX = 0 FOR COUNT = 1 TO NUM'CELLS IF GRID(COUNT) = -1 THEN & INDEX = INDEX + 1 :& POS'ARRAY(INDEX) = COUNT NEXT COUNT IF INDEX = 0 THEN GOTO DISPLAY'MAZE INDEX = INT(INDEX * RND(0)) + 1 CELL = POS'ARRAY(INDEX) GRID(CELL) = 0 IF (GRID(CELL + SIZE) <> 50) AND (GRID(CELL + SIZE) > 0) THEN & GRID(CELL + SIZE) = GRID(CELL + SIZE) + 1 :& GRID(CELL) = GRID(CELL) + 4 :& GOTO NEXT'ELEMENT IF (GRID(CELL - SIZE) <> 50) AND (GRID(CELL - SIZE) > 0) THEN & GRID(CELL - SIZE) = GRID(CELL - SIZE) + 4 :& GRID(CELL) = GRID(CELL) + 1 :& GOTO NEXT'ELEMENT IF (GRID(CELL + 1) <> 50) AND (GRID(CELL + 1) > 0) THEN & GRID(CELL + 1) = GRID(CELL + 1) + 8 :& GRID(CELL) = GRID(CELL) + 2 :& GOTO NEXT'ELEMENT IF (GRID(CELL - 1) <> 50) AND (GRID(CELL - 1) > 0) THEN & GRID(CELL - 1) = GRID(CELL - 1) + 2 :& GRID(CELL) = GRID(CELL) + 8 GOTO NEXT'ELEMENT !******************************************************** ! This routine simply scans through the GRID array and ! calls the appropriate DRAW routine to display the ! individual cell. Note that the X and Y coordinates, ! which the DRAW routines are based on, are set here. !******************************************************** DISPLAY: X = SCOL - 1 : Y = SROW + 2 FOR COUNT = 1 TO NUM'CELLS IF GRID(COUNT) = 50 THEN GOTO SKIP X = X + 4 IF X = ((SIZE-2)*4+SCOL+3) THEN Y = Y + 2 : X = SCOL + 3 ON GRID(COUNT) CALL DRAW'1,DRAW'2,DRAW'3,DRAW'4,DRAW'5, & DRAW'6,DRAW'7,DRAW'8,DRAW'9,DRAW'10, & DRAW'11,DRAW'12,DRAW'13,DRAW'14,DRAW'15 SKIP: NEXT COUNT RETURN !******************************************************************* ! These draw routines write over the initial grid design to create ! each cell. The routines assume that a cell is labeled as follows: ! ! 1 ! _____ ! | | ! 8| |2 ! |_____| ! 4 ! ! Therefore, the DRAW'2 routine simply removes the right side of the ! cell. The DRAW'9 routine removes the top and left sides of the ! cell (the sums of the side) and so on. The X and Y coordinates are ! set in the DISPLAY routine above. !******************************************************************** DRAW'1: ? TAB(Y-1,X-2);TAB(-1,43);" ";TAB(-1,44); RETURN DRAW'2: ? TAB(Y-1,X+2);TAB(-1,45); ? TAB(Y,X+2) " "; ? TAB(Y+1,X+2);TAB(-1,42); RETURN DRAW'3: ? TAB(Y-1,X-2);TAB(-1,43);" ";TAB(-1,40); ? TAB(Y,X+2) " "; ? TAB(Y+1,X+2);TAB(-1,42); RETURN DRAW'4: ? TAB(Y+1,X-2);TAB(-1,43);" ";TAB(-1,44); RETURN DRAW'5: ? TAB(Y-1,X-2);TAB(-1,43);" ";TAB(-1,44); ? TAB(Y+1,X-2);TAB(-1,43);" ";TAB(-1,44); RETURN DRAW'6: ? TAB(Y-1,X+2);TAB(-1,45); ? TAB(Y,X+2) " "; ? TAB(Y+1,X-2);TAB(-1,43);" ";TAB(-1,38); RETURN DRAW'7: ? TAB(Y-1,X-2);TAB(-1,43);" ";TAB(-1,40); ? TAB(Y,X+2) " "; ? TAB(Y+1,X-2);TAB(-1,43);" ";TAB(-1,38); RETURN DRAW'8: ? TAB(Y-1,X-2);TAB(-1,45); ? TAB(Y,X-2) " "; ? TAB(Y+1,X-2) ;TAB(-1,42); RETURN DRAW'9: ? TAB(Y-1,X-2);TAB(-1,41);" ";TAB(-1,44); ? TAB(Y,X-2) " "; ? TAB(Y+1,X-2) ;TAB(-1,42); RETURN DRAW'10: ? TAB(Y-1,X-2);TAB(-1,45);TAB(-1,46);TAB(-1,46);TAB(-1,46);TAB(-1,45); ? TAB(Y,X-2); " "; ? TAB(Y+1,X-2);TAB(-1,46);TAB(-1,46);TAB(-1,46);TAB(-1,46);TAB(-1,46); RETURN DRAW'11: ? TAB(Y-1,X-2) ;TAB(-1,41);" ";TAB(-1,40); ? TAB(Y,X-2) " "; ? TAB(Y+1,X-2);TAB(-1,42);TAB(-1,46);TAB(-1,46);TAB(-1,46);TAB(-1,42); RETURN DRAW'12: ? TAB(Y-1,X-2) ;TAB(-1,45); ? TAB(Y,X-2) " "; ? TAB(Y+1,X-2);TAB(-1,39);TAB(-1,46);TAB(-1,46);TAB(-1,46);TAB(-1,44); RETURN DRAW'13: ? TAB(Y-1,X-2);TAB(-1,41);" ";TAB(-1,44); ? TAB(Y,X-2) " "; ? TAB(Y+1,X-2);TAB(-1,39);" ";TAB(-1,44); RETURN DRAW'14: ? TAB(Y-1,X-2);TAB(-1,45);TAB(-1,46);TAB(-1,46);TAB(-1,46);TAB(-1,45); ? TAB(Y,X-2) " "; ? TAB(Y+1,X-2);TAB(-1,39);" ";TAB(-1,38); RETURN DRAW'15: ! Keep this in for consistency RETURN !******************************************************** ! Draw initial grid outlay on screen. Good example of ! a kludged subroutine - adapting screen for varying maze ! sizes and positions gets messy. !******************************************************** GRID'DRAW: ? TAB(-1,0); ? TAB(SROW+1,1) FOR Y = SROW + 1 TO SIZE - 3 + SROW ? TAB(SCOL) " "; FOR X = 1 TO SIZE - 3 ? TAB(-1,47);" "; NEXT X ? ? TAB(SCOL) " ";TAB(-1,46);TAB(-1,46);TAB(-1,46); FOR X = 1 TO SIZE - 3 ? TAB(-1,48);TAB(-1,46);TAB(-1,46);TAB(-1,46); NEXT X ? NEXT Y ? TAB(SCOL) " "; FOR X = 1 TO SIZE - 3 ? TAB(-1,47);" "; NEXT X RETURN !********************************************************** ! Draw final border around grid. ! See Kludge notes from GRID'DRAW routine. !********************************************************** OUTLINE: X = 1 : Y = SROW ? TAB(Y,X) ? TAB(SCOL) TAB(-1,38);TAB(-1,46);TAB(-1,46);TAB(-1,46); FOR X = 1 TO SIZE - 3 ? TAB(-1,42);TAB(-1,46);TAB(-1,46);TAB(-1,46); NEXT X ? TAB(-1,39) FOR Y = SROW + 2 TO (SIZE * 2 - 3) + SROW - 1 ? TAB(SCOL); TAB(-1,47); ? TAB(Y,(SIZE-2)*4+SCOL+1);TAB(-1,47) NEXT Y ? TAB(SCOL);TAB(-1,40);TAB(-1,46);TAB(-1,46);TAB(-1,46); FOR X = 1 TO SIZE - 3 ? TAB(-1,45);TAB(-1,46);TAB(-1,46);TAB(-1,46); NEXT X ? TAB(-1,41); RETURN