Whence the stupid name?
Well, the working name, perhaps rather unimaginatively, was YASudoku or Yet Another Sudoku, but when I got to the stage of thinking others might want to use the program and that it therefore needed a name, I found that YASudoku was already in use. While checking on other possible names I discovered that a quite an industry has grown around Sudoku and that any recognisable variant on sudoku had probably already been snapped up. Dreaming up names can be amusing if you don't have to worry about others having the same droll ideas, but if you do, it soon palls. So I ran out of patience.
The logic runs as follows. The name SourGumdrop is not recognisably related to Sudoku and hence has a chance of being unique. It also happens that AKA SourGumdrop is an anagram of "A Sudoku Program" and I was amused by the "AKA" component; especially when I didn't include it in the name. Oh, so witty.
So if you think "SourGumdrop" is not only stupid but too long, be aware that the full title is:
"A Sudoku Program, Also Known As SourGumdrop" and that "SourGumdrop" is the short version.
Acknowledgements
I used the following sites to learn about Sudoku techniques and terminology.
With help from Google, my start point was Wikipedia and then: Open Directory Project, sudoku.com, puzzle.jp, Simple Sudoku, SadMan Sudoku, Sudoku Solver, A Su Doku solver and Sudoku programmers forum.
My first real interest in Sudoku was to try to calculate the number of possible grids. While I was muddling along the problem was solved and it was shown that there are 6,670,903,752,021,072,936,960.
It would have been difficult to make any progress without the online Python help at Python.org and impossible (as I found it more difficult to grasp) without John Shipman, Stephen Ferg and Fredrik Lundh's. Tkinter documentation and example code. Thanks.
The program was developed on a Linux box running Mandrake10.1 but using the latest version of Python and checked on various machines running XP. Linux screendumps were obtained using KSnapshot. Samba made file transfers between Linux and MS painless. The web pages were written by hand using Emacs with documentation from The World Wide Web Consortium and checked using Tidy conveniently plugged into Firefox. Early versions of the website were improved with advice from the members of Webforumz
I thank KLS for many very helpful suggestions, cheeky comments and the website banner artwork.
Source code
This section is for those who are considering modifying the source code. The program is written in Python and distributed under the GNU General Public License. This means that you can redistribute it and/or modify it under the terms of the GPL.
Python code is very easy to understand and modify. Because it is interpreted you can see the results of your changes immediately. Even people who have never programmed before can easily modify the code.
Although I have programmed in other languages, this is my first attempt at Python! I've released the source in the hope that it will be of use.
If you make changes I'd be very interested to hear about them. I'm also interested in any errors in the code and any misunderstandings about Python or Tkinter that they reveal.
Some notes about the source code and its classes
SGP
The puzzle answers written using the symbols 1-9 and using positive values for givens and negatives for the others. Also contains the algorithm usage when the puzzle was solved using the Simplest First strategy.
SGG
Global variables.
SGHint
Handles the hint mechanism: the candidates that form a pattern - say X-wing - are "causes" and candidates that can be removed because of the pattern are "effects". Both cause and effect are stored as lists of cell_index, candidate_index pairs.
SGHistory
The history mechanism - an object stack used for recording the states of the grid while it is being worked on and for the backtracking mechanism used by the solver that uses guessing to solve puzzles that cannot be solved with the built-in algorithms. Phew!
SGCell
The data for a cell. We store the solution, the current guess, the state of each candidate (ie deleted or still available), and for convenience, the cell, row, column and box indexes (numbering from 0).
SGSudoku
An object containing a list of 81 SGCell's. This class contains all the algorithms that operate on the sudoku data.
SGWG
Here we keep our copies of all the widget variables: lists of objects that control every item in the gui - eg there are 810 (81x10) candidate buttons and we use my_little_buttons[little_button_index] to access the widget for button little_button_index.
SGHandleStatus
This class manages the status of objects. Consider a candidate button shown on the grid. It may be normal or disabled, coloured by the user, coloured as a hint cause, coloured as a hint effect, need to be redrawn, etc. Usually it can have several of these attributes at once. Writing in C I might code these states as bit patterns. For Python I assigned each possible state a different prime number, and for any object with state variable STATE, to add a state I multiply STATE by the appropriate prime number, to delete it I divide STATE.
SGWidget
This class contains the main event loop and many of the functions that handle the user interface. There is complete separation between the Sudoku variables (in SGSudoku) and the variables shown by the gui. After operations - say the application of a hint - the function sync_sg_and_sgw(self, new_sg, old_sg) is used to compare the current state of the Sudoku data (new_sg) with the previous state (old_sg). All differences found alter the status of the corresponding widget variables and each changed object is also given a "redraw" status. After sync_sg_and_sgw, refresh_widgets redraws all altered widgets accordingly and deletes their redraw status. Obviously, as widgets can have multiple states simultaneously the drawing routines need to order their operations so that the most important states are displayed - eg if a button has been coloured by the user but is also coloured by the hint mechanism, the hint colouring is shown. Once the hint has been acted upon the user colouring can be shown again.
Small classes: SGSCell, SGWidgetData, SelectPuzzle, ShowDifficulty, ConfigureSG, SGIO, EnterPuzzle.
The class and functions names are listed on the next page.
List Comprehension
One interesting idea I came across for the first time in rewriting the program is that of List comprehension and I have used it where efficiency was required in the new version.