Description
Backtracking is a general algorithm to finding all solutions for a computational problem. It’s used in solving constraint satisfactions problems.
The N-queens problems is about placing N queens on an NxN chess board so that no queen would be a threat to another.
Functions Used
There are 2 main methods I used to determine this. One determines if a queen is safe to be placed on a certain row and the other handles backtracking
//Testing if it's safe to place the queen
private bool IsSafe(char[,] Board, int row, int column)
{
//is column not safe - if for any other row on the same
//column we have a queen that it's not safe
for (int i = 0; i < row; i++) {
if (Board[i, column] == 'Q') return false; } //testing for the same \ diagonal
for (int i = row, j = column; i >= 0 && j >= 0; i--, j--)
{
if (Board[i, j] == 'Q') return false;
}
//testing for the same / diagonal
for (int i = row, j = column; i >= 0 && j < Size; i--, j++)
{
if (Board[i, j] == 'Q') return false;
}
return true;
}
private void Solve(char[,] Board, int row, int column)
{
if (column == 0 && row == Size)
{
this.Solutions.Add(CloneBoard(Board));
return;
}
for (int i = 0; i < Size; i++)
{
if (IsSafe(Board, row, i))
{
Board[row, i] = 'Q';
Solve(CloneBoard(Board), row + 1, 0);
Board[row, i] = '-';
}
}
}
Complete Solution
The solution defines a class that stores all the solutions in a List of matrix char. Queens will have the char ‘Q’ and empty items will have the char ‘-‘
public class NQueens
{
//the size of the board
public int Size { get; }
//A list to place all solutions
public List<char[,]> Solutions { get; }
//counting no of solutions
public int SolutionsCount => Solutions.Count();
public NQueens(int size)
{
this.Size = size;
this.Solutions = new List<char[,]>();
}
public void SolveNQueens()
{
char[,] board = new char[8, 8];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
board[i, j] = '-';
}
}
Solve(board, 0, 0);
}
public void PrintSolution(int index)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
sb.Append(Solutions[index][i, j]);
sb.Append(' ');
}
sb.AppendLine();
}
Console.Write(sb.ToString());
}
//Testing if it's safe to place the queen
private bool IsSafe(char[,] Board, int row, int column)
{
//is column not safe - if for any other row on the same
//column we have a queen that it's not safe
for (int i = 0; i < row; i++)
{
if (Board[i, column] == 'Q') return false; } //testing for the same \ diagonal
for (int i = row, j = column; i >= 0 && j >= 0; i--, j--)
{
if (Board[i, j] == 'Q') return false;
}
//testing for the same / diagonal
for (int i = row, j = column; i >= 0 && j < Size; i--, j++)
{
if (Board[i, j] == 'Q') return false;
}
return true;
}
private char[,] CloneBoard(char[,] board)
{
char[,] newBoard = new char[Size, Size];
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
newBoard[i, j] = board[i, j];
}
}
return newBoard;
}
private void Solve(char[,] Board, int row, int column)
{
if (column == 0 && row == Size)
{
this.Solutions.Add(CloneBoard(Board));
return;
}
for (int i = 0; i < Size; i++)
{
if (IsSafe(Board, row, i))
{
Board[row, i] = 'Q';
Solve(CloneBoard(Board), row + 1, 0);
Board[row, i] = '-';
}
}
}
}
Console Application and WPF Preview
NQueens nQueens = new NQueens(8);
nQueens.SolveNQueens();
nQueens.PrintSolution(0);
Console.WriteLine();
nQueens.PrintSolution(10);









