// A classic solitaire game, played with pegs on a board. #include #include using namespace std; class Board { protected: // A 9x9 board // We waste 9 squares on each corner, but it makes the // calculations easier. bool square[9][9]; public: // Does the row,column combination describe a legal square? // // Clients use row and column numbers 1-9. // bool legal_square(int row, int col) const { return 1 <= row && row <= 9 && 4 <= col && col <= 6 || 1 <= col && col <= 9 && 4 <= row && row <= 6; } // Is the square occupied? // // require: legal_square(row, col) // bool test_square(int row, int col) const { return square[row-1][col-1]; } // Set the square // // require: legal_square(row, col) // ensure: test_square(row, col) == value // void set_square(int row, int col, bool value) { square[row-1][col-1] = value; } // initialize a board with all but the central spot occupied: // // 1 2 3 4 5 6 7 8 9 // 1 * * * // 2 * * * // 3 * * * // 4 * * * * * * * * * // 5 * * * * - * * * * // 6 * * * * * * * * * // 7 * * * // 8 * * * // 9 * * * // Board() { int r, c; for (r = 1; r <= 9; r++) for (c = 4; c <= 6; c++) set_square(r, c, true); for (r = 4; r <= 6; r++) for (c = 1; c <= 9; c++) set_square(r, c, true); set_square(5, 5, false); } // Is it legal to move a peg from the indicated position // in the indicated direction (over a peg into an empty square) // bool legal_move(int row, int col, int delta_row, int delta_col) const { return delta_row*delta_row + delta_col*delta_col == 1 && legal_square(row, col) && legal_square(row + 2*delta_row, col + 2*delta_col) && test_square(row, col) && test_square(row + delta_row, col + delta_col) && ! test_square(row + 2*delta_row, col + 2*delta_col); } // Perform the move // // require: legal_move(row, col, delta_row, delta_col) // void make_move(int row, int col, int delta_row, int delta_col) { assert(legal_move(row, col, delta_row, delta_col)); set_square(row, col, false); set_square(row + delta_row, col + delta_col, false); set_square(row + 2*delta_row, col + 2*delta_col, true); } }; // Print the state of the board on the stream. ostream & operator<<(ostream & s, const Board & b) { s << ' '; for (int c = 1; c <= 9; c++) s << ' ' << c; s << '\n'; for (int r = 1; r <= 9; r++) { s << r << ' '; for (int c = 1; c <= 9; c++) { if (! b.legal_square(r, c)) s << ' '; else if (b.test_square(r, c)) s << '*'; else s << '-'; s << ' '; } s << '\n'; } return s; } // command characters const char UP = 'u'; const char DOWN = 'd'; const char LEFT = 'l'; const char RIGHT = 'r'; int main() { Board b; cout << b << '\n'; char c; while (cin >> c) if (c == UP || c == DOWN || c == LEFT || c == RIGHT) { int row, col; if (cin >> row >> col) { // translate the command into a a pair of // numbers representing the direction. int delta_col = 0; int delta_row = 0; if (c == UP) delta_row = -1; else if (c == DOWN) delta_row = 1; else if (c == LEFT) delta_col = -1; else if (c == RIGHT) delta_col = 1; if (b.legal_move(row, col, delta_row, delta_col)) { b.make_move(row, col, delta_row, delta_col); cout << '\n' << b << '\n'; } else cout << "illegal move\n"; } } else cout << "illegal command\n"; return 0; }