Computer Science 1622
Computer Science II

Laboratory Assignment 4
N Queens Problem
Due at the end of Lab

Introduction

The N Queens Problem is one in which you try to find a way to place N queens on a NxN chess board in such a way that no queen attacks any other. One strategy to solve this problem is to start with the first column, finding a position to place a queen in that column. Then we place a queen in the second column in a position the first queen cannot attack. Then we place a queen in the third column in a position the first and second queens cannot attack. We do this for each and every column and once we have placed a queen in each and every column, we have found a solution. So we can use recursion for solving this problem.

For example a solution for a 4x4 board would be:
         
        -------------
        |  |  |Q |  |
        -------------
        |Q |  |  |  |
        -------------
        |  |  |  |Q |
        -------------
        |  |Q |  |  |
        -------------

Suppose that we place the first queen in the first row and first column in a 4x4 board. Next we try the second queen in the first and second row (but the first queen would attack these positions) and settle on the third row:

        -------------
        |Q |  |  |  |
        -------------
        |  |  |  |  |
        -------------
        |  |Q |  |  |
        -------------
        |  |  |  |  |
        -------------

But with this board there is no safe place for the third queen (no row works), so we have to backtrack from our previous decision (placing the second queen in the third row) and try something else. This backtracking process is easy to capture using a recursive process.

In this Lab we will trace a solution to the N Queens Problem thereby gaining some experience in Recursion and Backtracking. A queen on the board is represented as Q, and an empty slot is represented by an underscore ( _ ).

The Program

The following program prompts for the value N for an NxN board (the maximum value of n is taken to be 8), and comes up with a solution to the N Queens Problem, if one exists.

To this program you should make the following changes:

  1. Add a set of statements to print a line every time a queen is placed on the board (look for the place(s) where a Queen is put in a position on the board). The line should begin with a number of spaces equal to 2 times the column number of the queen just placed on the board. You should then print "Placing Queen K at R,K" followed by a newline where K is the column number and R is the row you are trying. After adding this process, your solution for N=4 should produce the following output:
    Enter the board size between 1 and 8: 4
    
      Placing Queen 1 at 1,1
        Placing Queen 2 at 3,2
        Placing Queen 2 at 4,2
          Placing Queen 3 at 2,3
      Placing Queen 1 at 2,1
        Placing Queen 2 at 4,2
          Placing Queen 3 at 1,3
            Placing Queen 4 at 3,4
    
    Solution:
     _  _  Q  _ 
     Q  _  _  _ 
     _  _  _  Q 
     _  Q  _  _ 
    
  2. Add a statement to indicate Backtracking is occuring every time you remove a queen you previously placed on the board (look for a statement that replaces a Queen with an underscore character). The Backtracking statement should be indented by 2 times the column number of the queen just removed spaces. After adding this process, your solution for N=4 should produce the following output:
    Enter the board size between 1 and 8: 4
      Placing Queen 1 at 1,1
        Placing Queen 2 at 3,2
        Backtracking!
        Placing Queen 2 at 4,2
          Placing Queen 3 at 2,3
          Backtracking!
        Backtracking!
      Backtracking!
      Placing Queen 1 at 2,1
        Placing Queen 2 at 4,2
          Placing Queen 3 at 1,3
            Placing Queen 4 at 3,4
    
    Solution:
     _  _  Q  _ 
     Q  _  _  _ 
     _  _  _  Q 
     _  Q  _  _ 
    

Here is the program code:

#include <stdio.h>

#define MAX 8

int main()
{
  char board[MAX][MAX]; /* Representation of the board*/
  int i,j;
  int size, column;
  int found;

  int queen(char board[][MAX], int column, int size); /* The function that finds the solution*/
 
  do {
    printf("Enter the board size between 1 and 8: ");
    scanf("%d", &size);
  } while ((size < 1) || (size > 8));
  for (i = 0; i < size; i++)
    for (j = 0; j < size; j++)
      board[i][j] = '_';

  found = queen(board,0,size);
  if (!found)
    printf("Solution not Found \n");
  return 1;
}

/* The function that finds the solution, it uses recursion to do this*/

int queen(char board[][MAX], int column, int size)
{
  int row = 0;
  int solution;

  int  check(char board[][MAX], int row, int column, int size); /* The function to check whether the position is safe to place a queen */
  void print(char board[][MAX], int size); /* A function that prints out the board state */

  while (row < size) {
    if (check(board, row, column, size) == 1) {
      board[row][column] = 'Q';
      if (column == (size - 1)) { /* A solution has been found*/
        printf("\nSolution:\n");
        print(board, size); /* Prints the board state*/
        return 1;
      }
      else
        if (queen(board, column+1, size))
          return 1;
      board[row][column] = '_';
    }
    row++;
  }

  return 0;
}

/* The function that prints out the board state*/

void print(char board[][MAX], int size) {
  int i,j;

  for (i = 0; i < size; i++) {
    for (j = 0; j < size; j++)
      printf(" %c ", board[i][j]);
    printf("\n");
  }
}

/* The function that checks whether the position is safe to place a queen */
/* Note: you only need to check to the left of the current column */

int check(char board[][MAX], int row, int column, int size) {
  int r,c;

  /* Check for queens in the same row */
  for (c = 0; c < column; c++) 
    if (board[row][c] == 'Q')
      return 0;
  
  /* Checks for queens in the up, left diagonal */
  r = row - 1;
  c = column - 1;
  while ((r >= 0) && (c >= 0))
    if (board[r][c] == 'Q')
      return 0;
    else {
      r--;
      c--;
    }
  
  /* Checks for queens in the down, left diagonal */
  r = row + 1;
  c = column - 1;
  while ((r < size) && (c >= 0))
    if (board[r][c] == 'Q')
      return 0;
    else {
      r++;
      c--;
    }

  /* No queens found, the board checks out */
  return 1;
}


What to turn in

Turn in a hard copy of your final program. Also, turn in a copy of output for your program showing the output for N is 3, 4, 5, 6 and 7.