Professional Documents
Culture Documents
A Sudoku is a single-player puzzle where the player fills out a 9x9 grid (nine 3x3 subgrids) with the
numbers 1-9, with some values pre-stated. Each row, column and subgrid must contain exactly one
instance of each number 1, 2, , 9. Below is an example of a puzzle with its solution, and the kind of
input your game will take.
String[] sudokuString =
{
"53**7****",
"6**195***",
"*98****6*",
"8***6***3",
"4**8*3**1",
"7***2***6",
"*6****28*",
"***419**5",
"****8**79"
};
Define a class, SudokuGrid that reads in a String array representation of a sudoku puzzle and converts it
to a 2D int array sudoku to hold the 9x9 grid of values. You should have one constructor that does this
and a default constructor that loads it with empty values. Its up to you to decide how to indicate an
empty cell.
DATA
METHODS
Define an interface, Solver, that contains these method signatures. Any class that implements Solver is
expected to store a given SudokuGrid and a copy of it. There will be two so that you will always be able
to identify which cells were initially empty (i.e. which cells to work on) and which had the initial values
(to leave alone). We define this interface to use in the GUI without being tied to a single type of solving
algorithm.
Public SudokuGrid getOriginal() returns a clean copy of the initial sudoku puzzle
Public SudokuGrid getSolution() returns a clean copy of the work-in-progress sudoku puzzle
Public boolean nextStep() will update the work-in-progress with one step. Will return true
until puzzle is completely solved.
Public boolean createSolution() will solve the puzzle from start to finish.
DATA
METHODS
Default constructor loads an grid of empties (tip: call default SudokuGrid constructor).
Initializes emptyTracker and calls findEmptyPixels()
BruteForceSolver(SudokuGrid sudokuInput) loads copies of sudokuInput into sudokuOriginal
and sudoku. Initializes emptyTracker and calls findEmptyPixels()
Define each of the methods listed above in the Solver interface section. Also note:
o nextStep() should be one change of one cell. It should take the current cell (based on
emptyTracker), find its next valid value and put it in or reset to empty. Based on that,
increment/decrement emptyTracker.
o createSolution() should loop through calls of nextStep() until the puzzle is solved.
Private void findEmptyPixels() initialize and load the emptyPixels array.
Main() for testing purposes. Include output from run.
//main for testing purposes
public static void main(String[] args)
{
String[] sudokuString =
{
"53**7****",
"6**195***",
"*98****6*",
"8***6***3",
"4**8*3**1",
"7***2***6",
"*6****28*",
"***419**5",
"****8**79"
};
String[] sudokuString2 =
{
"*3*7*****",
"2****9***",
"97***3***",
"******4**",
"**6***2**",
"**3******",
"***8***54",
"***3****9",
"*****2*6*"
};
String[] sudokuString3 =
{
"8*****137",
"*****8**2",
"7**2**4*6",
"5**182***",
"***6*3***",
"***459**1",
"6*1**5**3",
"9**3*****",
"234*****8"
};
//Solve sudoku 1
SudokuGrid testSudoku = new SudokuGrid(sudokuString);
testSudoku.displayToConsole();
//Solve sudoku 2
testSudoku = new SudokuGrid(sudokuString2);
testSudoku.displayToConsole();
solution = new BruteForceSolver(testSudoku);
solution.createSolution();
solution.displaySolution();
//Solve sudoku 3
testSudoku = new SudokuGrid(sudokuString3);
testSudoku.displayToConsole();
import javax.swing.*;
import java.awt.*;
DATA
Public Solver sudoku an instance of any class that implements the Solver interface
Public JPanel buttonPanel so the controller class can designate buttons itself
Private JPanel gridPanel the panel that displays the sudoku. I recommend using a 9x9
GridLayout for this panel. You may want to consider adding a 2D array of subpanels to more
easily graphically display the nine subsquares of a sudoku puzzle. If you do, use the 3x3
GridLayout for the subpanels and gridPanel. Display a border on a panel like this:
panel.setBorder(BorderFactory.createLineBorder(Color.black))
Private JTextField[][] gridTextFields the array of JTextFields to display the sudoku values.
METHODS
Constructor SudokuFrame(String title, Solver sudoku) saves sudoku, all the panels, and places
the gridTextFields into the appropriate panel(s). Set the layout as BorderLayout so that the
gridPanel can be added to BorderLayout.CENTER and the buttonPanel at BorderLayout.SOUTH.
Will call paint() to load values into gridTextFields
Public void paint() update gridTextFields with values from sudoku and display to the user
using validate() and setVisible(true).
You may want to utilize other optional methods like createTextFields(), createSubGrids(), etc.
Use logic when creating the textFields to visually differentiate between the initial preset values and
those that are being filled in. This is where knowing the original puzzle values comes in handy.
For instance, you could set the original values bold and black and the filled in values smaller and
blue. Dont forget to center all of the textFields.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
DATA
METHODS
Constructor Sudoku(Solver solver) this will accept any class that implements the Solver
interface. (Were only using BruteForceSolver here, but you could write a HeuristicSolver class
that implemented Solver and use it here just the same). Use that Solver to instantiate
mySudokuFrame, size it, and set its default close operation. Instantiate, set up, and add the
buttons to mySudokuFrame.buttonPanel. Create a SolveThread to start solving.
main() this is the main that the puzzle GUI will run from. Use a sudokuString array from a
previous phases main() to create a SudokuGrid and then a BruteForceSolver. Then create and
instantiate Sudoku to start running the GUI. Do not display anything to the console.
Boolean setDelayTime(char newTime) sets delayTime based on given input. I used char
newTime with s for slow, m for medium, and f for fast to determine what to set delayTime
to. Feel free to use alternate input. This is what the TimeListener will call with input depending
on which button was pressed.
INNER CLASSES
All Done! Additional features could be adding the previously proposed HeuristicSolver class, allowing
the user to input a sudoku to solve, and adding buttons to start/stop the solving process.
Heres a stillshot of what my program run looks like mid-run without the additional features: