CSU Banner

CS 163/164, Spring 2018

Programming Assignment - Honors Option

Sudoku Solver

Due Friday, May. 4th at 11:55pm

This is an Honors Assignment

To get honors option credit for this assignment, you would have already completed the paperwork. All other students are welcome to complete this assignment as optional and will be rewarded a cookie coupon!

Objectives of this Assignment

This assignment has the goal of teaching you how to:
  1. How to write a reasonably complicated Java program,
  2. that solves Sudoku puzzles in a graphical environment,
  3. and makes you implement constraints in a binary format,
  4. and shows the utility of a Java ArrayList based on an inner class.


The purpose of the assignment is to implement an interface that has three methods relating to solving a Sudoku puzzle, and three getters that allow testing of your program. The interface is defined in GameInterface.java, which is part of the Java archive provided with this assignment, as shown below:
import java.util.ArrayList;

public interface GameInterface {

    // Load puzzle from file
    public void load(String filename);

    // Save puzzle to file
    public void save(String filename);

    // Return values
    public enum eStatus {
        eSuccess, // Made successful move
        eFailure, // Cannot solve puzzle!
        eSolved   // Solved entire puzzle
    // Fill in one square, if possible
    public eStatus step();
    // Getter for puzzle data
    public int[][] getData();
    // Getter for puzzle constraints
    public int[][] getConstraints();
    // Inner class for puzzle move
    public class Move {
        int row;
        int column;
        int value;

    // Getter for puzzle solution
    public ArrayList getSolution();
NOTE: This assignment is complex, make sure and read the instructions carefully!


Create a project called Sudoku, and import the Java archive file named Sudoku.jar into the project. If imported correctly, you should see the following project hierarchy: NOTE: Do not change any of the files shown above except GameEngine.java.

Part One

Implement the load(), save(), and updateConstraints() methods in GameEngine.java, as follows:
  1. The load() method allocates the 2-dimensional arrays for the puzzle and constraints, and an ArrayList of Move objects, and reads a puzzle file into the puzzle array. The method should also call updateConstraints().
  2. The save() method writes the puzzle array to a puzzle file.
  3. NOTE: Refer to the two provided puzzles for the format of puzzle files.
  4. The updateConstraints() method updates the constraints for each square that is not occupied in the puzzle.
  5. Test the code above by running the UserInterface, which contains the main() method, and verify that you can produce the correct constraints.
  6. No run configuration setup is required for the project, because the user interface launches a file browser to select files to read and write.
A short note on constraints. There is an integer constraint for each square that has not been filled in yet, meaning the value is still zero. Each constraint consists of the bottom 9 bits of the integer. Bit 0 corresponds to the value 1, Bit 1 corresponds to the value 2, and so on until Bit 8, which corresponds to the value 9. If the bit is 1, then the square cannot contain the corresponding value, otherwise it can. Thus if the bit value of a constraint is 0b110101111, then the value can only be 5 or 7. When the value has exactly one zero, you can fill in the square with the corresponding value. For example, if the constraint is 0b1111111101 then the corresponding square must have the value 2. The constraints are updated after loading the puzzle and after each step.

NOTE: You must implement the constraints exactly as described to pass testing!

Part Two

Implement the step() method to solve the puzzle one step at a time and return the correct status: eFailure for no move possible, eSuccess for a successful move that does not complete the puzzle, and eSolved for a successful move that also completes the puzzle.

The step method figures out the next move, as follows. Check the board row by row, from top to bottom, and within each row, from left to right. Update the first square that you find with a constraint with only one zero. Return eFailure if there are no squares with this status. Return eSuccess if you successfully update one square, but the puzzle is not completely solved. Return eSolved if you successfully update one square, and this also completes the puzzle. Update the constraints after each successful move. You should never update more than one square when the step method is called.

NOTE: In addition to updating one square, you must construct a Move object and add it to the history ArrayList defined in GameEngine.java.


The image below shows the correct constraints before any moves are made, which is all that is required for the initial submission.

Puzzle constraints before any moves

The output below shows the first 10 steps for the Normal.txt puzzle. The output is generated by the UserInterface based on the ArrayList of Move objects returned from the GameEngine.
Filled in 7 at row 0, column 2
Filled in 2 at row 0, column 3
Filled in 3 at row 0, column 5
Filled in 5 at row 0, column 0
Filled in 6 at row 0, column 1
Filled in 8 at row 0, column 7
Filled in 7 at row 1, column 4
Filled in 2 at row 1, column 7
Filled in 9 at row 2, column 5
Filled in 5 at row 2, column 6
The image below shows the correct constraints at the same point in the game, after 10 steps:

Puzzle constraints after 10 moves


Grading Criteria

50 points for Part One, 150 points for Part Two. Preliminary testing is identical to Part One, though testing section above shows an example of correct constraints and moves, and is a superior method of testing to automated grading for this assignment!

Final Testing (Part One) Final Testing (Part Two) The puzzle named Another.txt that we are using for final testing is available here.

Submit GameEngine.java to Checkin.

CS Banner
CS Building