*0123* 0X 0 1X 1 2X 2 3 3 *0123* *0123* 0 0 1 1 2 2 3XXX 3 *0123*Since the second board is the first board after rotating 90 degrees counterclockwise. transpose() is a no-brainer but rotate90() takes some skills, so code rotate90() by yourself to prove you are made of something, will you?
/* Michael Wen 6/8/2003 This program solves the classic eight queens' puzzle. */ #include <iostream> #include <vector> using namespace std; const int MAX = 8; struct array { int arr[MAX][MAX]; }; int counter; array b; vector<array> va; bool repeated(); void makeEqual(array&, array&); bool operator==(array&, array&); void transpose(array&); void rotate90(array&); void outputBoard(); void initArray(array&); bool conflict(); void recur(int, int); int main() { int cur; bool found; initArray(b); cur = MAX; found = false; counter = 1; /* run the recursive function given the size of the board */ recur(cur, -1); return 0; } /* precondition: none postcondition: return true if b is an orientation contained in va; b is not changed */ bool repeated() { int i; array tempa; makeEqual(tempa, b); /* rotate and transpose each element in va and test if b matches any of it */ for(i=0; i<va.size(); i++) { if(tempa==va[i]) return true; } makeEqual(tempa, b); rotate90(tempa); for(i=0; i<va.size(); i++) { if(tempa==va[i]) return true; } makeEqual(tempa, b); rotate90(tempa); rotate90(tempa); for(i=0; i<va.size(); i++) { if(tempa==va[i]) return true; } makeEqual(tempa, b); rotate90(tempa); rotate90(tempa); rotate90(tempa); for(i=0; i<va.size(); i++) { if(tempa==va[i]) return true; } makeEqual(tempa, b); transpose(tempa); for(i=0; i<va.size(); i++) { if(tempa==va[i]) return true; } makeEqual(tempa, b); transpose(tempa); rotate90(tempa); for(i=0; i<va.size(); i++) { if(tempa==va[i]) return true; } makeEqual(tempa, b); transpose(tempa); rotate90(tempa); rotate90(tempa); for(i=0; i<va.size(); i++) { if(tempa==va[i]) return true; } makeEqual(tempa, b); transpose(tempa); rotate90(tempa); rotate90(tempa); rotate90(tempa); for(i=0; i<va.size(); i++) { if(tempa==va[i]) return true; } return false; } /* precondition: none postcondition: equate b with a */ void makeEqual(array & a, array & b) { int i, i2; for(i=0; i<MAX; ++i) for(i2=0; i2<MAX; ++i2) a.arr[i][i2] = b.arr[i][i2]; } /* precondition: none postcondition: return true if a contains identical elements as b */ bool operator==(array & a, array & b) { int i, i2; for(i=0; i<MAX; ++i) for(i2=0; i2<MAX; ++i2) if(a.arr[i][i2]!=b.arr[i][i2]) return false; return true; } /* precondition: none postcondition: transpose a */ void transpose(array & a) { array tempa; int r, c; initArray(tempa); for(r=0; r<MAX; r++) for(c=0; c<MAX; c++) tempa.arr[r][c] = a.arr[c][r]; makeEqual(a, tempa); } /* precondition: none postcondition: rotate a by 90 degrees counterclockwise */ void rotate90(array & a) { int r, c; bool found = false; array tempa; initArray(tempa); for(r=0; r<MAX; r++) for(c=0; c<MAX; c++) if(MAX-c-1>=0) tempa.arr[MAX-c-1][r] = a.arr[r][c]; makeEqual(a, tempa); } /* precondition: none postcondition: output the board configuration represented by b */ void outputBoard() { int i, i2; cout << "*"; for(i=0; i<MAX; i++) cout << i; cout << "*\n"; for(i=0; i<MAX; i++) { cout << i; for(i2=0; i2<MAX; i2++) if(b.arr[i][i2]==0) cout << 'X'; else cout << ' '; cout << i << endl; } cout << "*"; for(i=0; i<MAX; i++) cout << i; cout << "*\n"; } /* precondition: none postcondition: each element in a is initialized to 1, meaning empty */ void initArray(array & a) { int i, i2; for(i=0; i<MAX; i++) for(i2=0; i2<MAX; i2++) a.arr[i][i2] = 1; } /* precondition: none postcondition: return true if there is conflict among the queens on b; return false otherwise */ bool conflict() { int i, i2, j, j2; for(i=0; i<MAX; i++) for(i2=0; i2<MAX; i2++) if(b.arr[i][i2]==0) { /* vertical and horizontal */ for(j=0; j<MAX; j++) { if(b.arr[j][i2]==0&&j!=i) return true; if(b.arr[i][j]==0&&j!=i2) return true; } /* upper left to lower right */ j = i-1; j2 = i2-1; while(j>=0 && j2>=0) { if(b.arr[j][j2]==0) return true; j--; j2--; } j = i+1; j2 = i2+1; while(j<MAX && j2<MAX) { if(b.arr[j][j2]==0) return true; j++; j2++; } /* upper right to lower left */ j = i-1; j2 = i2+1; while(j>=0 && j2<MAX) { if(b.arr[j][j2]==0) return true; j--; j2++; } j = i+1; j2 = i2-1; while(j<MAX && j2>=0) { if(b.arr[j][j2]==0) return true; j++; j2--; } } return false; } /* precondition: cur and ii should both contain positive values postcondition: recursively find a board configuration where no two queens can attack each other */ void recur(int cur, int ii) { /* if cur is 0 it is the base case */ if(cur==0) { /* if current solution is not repeated */ if(!repeated()) { /* put it in a vector */ va.push_back(b); cout << "\nSolution: " << counter << endl; ++counter; /* output it onto screen */ outputBoard(); } return; } int i, i2; /* loop through each position on the board starting from ii */ for(i=ii+1; i<MAX; i++) { for(i2=0; i2<MAX; i2++) { if(b.arr[i][i2]==1) { /* fill the position with a queen */ b.arr[i][i2]=0; /* if no queens are in conflict with one another */ if(!conflict()) /* call recur() to place the next queen */ recur(cur-1, i); /* un-fill the position */ b.arr[i][i2]=1; } } } }Congratulations if you worked this out by yourself. You’ve certainly gained more experience with writing recursive functions. Care to move on?