# The mechanics of Sudoku

The rules of Sudoku are so simple (see Sudoku puzzles screen capture) that it seems easy to write the mechanics of the puzzle in Fox. It took 20 minutes to write this. Move the mouse over a desired square and type a digit key. ‘0’ means erase what’s there. It doesn’t know any of the rules, but is a tool that can help you solve a puzzle.

It includes a rudimentary input/storage/output mechanism of saving Sudoku puzzles as a text string of 81 digits. A blank space is represented by 0 (how convenient!)

The 2 Sudoku puzzles included (myvar and myvar2) are the same: one is more solved than the other.

You can write a subclass of this code and add some methods to actually give hints or even generate Sudoku puzzles

If you improve upon this please let me know.

CLEAR ALL

CLEAR

PUBLIC ox

#define CELLHEIGHT 60

#define CELLWIDTH 60

#define NCELLSX 9

#define NCELLSY 9

#define XOFFSET 50

#define YOFFSET 50

#define CELLOFFX CELLWIDTH/3

#define CELLOFFY CELLHEIGHT/3

#define BOLDLINE 0xff0000

#define NORMLINE 0xffff

ox=CREATEOBJECT("Sudoku")

ox.show

DEFINE CLASS Sudoku AS FORM

left=200

backcolor=0xffffff

fontname="Courier New"

allowoutput=.f.

DIMENSION aSq[NCELLSX, NCELLSY]

PROCEDURE Init

this.DrawGrid

TEXT TO myvar

704002603

602730590

305006070

456900030

238641957

179325468

063200005

027060309

041803726

ENDTEXT

TEXT TO myvar2

004002600

002030090

300000070

400900030

000641000

070005008

060000005

020060030

001800700

ENDTEXT

this.aSq=0

IF ALINES(aal,myvar)=NCELLSX

FOR j = 1 TO ALEN(aal,1)

FOR i = 1 TO LEN(aal[j])

this.aSq[i,j]=VAL(SUBSTR(aal[j],i,1))

ENDFOR

ENDFOR

ENDIF

this.ShowNums

PROCEDURE ShowNums

thisform.ForeColor=0

thisform.FontSize=20

FOR i = 1 TO NCELLSX

FOR j = 1 TO NCELLSY

this.shownum(i-1,j-1,this.aSQ[i,j])

ENDFOR

ENDFOR

PROCEDURE ShowNum(i,j,num)

thisform.Print(IIF(num=0," ",TRANSFORM(num)),CELLOFFX+XOFFSET +i * CELLWIDTH , CELLOFFY+YOFFSET + j * CELLHEIGHT)

PROCEDURE keypress(p1,p2)

DO CASE

CASE p1=27

thisform.Release

CASE p1=ASC("C") OR p1=ASC("c")

OTHERWISE

IF p1 >= 48 AND p1 < 58

AMOUSEOBJ(aa,1)

i=1+INT((aa[3]-XOFFSET)/CELLWIDTH)

j=1+INT((aa[4]-YOFFSET)/CELLHEIGHT)

IF i>0 AND i <= NCELLSX AND J>0 AND j<=NCELLSY

thisform.asq[i,j]=p1-48

thisform.ForeColor=0xff0000

thisform.ShowNum(i-1,j-1,p1-48)

ELSE

?"Illegal"

ENDIF

ELSE

?p1,p2

ENDIF

ENDCASE

PROCEDURE DrawGrid

WITH this as Form

.Width = CELLWIDTH * NCELLSX+XOFFSET*2

.Height = CELLHEIGHT * NCELLSY+YOFFSET*2

FOR i = 0 TO NCELLSY && draw horiz

IF MOD(i,3)=0

.ForeColor=BOLDLINE

FOR j = -1 TO 1

.Line(XOFFSET,YOFFSET+ CELLWIDTH*i+j, XOFFSET+CELLWIDTH * NCELLSX, YOFFSET+ CELLWIDTH*i+j)

ENDFOR

ELSE

.ForeColor=NORMLINE

.Line(XOFFSET,YOFFSET+ CELLWIDTH*i, XOFFSET+CELLWIDTH * NCELLSX, YOFFSET+ CELLWIDTH*i)

ENDIF

ENDFOR

FOR i = 0 TO NCELLSX && draw VERT

IF MOD(i,3)=0

.ForeColor=BOLDLINE

FOR j = -1 TO 1

.Line(j+XOFFSET+ CELLHEIGHT*i,YOFFSET, j+XOFFSET+ CELLHEIGHT*i,YOFFSET+ CELLHEiGHT * NCELLSY)

ENDFOR

ELSE

.ForeColor=NORMLINE

.Line(XOFFSET+ CELLHEIGHT*i,YOFFSET, XOFFSET+ CELLHEIGHT*i,YOFFSET+ CELLHEiGHT * NCELLSY)

ENDIF

ENDFOR

ENDWITH

ENDDEFINE