/** EightQueens.java -- example of recursion & backtracking. * The problem is that we want to find a way to put 8 queens on a chess * board in such a way that no 2 queens can attack each other. */ public class EightQueens { private static char [][] board; private static boolean done; private static final char queen = 'Q'; private static final char empty = '.'; public static void main(String [] args) { board = new char[8][8]; for (int i = 0; i < board.length; ++i) for (int j = 0; j < board[i].length; ++j) { board[i][j] = empty; } // solve puzzle placeNextQueen(0); // output for (int i = 0; i < board.length; ++i) { for (int j = 0; j < board[i].length; ++j) System.out.print(board[i][j]); System.out.println(); } } /** Place queens in columns col..7 of the board. * Precondition - There are queens in columns 0..col-1. * Postcondition - If a solution is found, queens are in all columns of * the board and done = true. Otherwise, there is no solution for a queen * anywhere in column col and done = false. */ public static void placeNextQueen(int col) { if (col > 7) { done = true; return; } done = false; int row = 0; while (row <= 7 && !done) { // if square can be attacked, then consider next square in col if (canAttack(row, col)) ++row; else { board[row][col] = queen; placeNextQueen(col+1); // if no queen possible in next column, then backtrack // Backtrack means remove this queen, and try next square in col. if (! done) { board[row][col] = empty; ++row; } } } } /** Look in every other square in this row, column and diagonal for * a queen. If we find any, then it can be attacked. */ public static boolean canAttack(int row, int col) { int i, j; // look in this row -- squares of the form board[row][i] for (i = 0; i < 8; ++i) { if (i == col) continue; if (board[row][i] == queen) return true; } // look in this column -- squares of the form board[i][col] for (i = 0; i < 8; ++i) { if (i == row) continue; if (board[i][col] == queen) return true; } // upper-left direction for (i = row-1, j = col-1; i >= 0 && j >= 0; --i, --j) if (board[i][j] == queen) return true; // upper-right direction for (i = row-1, j = col+1; i >= 0 && j < 8; --i, ++j) if (board[i][j] == queen) return true; // lower-left direction for (i = row+1, j = col-1; i < 8 && j >= 0; ++i, --j) if (board[i][j] == queen) return true; // lower-right direction for (i = row+1, j = col+1; i < 8 && j < 8; ++i, ++j) if (board[i][j] == queen) return true; // didn't find a queen to attack return false; } }