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 REM Populate the minefield.
  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 REM Draw a cell.
  580 DEF PROC_drawCell(X%,Y%)PRINTTAB(X%,Y%)CHR$(FN_getCell(X%,Y%));:ENDPROC
  590 :
  600 REM Draw the entire field.
  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 REM Get a key, flashing the cursor.
  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 REM Get a game action key.
  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 REM Uncover a point on the grid.
  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 REM Start a new game.
 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 REM Main game logic loop.
 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 REM Sprite data.
 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