1 REM SUDOKU SOLVER V 1.0 BY GRAHAM DEARSLEY 5 REM SETUP DISPLAY AND HIDE SYSTEM CURSOR 10 GRAPHICS 0:SETCOLOR 2,0,0:POKE 752,1 20 GOSUB 5000 30 GOSUB 6000 40 CX=30:CY=6:REM CURSOR POSITION 50 COX=30:COY=6:REM OLD CURSOR POSITION 60 CCOLD=49:REM OLD CURSOR CONTENT 70 BLATCH=1:REM BUTTON LATCH 80 DIM SUDOKU(9,9):REM DIMENSION MATRIX ARRAY 90 DIM TEMP$(9):TEMP$="" 100 GOSUB 8000 495 REM MAIN LOOP 500 J=STICK(0):T=STRIG(0) 510 IF J=7 THEN GOSUB 7000:REM RIGHT 520 IF J=11 THEN GOSUB 7100:REM LEFT 530 IF J=14 THEN GOSUB 7200:REM UP 540 IF J=13 THEN GOSUB 7300:REM DOWN 550 IF T=0 THEN GOSUB 7400:REM TRIGER BUTTON 560 POKE 77,0:REM RESET SCREEN SAVER TIMER 570 GOTO 500 4990 END 4995 REM PLOT THE GRID 5000 POSITION 2,0 5010 PRINT "   " 5020 FOR I=1 TO 2 5030 PRINT " | | |   | |   | | |" 5040 PRINT "   " 5050 PRINT " | | |   | |   | | |" 5060 PRINT "   " 5070 PRINT " | | |   | |   | | |" 5080 PRINT "                    " 5090 NEXT I 5100 PRINT " | | |   | |   | | |" 5110 PRINT "   " 5120 PRINT " | | |   | |   | | |" 5130 PRINT "   " 5140 PRINT " | | |   | |   | | |" 5150 PRINT "   " 5160 RETURN 5995 REM PLOT THE NUM PAD 6000 POSITION 30,6:PRINT "1 2 3" 6010 POSITION 30,8:PRINT "4 5 6" 6020 POSITION 30,10:PRINT "7 8 9" 6030 POSITION 30,12:PRINT "SOLVE" 6040 RETURN 6995 REM CONDITION BLOCK 7000 CX=CX+2 7010 IF CX>34 THEN CX=CX-2:RETURN 7015 IF CX>22 AND CY=12 THEN CX=CX-2:RETURN 7020 IF CX=22 THEN POSITION COX,COY:PRINT CHR$(CCOLD):CX=30:CY=6:COX=30:COY=6:CCOLD=49 7070 IF CX<22 THEN BLATCH=1:GOSUB 9000 7080 IF CX>22 THEN GOSUB 8000 7090 RETURN 7100 CX=CX-2 7110 IF CX<3 THEN CX=CX+2:RETURN 7115 IF CX>22 AND CY=12 THEN CX=CX+2:RETURN 7120 IF CX=28 THEN CX=CX+2:RETURN 7170 IF CX<22 THEN BLATCH=1:GOSUB 9000 7180 IF CX>22 THEN GOSUB 8000 7190 RETURN 7200 CY=CY-2 7210 IF CY<0 THEN CY=CY+2:RETURN 7215 IF CX>20 AND CY=10 THEN POSITION 30,12:PRINT "SOLVE" 7220 IF CX>20 AND CY<6 THEN CY=CY+2:RETURN 7270 IF CX<22 THEN BLATCH=1:GOSUB 9000 7280 IF CX>22 THEN GOSUB 8000 7290 RETURN 7300 CY=CY+2 7310 IF CY>18 THEN CY=CY-2:RETURN 7320 IF CX>20 AND CY>12 THEN CY=CY-2:RETURN 7370 IF CX<22 THEN BLATCH=1:GOSUB 9000 7380 IF CX>22 THEN GOSUB 8000 7385 IF CX>20 AND CY=12 THEN POSITION 30,12:PRINT "ΣΟΜΦΕ" 7390 RETURN 7400 IF CX<22 AND BLATCH=1 THEN CCOLD=CCONTENT:GOSUB 9000 7410 IF CX<22 AND BLATCH=-1 THEN CCOLD=32:GOSUB 9000 7415 IF CX>20 AND CY<12 THEN BLATCH=-1 7420 IF CX>20 AND CY<12 THEN POSITION COX,COY:PRINT CHR$(CCOLD):LOCATE 4,1,CCOLD:CX=4:CY=1:COX=4:COY=1:GOSUB 9000 7430 IF CX<22 THEN BLATCH=-BLATCH 7440 IF CX>20 AND CY=12 THEN GOSUB 10000 7490 RETURN 7995 REM PLOT NUM PAD CURSOR 8000 LOCATE CX,CY,CCONTENT 8010 POSITION COX,COY:PRINT CHR$(CCOLD) 8020 CCOLD=CCONTENT 8030 POSITION CX,CY:PRINT CHR$(CCONTENT+128) 8040 COX=CX:COY=CY 8050 SOUND 0,255,10,10 8060 FOR DELAY=1 TO 20:NEXT DELAY 8070 SOUND 0,0,0,0 8080 RETURN 8995 REM PLOT GRID CURSOR 9000 POSITION COX,COY:PRINT CHR$(CCOLD) 9010 LOCATE CX,CY,CCOLD 9020 POSITION CX,CY:PRINT CHR$(CCONTENT+128) 9030 COX=CX:COY=CY 9040 SOUND 0,255,10,10 9050 FOR DELAY=1 TO 20:NEXT DELAY 9060 SOUND 0,0,0,0 9070 RETURN 9995 REM FILL SUDOKU MATRIX 10000 POSITION 29,1:PRINT "WORKING" 10005 POSITION 5,21:PRINT " " 10010 FOR COL=0 TO 8 10020 FOR ROW=0 TO 8 10025 POSITION 1,21:PRINT COL:POSITION 1,22:PRINT ROW 10030 LOCATE (COL*2)+4,(ROW*2)+1,VALUE:POSITION (COL*2)+4,(ROW*2)+1:PRINT CHR$(VALUE) 10040 SUDOKU(COL,ROW)=VALUE-48 10050 NEXT ROW 10060 NEXT COL 10070 POSITION 28,1:PRINT " " 10195 REM THE LOGIC ! ! ! 10196 PASS=1 10197 FILLED=0 10198 POSITION 23,3:PRINT "PASS ";PASS 10200 FOR ROW=0 TO 8:REM PROCESS THE ROWS 10210 POSCOL=0:POSROW=0:POSNUM=0 10220 GOSUB 10500:REM PUT UNFILLED NUMBERS FOR ROW IN TEMP$ 10230 FOR CHECK=1 TO LEN(TEMP$) 10232 COUNT=0 10235 FOR COL=0 TO 8 10237 IF COUNT>1 THEN GOTO 10250 10240 GOSUB 10710:REM CHECK NUMBER IS UNIQUE IN COLUNM 10243 POSITION 20,20:PRINT "TRUE ";TRUE:POSITION 27,20:PRINT "COUNT ";COUNT 10245 POSITION 20,21:PRINT "POSROW ";POSROW:POSITION 29,21:PRINT "POSCOL ";POSCOL 10247 POSITION 20,22:PRINT "POSNUM ";POSNUM 10250 NEXT COL 10350 IF COUNT=1 THEN SUDOKU(POSCOL,POSROW)=POSNUM:FILLED=FILLED+1 10355 IF COUNT=1 THEN POSITION (POSCOL*2)+4,(POSROW*2)+1:PRINT POSNUM 10360 NEXT CHECK 10390 TEMP$="" 10400 NEXT ROW 10401 GOSUB 11200 10402 IF FILLED>0 THEN PASS=PASS+1:GOTO 10197 10405 POSITION 23,1:PRINT " " 10410 RETURN :REM RETURN TO MAIN PROGRAM 10495 REM FILL TEMP$ 10500 POSITION 23,1:PRINT "PROCESSING ROW ";ROW+1 10510 FOR NUMBER=1 TO 9 10520 MARK=1 10530 FOR COL=0 TO 8 10550 IF SUDOKU(COL,ROW)=NUMBER THEN MARK=0 10560 NEXT COL 10570 IF MARK=1 THEN TEMP$(LEN(TEMP$)+1)=STR$(NUMBER) 10580 NEXT NUMBER 10590 POSITION 5,21:PRINT " " 10600 POSITION 5,21:PRINT TEMP$ 10610 RETURN :REM RETURN TO 10220 10710 REM 10720 IF SUDOKU(COL,ROW)<>-16 THEN RETURN 10725 TRUE=1 10730 FOR ROWTAG=0 TO 8 10740 IF SUDOKU(COL,ROWTAG)=VAL(TEMP$(CHECK,CHECK)) THEN TRUE=0 10750 NEXT ROWTAG 10752 IF TRUE=1 THEN GOSUB 12000 10755 IF TRUE=1 AND COUNT>0 THEN COUNT=COUNT+1 10760 IF TRUE=1 AND COUNT=0 THEN POSCOL=COL:POSROW=ROW:POSNUM=VAL(TEMP$(CHECK,CHECK)):COUNT=COUNT+1 10780 RETURN 11200 FOR COL=0 TO 8:REM PROCESS THE COLUNMS 11210 POSCOL=0:POSROW=0:POSNUM=0 11220 GOSUB 11500:REM PUT UNFILLED NUMBERS FOR COLUNM IN TEMP$ 11230 FOR CHECK=1 TO LEN(TEMP$) 11232 COUNT=0 11235 FOR ROW=0 TO 8 11237 IF COUNT>1 THEN GOTO 11250 11240 GOSUB 11710:REM CHECK NUMBER IS UNIQUE IN ROW 11243 POSITION 20,20:PRINT "TRUE ";TRUE:POSITION 27,20:PRINT "COUNT ";COUNT 11245 POSITION 20,21:PRINT "POSROW ";POSROW:POSITION 29,21:PRINT "POSCOL ";POSCOL 11247 POSITION 20,22:PRINT "POSNUM ";POSNUM 11250 NEXT ROW 11350 IF COUNT=1 THEN SUDOKU(POSCOL,POSROW)=POSNUM:FILLED=FILLED+1 11355 IF COUNT=1 THEN POSITION (POSCOL*2)+4,(POSROW*2)+1:PRINT POSNUM 11360 NEXT CHECK 11390 TEMP$="" 11400 NEXT COL 11402 RETURN 11405 POSITION 23,1:PRINT " " 11410 RETURN :REM RETURN TO MAIN PROGRAM 11495 REM FILL TEMP$ 11500 POSITION 23,1:PRINT "PROCESSING COL ";COL+1 11510 FOR NUMBER=1 TO 9 11520 MARK=1 11530 FOR ROW=0 TO 8 11550 IF SUDOKU(COL,ROW)=NUMBER THEN MARK=0 11560 NEXT ROW 11570 IF MARK=1 THEN TEMP$(LEN(TEMP$)+1)=STR$(NUMBER) 11580 NEXT NUMBER 11590 POSITION 5,21:PRINT " " 11600 POSITION 5,21:PRINT TEMP$ 11610 RETURN :REM RETURN TO 11220 11710 REM 11720 IF SUDOKU(COL,ROW)<>-16 THEN RETURN 11725 TRUE=1 11730 FOR COLTAG=0 TO 8 11740 IF SUDOKU(COLTAG,ROW)=VAL(TEMP$(CHECK,CHECK)) THEN TRUE=0 11750 NEXT COLTAG 11752 IF TRUE=1 THEN GOSUB 12000 11755 IF TRUE=1 AND COUNT>0 THEN COUNT=COUNT+1 11760 IF TRUE=1 AND COUNT=0 THEN POSCOL=COL:POSROW=ROW:POSNUM=VAL(TEMP$(CHECK,CHECK)):COUNT=COUNT+1 11780 RETURN 12000 IF COL<3 THEN SQCOL=0 12002 IF COL>2 AND COL<6 THEN SQCOL=3 12004 IF COL>5 THEN SQCOL=6 12010 IF ROW<3 THEN SQROW=0 12012 IF ROW>2 AND ROW<6 THEN SQROW=3 12014 IF ROW>5 THEN SQROW=6 12020 FOR SQUARECOL=SQCOL TO SQCOL+2 12030 FOR SQUAREROW=SQROW TO SQROW+2 12040 IF SUDOKU(SQUARECOL,SQUAREROW)=VAL(TEMP$(CHECK,CHECK)) THEN TRUE=0 12050 NEXT SQUAREROW 12060 NEXT SQUARECOL 12070 RETURN