With the first episode focusing on the player, and barely making the self-imposed time limit, I was really worried when I started working on this episode. The player was fairly straight-forward with the implementation, I started this project out with no idea whatsoever how I was going to actually implement this. To figure out how to write a generator, I figured the best way to start would be to simply create a puzzle by hand. By doing this, I would get a hand on what is required. While often techniques in the real world are hard to translate into software, it often can result in at least a good plan for attacking the problems. In fact, I found that sudoku puzzle creation, or at least the method I ended up using to create the puzzle, was the opposite case. It would be much easier for the computer to use my technique then it was for me to.
While generating the puzzle, I quickly realized that the process consisted of two different tasks. First is the creation of the solution, which will be the tricky part. Second is uncovering parts of the puzzle in such a way to make the puzzle solvable yet have very few (ideally one) potential solutions. The second task to me seemed to be the easiest to implement so I decided to implement my generator in reverse, starting by implementing the hider followed by generating unique solutions.
Both tasks require that I have some type of model. The sudoku model should already exist as it should have been part of the player. To save time, however, I combined the model with the controller. This is not something that should be done as the time I saved by doing this was minimal (though as it turns out necessary) while the gain of having a separate and reusable model would have been nice at this point. Still, this isn’t that much work to implement and what I came out with is slightly different than I would have done in the first project.
The model class consists of an array of values and an array of locked tiles. Any tile can be set, with the set function setting the value of the tile to the mod 10 of the passed number. If the passed number is greater than 10 the lock value is set. This is done to make it easier to pass grid data but is not necessarily a user friendly way of dealing with this problem.
A convenience function for determining which group a tile belongs to based on the row and column was added. The row, column and group counting functions have more appropriate names this time as they are now countValueInX with X being row, col, or group. These functions simply count the occurrences of the indicated value returning the count. To finish off the class, clear and setData methods were added.
The next step then is to implement the hiding of tiles.