10 ON ERROR MODE 0:REPORT:PRINT" at line ";ERL:END
20 VDU 22,4,26,20,28,0,7,11,0,17,0,17,255,12,23,1,0;0;0;0;
30 *FX 4,1
40 *ESC OFF
50 fW%=12:fH%=8:mineCount%=10
60 DIM field%(fW%-1,fH%-1):DIM swept%(fW%-1,fH%-1)
70 floodQSz%=fW%*fH%-1:DIM floodQ%(floodQSz%)
80 :
90 DIM sp% 7
100 FOR inv%=0 TO 1
110 invA%=inv%*&7F7F7F00:invB%=inv%*&7F7F7F7F
120 RESTORE
130 FOR n%=1 TO 17
140 READ s%:sp%!0=s%EORinvA%:READ s%:sp%!4=s%EORinvB%
150 VDU 23,127+n%+inv%*64
160 FOR i%=0 TO 7:VDU sp%?i%:NEXT i%
170 NEXT n%
180 NEXT inv%
190 :
200 gameState%=1
210 REPEAT
220 ON gameState% PROC_mainMenu,PROC_gameLoop ELSE
230 UNTIL gameState%=0
240 CLS:MODE 0
250 *ESC ON
*FX 4,0
260 PRINT"Thank-you for playing."
270 END
280 :
290 DEF FN_min(a,b) IF a<b =a ELSE =b
300 DEF FN_max(a,b) IF a>b =a ELSE =b
310 :
320
330 DEF PROC_populate
340 FOR X%=0 TO fW%-1:FOR Y%=0 TO fH%-1
350 field%(X%,Y%)=0:swept%(X%,Y%)=FALSE
360 floodQ%(X%+Y%*fW%)=X%+Y%*256
370 NEXT Y%:NEXT X%
380 FOR I%=0 TO fW%*fH%-1
390 X%=RND(fW%*fH%-1):Y%=RND(fW%*fH%-1)
400 S%=floodQ%(X%):floodQ%(X%)=floodQ%(Y%):floodQ%(Y%)=S%
410 NEXT I%
420 FOR I%=1 TO mineCount%
430 X%=floodQ%(I%)AND255:Y%=floodQ%(I%)DIV256
440 field%(X%,Y%)=-1
450 FOR xc%=FN_max(X%-1,0) TO FN_min(X%+1,fW%-1):FOR yc%=FN_max(Y%-1,0) TO FN_min(Y%+1,fH%-1)
460 IF field%(xc%,yc%)>=0 field%(xc%,yc%)=field%(xc%,yc%)+1
470 NEXT yc%:NEXT xc%
480 NEXT I%
490 ENDPROC
500 :
510 DEF FN_getCell(X%,Y%)
520 C%=128
530 IF swept%(X%,Y%)=1 C%=field%(X%,Y%)+129 IF field%(X%,Y%)=-1 C%=138
540 IF swept%(X%,Y%)=2 C%=139
550 IF swept%(X%,Y%)=3 C%=140
560 =C%
570
580 DEF PROC_drawCell(X%,Y%)PRINTTAB(X%,Y%)CHR$(FN_getCell(X%,Y%));:ENDPROC
590 :
600
610 DEF PROC_drawField
620 FOR X%=0 TO fW%-1:FOR Y%=0 TO fH%-1
630 PROC_drawCell(X%,Y%)
640 NEXT Y%:NEXT X%
650 ENDPROC
660 :
670
680 DEF FN_getKey
690 REPEAT
700 FOR I%=1 TO 0 STEP -1
710 PRINTTAB(pX%,pY%)CHR$(FN_getCell(pX%,pY%)+I%*64);
720 K%=INKEY20
730 IF K%<>-1 I%=0
740 NEXT I%
750 UNTIL K%<>-1
760 =K%
770 :
780
790 DEF FN_getGameKey
800 K%=FN_getKey
810 PROC_drawCell(pX%,pY%)
820 IF K%=139 =1
830 IF K%=138 =2
840 IF K%=136 =3
850 IF K%=137 =4
860 IF K%=13 =5
870 IF K%=27 =6
880 IF K%=127 OR K%=135 =7
890 =0
900 :
910 DEF PROC_sweep(X%,Y%)IF swept%(X%,Y%) ENDPROC ELSE swept%(X%,Y%)=1:PROC_drawCell(X%,Y%):IF field%(X%,Y%)<>-1 toDo%=toDo%-1:ENDPROC ELSE ENDPROC
920
930 DEF PROC_uncover(X%,Y%)
940 IF swept%(X%,Y%) ENDPROC
950 IF field%(X%,Y%)=-1 PROC_sweep(X%,Y%):PROC_gameOver:ENDPROC
960 IF field%(X%,Y%) PROC_sweep(X%,Y%):ENDPROC
970 PROC_qclr:PROC_enq(X%+Y%*256)
980 REPEAT:PROC_fill:UNTIL FN_qlen=0
990 ENDPROC
1000 DEF PROC_fill
1010 xy%=FN_deq
1020 X%=xy%AND255
1030 Y%=xy%DIV256
1040 IF swept%(X%,Y%) OR field%(X%,Y%)<>0 ENDPROC
1050 W%=X%+1:REPEAT:W%=W%-1:UNTIL W%=0 OR field%(FN_max(W%,0),Y%)
1060 E%=X%-1:REPEAT:E%=E%+1:UNTIL E%=fW%-1 OR field%(FN_min(E%,fW%-1),Y%)
1070 FOR X%=W% TO E%
1080 PROC_sweep(X%,Y%)
1090 IF Y%>0 PROC_fillU
1100 IF Y%<fH%-1 PROC_fillD
1110 NEXT X%
1120 ENDPROC
1130 DEF PROC_fillU IF field%(X%,Y%-1)=0 PROC_enq(X%+(Y%-1)*256):ENDPROC ELSE PROC_sweep(X%,Y%-1):ENDPROC
1140 DEF PROC_fillD IF field%(X%,Y%+1)=0 PROC_enq(X%+(Y%+1)*256):ENDPROC ELSE PROC_sweep(X%,Y%+1):ENDPROC
1150 DEF PROC_qclr:floodQR%=0:floodQW%=0:ENDPROC
1160 DEF PROC_enq(I%)floodQ%(floodQW%)=I%:floodQW%=(floodQW%+1)MODfloodQSz%:ENDPROC
1170 DEF FN_deq:LOCAL I%:I%=floodQ%(floodQR%):floodQR%=(floodQR%+1)MODfloodQSz%:=I%
1180 DEF FN_qlen =floodQW%-floodQR%
1190 :
1200 DEF PROC_flag(X%,Y%)
1210 IF swept%(X%,Y%)=0 AND flags%>0 swept%(X%,Y%)=2:PROC_drawCell(X%,Y%):flags%=flags%-1:ENDPROC
1220 IF swept%(X%,Y%)=0 swept%(X%,Y%)=3:PROC_drawCell(X%,Y%):ENDPROC
1230 IF swept%(X%,Y%)=2 swept%(X%,Y%)=3:PROC_drawCell(X%,Y%):flags%=flags%+1:ENDPROC
1240 IF swept%(X%,Y%)=3 swept%(X%,Y%)=0:PROC_drawCell(X%,Y%)
1250 ENDPROC
1260 :
1270 DEF PROC_gameOver
1280 FOR x%=0 TO fW%-1:FOR y%=0 TO fH%-1
1290 IF field%(x%,y%)=-1 PROC_sweep(x%,y%)
1300 NEXT y%:NEXT x%
1310 gameOver%=TRUE:gameState%=1:IFGET
1320 ENDPROC
1330 DEF PROC_gameWon
1340 FOR x%=0 TO fW%-1:FOR y%=0 TO fH%-1
1350 IF field%(x%,y%)=-1 swept%(x%,y%)=2:PROC_drawCell(x%,y%)
1360 NEXT y%:NEXT x%
1370 gameOver%=TRUE:gameState%=1:IFGET
1380 ENDPROC
1390 :
1400
1410 DEF PROC_newGame
1420 CLS:PRINTTAB(2,3)"Busy...";CHR$144;
1430 gameState%=2
1440 pX%=0:pY%=0:gameOver%=FALSE
1450 PROC_populate
1460 CLS:PROC_drawField
1470 toDo%=fW%*fH%-mineCount%:flags%=mineCount%
1480 ENDPROC
1490 :
1500
1510 DEF PROC_gameLoop REPEAT:PROC_gameLogic:UNTIL gameOver%:ENDPROC
1520 DEF PROC_gameLogic
1530 REPEAT:k%=FN_getGameKey:UNTIL k%
1540 IF k%=1 pY%=(pY%-1+fH%) MOD fH%
1550 IF k%=2 pY%=(pY%+1) MOD fH%
1560 IF k%=3 pX%=(pX%-1+fW%) MOD fW%
1570 IF k%=4 pX%=(pX%+1) MOD fW%
1580 IF k%=5 PROC_uncover(pX%,pY%):IF toDo%<1 PROC_gameWon:ENDPROC
1590 IF k%=6 PROC_gameOver:ENDPROC
1600 IF k%=7 PROC_flag(pX%,pY%)
1610 ENDPROC
1620 :
1630 DEF PROC_mainMenu
1640 VDU 12,17,127,17,128
1650 PRINT"MINE";CHR$143;"SWEEPER";
1660 PRINTTAB(0,7)"by Ben Ryves";
1670 VDU 17,0,17,255
1680 PRINTTAB(2,2)"Mines:";
1690 PROC_drawMineCount
1700 LOCAL k%
1710 REPEAT
1720 REPEAT:k%=INKEY(0):UNTIL k%<>-1
1730 IF k%=13 PROC_newGame
1740 IF k%=136 mineCount%=FN_max(1,mineCount%-1):PROC_drawMineCount
1750 IF k%=137 mineCount%=FN_min(24,mineCount%+1):PROC_drawMineCount
1760 IF k%=27 gameState%=0
1770 UNTIL gameState%<>1
1780 ENDPROC
1790 DEF PROC_drawMineCount
1800 @%=&00020002
1810 LOCAL i%
1820 PRINTTAB(8,2)mineCount%TAB(0,4)"";
1830 FOR i%=0 TO mineCount%-1:PRINTCHR$141;:NEXT i%
1840 IF mineCount%>23 ENDPROC
1850 FOR i%=mineCount% TO 23:PRINTCHR$142;:NEXT i%
1860 ENDPROC
1870 :
1880
1890 DATA&80AA807F,&80AA80AA,&8080807F,&80808080,&9888807F,&809C8888,&8498807F,&809C9088,&8498807F,&80988488,&9490807F,&8084849C,&909C807F,&80988498,&908C807F,&809C949C,&849C807F,&80909088,&949C807F,&809C949C
1900 DATA&E3D5FF7F,&FFD5E3C9,&C7C7FF7F,&FFC1F7F7,&FBE7FF7F,&FFF7FFF7,&DE4C7C92,&00927C7C,&44281000,&00001028,&08787878,&007F1C08,&9A924438,&00384482