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