Develop a program with a GUI and a text-file reader that solves sudoku puzzles, with the characteristics described below.
- The GUI should include the following:
- buttons for the following functions:
- loading a text file,
- starting the solving algorithm, interrupting the solver,
- clearing all the cells, and
- quitting the program;
- a grid of 81 cells arranged in a square, with visible boundaries between the cells and “stronger” (for example, darker, thicker, or both) boundaries between the 3 3 blocks;
- a “status console” showing status output from the program.
The user can edit cells with the mouse and keyboard when the solver is not run- ning, but the cells should be read-only (to the user) while it is running. Cells that are solved (reduced to one possible value) or impossible (because an inconsistency has been detected) must be colour-coded yellow or red, respectively.
Figures 1, 2 and 3 show a satisfactory example, but your program does not need to look exactly like this. For the best mark, make the cells square with the contents centred horizontally and vertically (better than this example). You can put the buttons and status console in any reasonably usable places. A screen capture of this program running can be found on Youtube. https://youtu.be/F_-ucTsnxM0
Note that the program used in this example would not get 10/10 for the GUI and its solving algorithm is in complete your program should be able to solve this puzzle (it is a real one from a newspaper, which I have been able to solve by hand).
- The status console should be visibly separate from the puzzle grid (a different background colour is sufficient) and should have a fixed number of lines. When a new message is added to a full status console, the oldest message should “roll” off the top. (No scrollbar is needed.) A message should be added when any of the following happens:
- the solving procedure starts;
- the procedure gets stuck (it detects that it cannot eliminate any more possibilities with the information available);
- the procedure succeeds (solves the puzzle);
- the procedure detects an inconsistency or impossibility in the puzzle;
- the user interrupts the solving procedure.
- The solving procedure should try to update cell displays whenever it can and should have occasional short pauses (using Thread.sleep, for example) so the user can see it progress instead of just instantly getting the solution). Updating cell displays will need to use the invokeLater technique in the Week 10 lecture.
Once the solving procedure starts, each cell display should have the following characteristics.
- It is not user-editable.
- It is blank (with a white background) if the program has not eliminated any of the 9 possibilities yet.
- It contains one digit on a yellow background if the cell has been solved.
- It contains 2 to 8 digits on a white background if the cell has not been solved but some values have been eliminated.
- It has a red background if an inconsistency has been detected, such as the following:
- it has only one possible value and another cell in its group (row, column, or block) also has been reduced to the same value;
- it has no possible values because all 9 digits have been used up in its groups (column, row, and block).
- The solving procedure should be able to determine when it has run through all the possible avenues for solving the puzzle without making any progress; in this case it should stop looping and report to the status console that it is stuck.
- The listener for the solve or run button will need to start the solving procedure in a separate thread to avoid locking the GUI, and it will need to check repeatedly whether the interrupt button has been pressed. (See the Week 10 lecture.)
- Your program only needs to handle the most common sudoku format: 9 9 cells in 3 3 blocks, with with the digits 1-9.
- You can use AWT instead of Swing if you wish, but do not use any external libraries (no jar files).
The file-loading code in your program should accept a plain-text file such as those shown in Figure 4. (The second example is more difficult.)
- Loading a file should overwrite all cells in the puzzle.
- The program can ignore extra lines if the file contains more than 9.
- The program can ignore extra characters if a line contains more than 9.
- Any character other than a decimal digit can be treated as a blank cell.
- If any line contains fewer than 9 characters, or the file contains fewer than 9 lines, your program must report an error to the status console and continue running the program should not throw a fatal runtime exception and abort, but let the user type in the cells or try to load another file. In this case, you can leave the cells with their previous values or clear them all to blank (your choice).
- If any java.io.*classes or their methods throw an exception, your program must report an error to the status console and continue running.
The following link contains useful information about methods for solving sudoku puzzles. You can use any of them, but in my experience item 3 (pencilling in) works well with a computer model of the puzzle. Your program will, however, have to use some other techniques (probably pairs and triples using this page’s terminology) to solve more difficult puzzles (for full marks). This link is just a suggestion you can use other algorithms if you prefer, but make sure your code is readable and understandable.
You can represent the puzzle data as 27 cell groups, each containing 9 cells: a group for each row, a group for each column, and a group for each 3 3 block; each cell will be a member of one row group, one column group, and one block group. Each cell should be displayed on screen with an appropriate component (probably a JTextArea or part of a JTable, but you can use any Swing or AWT approach that works without external libraries).
The cell class will need several fields for such things as the possible values it can have, the text to display, whether it has been solved yet, and whether it has been marked as impossible to solve. You will probably need to design an appropriate class for the cell groups too.
One way to control the status console is to store a
List<String> and write a method for adding a new message to it, which also removes the oldest message if the list size is now greater than the fixed length of the console. You could then use the String.join method and update the JTextArea with the result. (This is just a suggestion you can use any approach that works and makes sense.)
This is an individual assignment so you are expected to work on your own. You may discuss the general principles with other students but you must not work together to develop your solution. You must write your own code. All code submitted may be examined using specialized software to identify evidence of code written by another student or downloaded from online resources.
Upload your *.java files to MOLE using the assignments button on the menu bar. Do not submit any other files, such as *.class or *.jar files. (Ignore the week 1 handout about using ZipCentral.) This assignment does not require the sheffield package or any libraries other than the Java standard library, and no other libraries will be used when your code is compiled and executed for marking.
Your code should compile and run under Java 1.8 on the command line:
javac *.java java NameOfMainClass
You can submit your work more than once; the last version submitted will be marked, so check it carefully. You will not be able to submit any code after the final deadline.