
0REM  This program is a cleaned up version of the MAZE program printed in this month's Family Computing
1REM  I have also made it compatible with SmartBEST.
3POKE 17059, 7:POKE 17115, 23
5POKE 17126, 26:POKE 16953, 32:TEXT
6INVERSE:HOME:VTAB 8:HTAB 11:? "********":HTAB (11):? "*      *"
7HTAB (11):? "* MAZE *":HTAB (11):? "*      *"
8HTAB (11):? "********":VTAB 24:NORMAL:? TAB(4); "--> touch any key <--"; 
9GOSUB 19950
10DIM cd(4, 2), rd(4, 3), rp(3), xr(2), yr(2):NORMAL
20 ms=2: sp$=CHR$(32):FOR i=1 TO 4
30FOR j=1 TO 3:READ rd(i, j):NEXT j, i
40FOR i=1 TO 4:FOR j=1 TO 2:READ cd(i, j):NEXT j, i
50 xr(1)=59: xr(2)=31: yr(1)=59: yr(2)=23
60HOME:? TAB(39); "*MAZE CREATOR*":?
70VTAB 6:? " You may generate your MAZE on  the screen or your printer."
80?:? " Touch: <P> for printer                                               <S> for screen"
100GOSUB 3000: ms=(k=80)+2*(k=83)
110ON (ms=0) GOTO 100:HOME
120VTAB 8:? " This program is now set to":? " generate a maze of "; xr(ms); " X "; yr(ms)
130? " (width x height)."
140?:? " Wish to change the size?                                               <Y>/<N>"
160GOSUB 3000:IF k<>78 AND k<>89 THEN ? CHR$(7):GOTO 160
170IF k=78 THEN  mx=xr(ms): my=yr(ms):GOTO 200
180 tt$="width": a=xr(ms):GOSUB 2000: mx=k
190 tt$="height": a=yr(ms):GOSUB 2000: my=k
200 qx=mx-1: qy=my-1: max=qx*qy/4
210HOME:DIM mp%(mx, my), pt%(max, 1)
220VTAB 12:FLASH:? " I'm generating your maze NOW! ":NORMAL
230FOR x=1 TO mx:FOR y=1 TO my
240 mp%(x, y)=-1:NEXT y, x
250 g=0: lc=max: cx=2: cy=2: c=1
260 pt%(1, 0)=2: pt%(1, 1)=2: mp%(2, 2)=2
270GOSUB 1000:IF v<>0 THEN 320
280 s=mp%(cx, cy): mp%(cx-cd(s, 1)/2, cy-cd(s, 2)/2)=-1
290 mp%(cx, cy)=0: c=c-1
300 pt%(lc, 0)=cx: pt%(lc, 1)=cy: lc=lc-1
310 cx=pt%(c, 0): cy=pt%(c, 1):? "-"; :GOTO 270
320 s=rp(RND(1)*v+1)
330 tx=cx+cd(s, 1): ty=cy+cd(s, 2)
340IF (s=1 AND (tx=2 OR tx=qx)) OR (s=4 AND (ty=2 OR ty=qy)) THEN 320
350 mp%(cx+cd(s, 1)/2, cy+cd(s, 2)/2)=5
360 c=c+1: cx=tx: cy=ty: mp%(cx, cy)=s
370 pt%(c, 0)=cx: pt%(c, 1)=cy:? "+"; 
380IF cx<>qx OR cy<>qy THEN 270
390?: mp%(qx, qy)=5:IF c=max THEN 520
400 g=1: w=4: l=1
410? "#"; : cx=pt%(l, 0): cy=pt%(l, 1)
420IF mp%(cx, cy)=5 THEN 490
430GOSUB 1000:IF v=0 THEN  mp%(cx, cy)=5:GOTO 490
440 s=rp(RND(1)*v+1): c=c+1
450 mp%(cx+cd(s, 1)/2, cy+cd(s, 2)/2)=5
460 cx=cx+cd(s, 1): cy=cy+cd(s, 2)
470 mp%(cx, cy)=s: pt%(c, 0)=cx: pt%(c, 1)=cy
480? "@"; :GOTO 430
490 l=l+w:IF l<c THEN 410
500IF c=max THEN 520
510?: l=1: w=w-(w=4)*3:GOTO 410
520HOME:IF ms=1 THEN GOSUB 4000:GOTO 870
530VTAB 8:? " Select level of play:"
535?:?:? TAB(12); "<1>  Easy"
540?:? TAB(12); "<2>  Harder"
545?:? TAB(12); "<3>  Hardest"
550GOSUB 3000: ls=k-48:IF ls<1 OR ls>3 THEN ? CHR$(7):GOTO 550
560HOME:VTAB 11:? " Do you want a printed copy of  this maze before you start?"
570?:? TAB(12); "<Y>/<N>"
580GOSUB 3000:IF k<>78 AND k<>89 THEN GOTO 580
590IF k=89 THEN HOME:GOSUB 4000
600HOME: lm=INT(15.5-mx/2): cx=2: cy=2: sc=0
610INVERSE:FOR y=1 TO my:VTAB y:HTAB lm+1:? sp$; 
620HTAB lm+mx:? sp$; :NEXT y
630FOR x=lm+2 TO lm+qx:VTAB 1:HTAB x:? sp$
640VTAB my:HTAB x:? sp$; :NEXT x:NORMAL
650VTAB 2:HTAB lm+1:? "S"; 
660VTAB qy:HTAB lm+mx:? "E"; :IF ls<>1 THEN 700
670INVERSE:FOR y=2 TO qy:FOR x=2 TO qx
680IF mp%(x, y)=-1 THEN VTAB y:HTAB lm+x:? sp$; 
690NEXT x:NEXT y:NORMAL
700VTAB cy:HTAB lm+cx:? "*"; CHR$(8); 
710GOSUB 3000
720 dx=(k=161)-(k=163): dy=(k=162)-(k=160)
730IF dx=0 AND dy=0 THEN 710
740 tx=cx+dx: ty=cy+dy
750IF mp%(tx, ty)<>-1 THEN 810
760? CHR$(7); :IF ls=1 THEN 710
770 sc=sc+1:VTAB 24:HTAB 11-INT(LEN(STR$(sc))/2)
780? "Blunders = "; sc; :IF ls=3 THEN 710
790IF tx=1 AND ty=2 THEN 710
800INVERSE:VTAB ty:HTAB lm+tx:? sp$; :NORMAL:GOTO 700
810VTAB cy:HTAB lm+cx:? sp$; 
820 cx=tx: cy=ty:IF cx<>qx OR cy<>qy THEN 700
830VTAB cy:HTAB lm+cx:? "*"; 
840FOR l=1 TO 10:? CHR$(7); :NEXT l
850VTAB 24:HTAB 31:FOR l=1 TO 24
860FOR d=1 TO 150:NEXT d:?:NEXT l
870HOME:VTAB 12:? "    ANOTHER MAZE? <Y>/<N>"
880GOSUB 3000:IF k<>78 AND k<>89 THEN 880
890IF k=89 THEN RUN
900POKE 16953, 123:END
1000 v=0:FOR z=1 TO 3: tt=rd(mp%(cx, cy), z)
1010 x=cx+cd(tt, 1): y=cy+cd(tt, 2)
1020IF x<2 OR x>qx OR y<2 OR y>qy THEN 1040
1030IF mp%(x, y)<g THEN  v=v+1: rp(v)=tt
1040NEXT z:RETURN
2000HOME:?:? " The "; tt$; " must be an odd"
2010? " number between 9 and "; a; "."
2020?:? " What "; tt$; " do you choose? "; :INPUT k:? CHR$(7)
2040IF k<9 OR k>a OR k/2=INT(k/2) THEN 2000
2050RETURN
3000GET k$: k=ASC(k$):IF k=3 THEN END
3010 k=k-32*(k>96)*(k<123):RETURN
4000? TAB(4); "Press <return> when your"
4010? TAB(8); "printer is ready."
4020GOSUB 3000:IF k<>13 THEN 4020
4030HGR2:?
4040? CHR$(4); "PR# 1":?
4050FOR y=1 TO my:FOR x=1 TO mx
4060IF y=2 AND x=1 THEN ? "S"; :GOTO 4090
4070IF y=qy AND x=mx THEN ? "E"; :GOTO 4090
4080? CHR$(32+3*(mp%(x, y)=-1)); 
4090NEXT x:?:NEXT y:?
4100? CHR$(4); "PR# 0"
4110TEXT:?:RETURN
5000DATA        1,2,4,1,2,3,2,3,4,1,3,4
5010DATA         0,-2,2,0,0,2,-2,0
19950REM                             RANDOMIZE  
19951REM                          
19956POKE 16149, 255:POKE 16150, 255:POKE 64885, 0
19957 z=RND(1)
19958IF PEEK(64885)=0 THEN 19957
19959? CHR$(7)
19960RETURN
