1/*2 * NQueens.java3 *4 * Computer Science S-22, Harvard University5 */6 7import java.util.*;8 9/** 10 * NQueens - blueprint class for an object that solves the n-queens puzzle 11 * using recursive backtracking. Includes a main() method for using the solver.12 */13public class NQueens { 14 private boolean[][] board; // 2-D array that keeps track of which15 // squares on the board are occupied16 private boolean[] colEmpty; // keeps track of empty columns17 private boolean[] upDiagEmpty; // keeps track of empty up-diagonals18 private boolean[] downDiagEmpty; // keeps track of empty down-diagonals19 20 /** 21 * Constructor - initializes the state of a chess board22 * with the specified boardSize23 */24 public NQueens(int n) {25 this.board = new boolean[n][n]; // initially all false26 this.colEmpty = new boolean[n];27 this.upDiagEmpty = new boolean[2*n - 1];28 this.downDiagEmpty = new boolean[2*n - 1];29 30 /* 31 * set the entries in the the extra bookkeeping arrays to true,32 * since initially everything is empty33 */34 for (int i = 0; i < 2*n - 1; i++) {35 if (i < n) {36 this.colEmpty[i] = true;37 }38 this.upDiagEmpty[i] = true;39 this.downDiagEmpty[i] = true;40 }41 }42 43 /*44 * placeQueen - place a queen at the specified row and column;45 * a private helper method, so we don't need to perform error-checking!46 */47 private void placeQueen(int row, int col) {48 this.board[row][col] = true;49 this.colEmpty[col] = false;50 this.upDiagEmpty[row + col] = false;51 this.downDiagEmpty[(this.board.length - 1) + row - col] = false;52 }53 54 /*55 * removeQueen - remove the queen at the specified row and column;56 * a private helper method, so we don't need to perform error-checking!57 */58 private void removeQueen(int row, int col) {59 this.board[row][col] = false;60 this.colEmpty[col] = true;61 this.upDiagEmpty[row + col] = true;62 this.downDiagEmpty[(this.board.length - 1) + row - col] = true;63 }64 65 /*66 * isSafe - returns true if it is safe to place a queen at the67 * specified square, and false otherwise;68 * a private helper method, so we don't need to perform error-checking!69 */70 private boolean isSafe(int row, int col) {71 return (this.colEmpty[col] && 72 this.upDiagEmpty[row + col]&& 73 this.downDiagEmpty[(this.board.length - 1) + row - col]); 74 }75 76 /*77 * findSolution(int row) - recursive function to search for solutions.78 * Tries to find a safe column in the specified row.79 * If it finds one, it makes a recursive call to handle the next row.80 * If it can't find one, it backtracks by returning from the81 * recursive call.82 * a private helper method, so we don't need to perform error-checking!83 */84 private boolean findSolution(int row) {85 if (row == this.board.length) { // base case: a solution!86 this.displayBoard();87 return true;88 } 89 90 // Try each column in the current row.91 for (int col = 0; col < this.board.length; col++) {92 if (this.isSafe(row, col)) {93 this.placeQueen(row, col);94 95 // Move onto the next row by making a recursive call.96 // If the call returns true, we've already found the solution,97 // so we just keep returning true. Otherwise, we pick up 98 // where we left off in the current row.99 if (this.findSolution(row + 1)) {100 return true;101 }102 103 // If we get here, we've backtracked.104 this.removeQueen(row, col);105 }106 }107 108 return false; // tried all columns in this row, so backtrack!109 } 110 111 /*112 * findSolution() - public "wrapper" method that takes no parameters.113 * Makes the initial call to the private recursive-backtracking method,114 * and returns whatever it returns.115 * 116 * This is an example of method *overloading* -- since we have two methods 117 * with the same name but different parameter lists.118 */119 public boolean findSolution() {120 boolean foundSol = this.findSolution(0);121 return foundSol;122 }123 124 /**125 * displayBoard - display the current state of the board126 */127 public void displayBoard() {128 // print column indices129 System.out.print(" ");130 for (int c = 0; c < this.board.length; c++) {131 System.out.print(" " + (c % 10));132 }133 System.out.println();134 135 // print the contents of the board136 for (int r = 0; r < this.board.length; r++) {137 System.out.print(" " + (r % 10)); // row index138 for (int c = 0; c < this.board.length; c++) {139 if (this.board[r][c]) {140 System.out.print(" Q");141 } else {142 System.out.print(" ");143 }144 }145 System.out.println();146 }147 }148 149 public static void main(String[] args) {150 Scanner console = new Scanner(System.in);151 System.out.print("What is the dimension of the board? ");152 int n= console.nextInt();153 154 NQueens solver = new NQueens(n);155 boolean foundSol = solver.findSolution();156 if (!foundSol) {157 System.out.println("Failed to find a solution!");158 }159 }160}
boolean[][] board
Field defined at line 14.
boolean[] colEmpty
Field defined at line 16.
boolean[] upDiagEmpty
Field defined at line 17.
boolean[] downDiagEmpty
Field defined at line 18.
NQueens(n)
Constructor defined at line 24.
placeQueen(row, col)
Method defined at line 47.
removeQueen(row, col)
Method defined at line 58.
isSafe(row, col)
Method defined at line 70.
findSolution(row)
Method defined at line 84.
findSolution()
Method defined at line 119.
displayBoard()
Method defined at line 127.
main(args)
Method defined at line 149.