3-In-A-Row Solver

Start: 04/30/2020
Due: 05/20/2020
Collaboration: individual
Important Links: style guidelines, maze.zip, nQueens.kt, input_outputs.zip, gradesheet

Lab idea from Dave Reed, Creighton University.


In the 3-In-A-Row puzzle you are given an n by n board for some even integer n. The board is partially filled—some cells are occupied by blue squares, and some by white squares. The rest of the board is empty (shown as gray).

Input board
Figure 1. Input board

You have to fill the board with blue and white squares in such a way that the following two conditions are satisfied.

  1. No row or column has 3-In-A-Row (or 3-In-A-Column) squares of the same color, and
  2. Each row and column has equal number of blue and white squares.

The given puzzle has this solution:

Solution board
Figure 2. Solution

A human trying to solve this puzzle will have to carefully reason her way through it using logical analysis. See an example of such analysis at 3-In-A-Row help. Nevertheless, we can write a computer program that takes an initial board configuration and searches for an answer. However, due to the exponential growth rate in the size of the search space, a naive brute-force search will take prohibitively long. We need to search intelligently.

Backtracking

Backtracking is an established search method for solving many intractable computational problems, including a problem like the 3-In-A-Row puzzle. The algorithm starts with an empty current partial solution. It keeps attempting to complete the current partial solution to a full solution by incrementally adding to the current partial solution one new item at each step. It will systematically try all possibilities of expanding the current partial solution, so long as it cannot prove that the current partial solution is doomed, i.e., not capable of being expanded to a complete solution. Immediately after trial adding a new item to the current partial solution, it checks whether this results in a full solution or not. If it does, the algorithm halts and declares success. Otherwise, it checks whether the last addition has resulted in a doomed partial solution or not. If the new partial solution is not doomed, it continues the search using the new partial solution as the current partial solution. If the new partial solution is doomed, it retracts the last addition and continues with the next possible way to expand this current partial solution. If all possible ways to expand the current partial solution has been exhausted without finding a solution, it retracts its last addition, and continues the search. The search stops when we have checked all possible ways to expand the current partial solution without finding a solution, and the current partial solution is empty. In such a case, it declares failure.

This basic algorithm can be modified to search for all solutions instead of just one solution.

Getting Started

First, make sure you understand the rules and objectives of the puzzle. Second, study the lecture notes on backtracking. Third, design your backtracking search algorithm for the puzzle. Decide on the data structures to be used, the ordering of the items to be added to the current partial solution, how to check for success condition, how to check whether a partial solution is doomed or not, etc. Fourth, write pseudocode for the search. Last, you can now implement your pseudocode as a Kotlin program. Don’t forget to test as soon as you have written even one function.

Required Structure

Instead of being given a skeleton Kotlin file to start from, you are going to write the code more or less from scratch. However, in order to enforce some uniformity (which will make the grading easier), we request that you do certain things:

Extra Credit

You must have completed the program for the regular part described above before attempting this extra credit part. Your attempted extension to the basic program will not be graded unless you also submit a correct program for the regular part. You can make either one or both of the following extensions.

The first entension is to make your program output graphically. Instead of just simple text, make your program display both the input board along side the solution board. This will make it easy for the user to check the correctness of the program’s solution. Here is the result of running my program on the 03-26-easy-6x6.in input file.


Figure 3. Input and solution boards for 03-26-easy-6x6.in

The second extension is to animate the backtracking search like this


Figure 4. Input board and search animation for 03-26-easy-6x6.in

except that, in contrast to the animated gif, your animation should not loop. Your program should animate how the backtrack search proceeds until it finds a solution or determines that there is none, and then stop.

The third extension is to combine all three versions of the program (text, GUI, and animation) into one program. The user chooses which version to execute by providing the appropriate flag on the command line.

The fourth extension is to write a text-only version of the program that prints all solutions.

Gradesheet

We will use this gradesheet when grading your lab.

Submission

As usual, you should submit via Moodle. Simply submit TiarSolverText.kt if you attempt the basic backtracking algorithm only. You should create a new project for each extra credit you attempt. However, when submitting the extra credit work, simply submit the kotlin source code.