Sudoku Solver; personal project
29 July 2005 — 17 August 2005
  Winter Style | Home » Old » Sudoku
 
 

Sudoku is basically a crossword puzzle with numbers. The goal is to get the numbers one through nine to appear once in each row, column, and 3x3 square on the 9x9 grid. After filling out one row in the first puzzle that I worked on, I thought “Why am I doing this completely mechanical process by hand?” This is the result ;)

When I started to seriously consider writing the program, I hit upon a nifty little design idea. From the top, you can think about the main grid in one of two ways: as either a 9x9 grid of little squares, or as a 3x3 grid of 3x3 grids. And since I wanted to show the options disappearing as the grid was solved, each unknown square would need a little 3x3 grid of its own to play with.  . . . well, I think it’s pretty cool anyway :)

Having figured out how to display the grid being solved, I jiggered up all the necessary user interface rigmarole and started in on the code to actually solve the problems ;) Briefly, this is how it works (reader beware: it does get a little technical):

  • When you hit Solve, an instance of the Coordinator class is created for each row, column, and square.
  • These are passed down to each of the little squares in the grid.
  • Once all the Coordinators and squares are set up, the main grid walks though all the little squares and jabs them.
    • If the square has a known value (i.e. you entered it into the grid before you hit Solve), it sends a message out to all three of its Coordinators (you know, the row, column, and square Coordinators that the little square belongs to).
    • Each Coordinator checks its internal list and either:
      • Sets the unused value, and notifies all of the other little squares connected to it about the update, or
      • Finds a conflict (that value was already taken), in which case it notifies the caller square of an error and starts the chain reaction of Lime Green Errors
    • In the first case (the error-free one), the messages the Coordinator sends out will in turn notify other squares that the specified value has been taken.
    • Eventually, eight of the nine values in one of the unsolved little squares will be removed, and that square will become solved (blue). The square will then notify its Coordinators, as described above.
    • Etc, etc.
  • Finally, once the main grid has jabbed all the little squares (and assuming there have been no errors), the grid will do a quick check of the values:
    • If every square has been set, the problem is solved!
    • If not, one of the unsolved squares is chosen and a guess (green) is made. A new main grid is created for each value that the chosen square could be, and each of those is solved in turn.
  • Eventually, we run out of grids.

Like I said: simple ;D

The program does have a few shortcomings, however. For example, you can’t stop or pause once you hit Solve, it’s a bit of a memory hog, the method I use to hilight the “bad squares” isn’t exactly accurate*, and it only works with the 9x9 grids (there are many other variations). It’s a bit messy on the inside too, since I just stuck most-all of the logic in with the UI code (which is all you get for two weeks of effort, give or take ;). All in all, though, I’d say it works pretty well.

 

* – Remeber the cascade of Coordinator messages when one square is solved, which leads to another square being solved, which leads . . . ? Yeah, I didn’t mention it directly, but anyway: remember how the error condition is just passed back to the caller? Well that means that all of the callers get that error value, even if they’re not directly involved in the conflict. None too accurate, but really easy to write good enough in my book ;) 

 
 
Go back a page | Action Shots |  Sudoku Solver,  Source Code | Resume Entry | @ | Copyright © 2005-2011 Paul A Hansen. Some rights reserved.