#include <iostream>
#include <string>
#include <assert.h>
using namespace std;
const int NUM_ROWS = 9;
const int NUM_COLS = 9;
// **************** CLASS: CELL *******************
class Cell {
char piece;
char color;
public:
Cell();
void place(char color, char piece);
string take();
string getPiece();
string look();
};
Cell::Cell() {
piece = ' ';
color = ' ';
}
string Cell::look() {
string result = "";
result = result.append(1, color);
result = result.append(1, piece);
return result;
}
string Cell::take() {
string result = look();
piece = ' ';
color = ' ';
return result;
}
void Cell::place(char newColor, char newPiece) {
//assert((newColor == 'W') || (newColor == 'B'));
color = newColor;
//assert((newPiece == 'R') || (newPiece == 'K') || (newPiece == 'B') || (newPiece == 'Q') || (newPiece == 'K') || (newPiece == 'N') || (newPiece == 'P'));
piece = newPiece;
}
string Cell::getPiece() {
string result = "";
result = result.append(1, color);
result = result.append(1, piece);
return result;
}
// **************** CLASS: BOARD *******************
class Board {
Cell board[NUM_ROWS][NUM_COLS]; // <-- Not a good idea in the long run
void displayLine();
bool moveRook(int row, int col, string direction, int steps);
bool movePawn(int row, int col, string direction, int steps);
bool moveBishop(int row, int col, string direction, int steps);
bool moveQueen(int row, int col, string direction, int steps);
bool moveKing(int row, int col, string direction, int steps);
bool moveKnight(int row, int col, string direction, int steps);
public:
Board(string = "WITHPAWNS");
Board(string, int, int, char, char); // Constructor for board with only one piece
void displayBoard();
void place(int, int, char, char);
string take(int, int);
bool cellEmpty(int, int);
string look(int, int);
bool movePieceOneStep(string, string, int&, int&);
bool movePiece(int row, int col, string direction, int steps);
bool turn(int row, int col, string direction, int numSpaces);
};
bool Board::cellEmpty(int row, int col) {
if (board[row][col].getPiece() == " ")
return true;
return false;
}
void Board::place(int row, int col, char color, char peice) {
assert((row >= 0) && (row < NUM_ROWS));
assert((col >= 0) && (col < NUM_COLS));
board[row][col].place(color, peice);
}
string Board::look(int row, int col) {
assert((row >= 0) && (row < NUM_ROWS));
assert((col >= 0) && (col < NUM_COLS));
return board[row][col].look();
}
string Board::take(int row, int col) {
assert((row >= 0) && (row < NUM_ROWS));
assert((col >= 0) && (col < NUM_COLS));
return board[row][col].take();
}
Board::Board(string command, int row, int col, char color, char piece) {
if (command == "ONEPIECE") {
board[row][col].place(color, piece);
return;
}
}
Board::Board(string command) {
board[0][1].place('0', ' ');
board[0][2].place('1', ' ');
board[0][3].place('2', ' ');
board[0][4].place('3', ' ');
board[0][5].place('4', ' ');
board[0][6].place('5', ' ');
board[0][7].place('6', ' ');
board[0][8].place('7', ' ');
board[1][0].place('0', ' ');
board[2][0].place('1', ' ');
board[3][0].place('2', ' ');
board[4][0].place('3', ' ');
board[5][0].place('4', ' ');
board[6][0].place('5', ' ');
board[7][0].place('6', ' ');
board[8][0].place('7', ' ');
board[1][1].place('B', 'R');
board[1][2].place('B', 'N');
board[1][3].place('B', 'B');
board[1][4].place('B', 'Q');
board[1][5].place('B', 'K');
board[1][6].place('B', 'B');
board[1][7].place('B', 'N');
board[1][8].place('B', 'R');
if (command != "NOPAWNS") {
for (int c = 1; c < NUM_COLS; c++) {
board[2][c].place('B', 'P');
}
}
board[NUM_ROWS - 1][1].place('W', 'R');
board[NUM_ROWS - 1][2].place('W', 'N');
board[NUM_ROWS - 1][3].place('W', 'B');
board[NUM_ROWS - 1][4].place('W', 'K');
board[NUM_ROWS - 1][5].place('W', 'Q');
board[NUM_ROWS - 1][6].place('W', 'B');
board[NUM_ROWS - 1][7].place('W', 'N');
board[NUM_ROWS - 1][8].place('W', 'R');
if (command != "NOPAWNS") {
for (int c = 1; c < NUM_COLS; c++) {
board[NUM_COLS - 2][c].place('W', 'P');
}
}
}
void Board::displayLine() {
cout << endl;
for (int x = 0; x < NUM_COLS; x++) {
cout << " | ";
}
cout << endl;
for (int x = 0; x < NUM_COLS; x++) {
cout << "----| ";
}
cout << endl;
}
void Board::displayBoard() {
//return; // DEBUG
cout << endl << "CURRENT BOARD:" << endl << endl;
for (int r = 0; r < NUM_ROWS; r++) {
for (int c = 0; c < NUM_COLS; c++) {
cout << " " << board[r][c].getPiece() << " | ";
}
displayLine();
}
cout << endl << endl;
}
bool Board::movePieceOneStep(string piece, string direction, int &row, int &col) {
assert((row >= 1) && (row < NUM_ROWS));
assert((col >= 1) && (col < NUM_COLS));
int toRow = row;
int toCol = col;
if (direction == "S")
toRow = row + 1;
else if (direction == "N")
toRow = row - 1;
else if (direction == "E")
toCol = col + 1;
else if (direction == "W")
toCol = col - 1;
else if (direction == "NW") {
toRow = row - 1;
toCol = col - 1;
}
else if (direction == "NE") {
toRow = row - 1;
toCol = col + 1;
}
else if (direction == "SW") {
toRow = row + 1;
toCol = col - 1;
}
else if (direction == "SE") {
toRow = row + 1;
toCol = col + 1;
}
else {
cout << "INVALID DIRECTION!" << endl;
assert(false); // force a failure
}
assert((toRow >= 1) && (toRow < NUM_ROWS));
assert((toCol >= 1) && (toCol < NUM_COLS));
if (!cellEmpty(toRow, toCol)) {
string movingPiece = look(row, col);
string blockingPiece = look(toRow, toCol);
if(movingPiece.at(0) == 'W' && blockingPiece.at(0) == 'B'){
piece = take(toRow, toCol);
}
else if(movingPiece.at(0) == 'W' && blockingPiece.at(0) == 'W'){
cout << "Space [ " << toRow << ", " << toCol <<
"] Contains [" << look(toRow, toCol) << "]" << endl;
return false;
}
else if(movingPiece.at(0) == 'B' && blockingPiece.at(0) == 'W'){
piece = take(toRow, toCol);
}
else if(movingPiece.at(0) == 'B' && blockingPiece.at(0) == 'B'){
cout << "Space [ " << toRow << ", " << toCol <<
"] Contains [" << look(toRow, toCol) << "]" << endl;
return false;
}
}
piece = take(row, col);
place(toRow, toCol, piece.at(0), piece.at(1));
row = toRow;
col = toCol;
return true;
}
bool Board::moveQueen(int row, int col, string direction, int steps) {
string piece = look(row, col);
assert(piece.at(1) == 'Q');
for (int x = 0; x < steps; x++) {
if (!movePieceOneStep(piece, direction, row, col))
return false;
}
return true;
}
bool Board::moveKing(int row, int col, string direction, int steps) {
string piece = look(row, col);
assert(piece.at(1) == 'K');
if (steps > 1) {
cout << "Kings can not move " << steps << " steps at a time!" << endl;
return false;
}
if (!movePieceOneStep(piece, direction, row, col))
return false;
return true;
}
bool Board::moveBishop(int row, int col, string direction, int steps) {
string piece = look(row, col);
assert(piece.at(1) == 'B');
if (!((direction == "NE") || (direction == "SE") || (direction == "NW") || (direction == "SW"))) {
cout << "Bishops can not move " << direction << "!" << endl;
return false;
}
for (int x = 0; x < steps; x++) {
if (!movePieceOneStep(piece, direction, row, col))
return false;
}
return true;
}
bool Board::moveRook(int row, int col, string direction, int steps) {
string piece = look(row, col);
assert(piece.at(1) == 'R');
if (!((direction == "N") || (direction == "S") || (direction == "W") || (direction == "E"))) {
cout << "Rooks can not move " << direction << "!" << endl;
return false;
}
for (int x = 0; x < steps; x++) {
if (!movePieceOneStep(piece, direction, row, col))
return false;
}
return true;
}
bool Board::moveKnight(int row, int col, string direction, int steps) {
string piece = look(row, col);
assert(piece.at(1) == 'N');
if (steps > 1) {
cout << "Knights can not move " << steps << " steps at a time!" << endl;
return false;
}
int toRow = row;
int toCol = col;
if (direction == "NNE") {
toRow -= 2;
toCol += 1;
}
else if (direction == "NEE") {
toRow -= 1;
toCol += 2;
}
else if (direction == "SEE") {
toRow += 1 ;
toCol += 2;
}
else if (direction == "SSE") {
toRow += 2 ;
toCol += 1;
}
else if (direction == "SSW") {
toRow += 2;
toCol -= 1;
}
else if (direction == "SWW") {
toRow += 1;
toCol -= 2;
}
else if (direction == "NWW") {
toRow -= 1;
toCol -= 2;
}
else if (direction == "NNW") {
toRow -= 2;
toCol -= 1;
}
else {
cout << "Knights can not move " << direction << "!" << endl;
return false;
}
if (!cellEmpty(toRow, toCol)) {
string movingPiece = look(row, col);
string blockingPiece = look(toRow, toCol);
if(movingPiece.at(0) == 'W' && blockingPiece.at(0) == 'B'){
piece = take(toRow, toCol);
}
else if(movingPiece.at(0) == 'W' && blockingPiece.at(0) == 'W'){
cout << "Space [ " << toRow << ", " << toCol <<
"] Contains [" << look(toRow, toCol) << "]" << endl;
return false;
}
else if(movingPiece.at(0) == 'B' && blockingPiece.at(0) == 'W'){
piece=take(toRow, toCol);
}
else if(movingPiece.at(0) == 'B' && blockingPiece.at(0) == 'B'){
cout << "Space [ " << toRow << ", " << toCol <<
"] Contains [" << look(toRow, toCol) << "]" << endl;
return false;
}
}
piece = take(row, col);
place(toRow, toCol, piece.at(0), piece.at(1));
return true;
}
bool Board::movePawn(int row, int col, string direction, int steps) {
string piece = look(row, col);
assert(piece.at(1) == 'P');
if ((piece.at(0) == 'W') && (direction != "N")) {
cout << "White pawns can not move " << direction << "!" << endl;
return false;
}
if ((piece.at(0) == 'B') && (direction != "S")) {
cout << "Black pawns can not move " << direction << "!" << endl;
return false;
}
if (steps > 2) {
cout << "Pawns can not move " << steps << " steps at a time!" << endl;
return false;
}
else if ((row == 2 && steps <= 2) || (row == 7 && steps <=2)){
for (int x = 0; x < steps; x++) {
if (!movePieceOneStep(piece, direction, row, col))
return false;
}
}
else if (steps == 1){
for (int x = 0; x < steps; x++) {
if (!movePieceOneStep(piece, direction, row, col))
return false;
}
}
return true;
}
bool Board::movePiece(int row, int col, string direction, int steps) {
int holdRow = row, holdCol = col; // <---- CHANGED!
bool result = false; // <---- CHANGED!
string piece = look(row, col);
cout << "*** MOVING " << piece << " FROM [" << row << ", " << col
<< "] Direction:" << direction << " #steps: " << steps << endl;
if (piece.at(1) == 'R')
result = moveRook(row, col, direction, steps);
else if (piece.at(1) == 'P')
result = movePawn(row, col, direction, steps);
else if (piece.at(1) == 'B')
result = moveBishop(row, col, direction, steps);
else if (piece.at(1) == 'Q')
result = moveQueen(row, col, direction, steps);
else if (piece.at(1) == 'K')
result = moveKing(row, col, direction, steps);
else if (piece.at(1) == 'N')
result = moveKnight(row, col, direction, steps);
else {
cout << "Invalid piece " << piece << " at position [" << row << ", " << col << "]" << endl;
assert(false);
}
if (result) { // <---- CHANGED!
return true; // <---- CHANGED!
}
else{// did not work, put it back
piece = take(row, col); // <---- CHANGED!
place(holdRow, holdCol, piece.at(0), piece.at(1)); // <---- CHANGED!
return false;
} // <---- CHANGED!
}
bool Board::turn(int row, int col, string direction, int numSpaces) {
if ((row < 1) || (row >= NUM_ROWS)) {
cout << "OUT OF BOUNDS!" << endl;
assert(false); // temporary
return false;
}
if ((col < 1) || (col >= NUM_COLS)) {
cout << "OUT OF BOUNDS!" << endl;
assert(false); // temporary
return false;
}
if (!movePiece(row, col, direction, numSpaces)) {
cout << "Failed to move the piece the entire way!" << endl;
// assert(false); // temporary
}
displayBoard();
return true;
}
bool makeMove(Board &x, char c){
x;
int row;
int col;
string direction = "";
int numSteps;
if(c=='W'){
cout << "White's Turn!" << endl;
cout << "Enter row: ";
cin >> row;
cout << row << endl;
cout << "Enter column: ";
cin >> col;
cout << col << endl;
cout << "Enter direction: ";
cin >> direction;
cout << direction << endl;
cout << "Enter number of steps: ";
cin >> numSteps;
cout << numSteps << endl;
string piece = x.look((row + 1), (col +1));
if(piece.at(0) == 'W'){
if(!x.turn(row + 1, col + 1, direction, numSteps)){
cout << "Invalid Move. Try another move." << endl;
return false;
}
return true;
}
else{
cout << "White Player can't move that." << endl;
return false;
}
}
else if (c == 'B'){
cout << "Black's Turn!" << endl;
cout << "Enter row: ";
cin >> row;
cout << row << endl;
cout << "Enter column: ";
cin >> col;
cout << col << endl;
cout << "Enter direction: ";
cin >> direction;
cout << direction << endl;
cout << "Enter number of steps: ";
cin >> numSteps;
cout << numSteps << endl;
string piece = x.look((row +1), (col + 1));
if(piece.at(0) == 'B'){
if(!x.turn(row + 1, col + 1, direction, numSteps)){
cout << "Invalid Move. Try another move." << endl;
return false;
}
return true;
}
else{
cout << "Black Player can't move that." << endl;
return false;
}
}
}
bool mated(){
return false;
}
int main() {
Board board;
string goOn = "";
cout << "BEGINNING BOARD:" << endl;
board.displayBoard();
while ((goOn != "N") && (goOn != "n")) {
if (mated())
break;
while (!makeMove(board, 'W')){
continue;
}
if (mated())
break;
while (!makeMove(board, 'B')){
continue;
}
cout << "Continue? (Y/N) ";
cin >> goOn;
cout << goOn << endl;
}
cout << "ENDING BOARD:" << endl;
board.displayBoard();
return 0;
}