A simple but lengthy program in c++. I am new to programming and find it a bit c
ID: 3841835 • Letter: A
Question
A simple but lengthy program in c++. I am new to programming and find it a bit challenging to write this program. If anyone willing to help, and maybe write a few //comments so I can understand the code myself. The guidelines should be pretty clear.
Othello is a game touted as a minute to learn, a lifetime to master." The game is played by 2 people (one who chooses black and one who chooses white) on a board containing 61 squares. The game also uses 6 disks which are white on one side and black on the other. The two players take turns placing disks with their color side up. When a player places a disk which outflanks the opponents color, the opponents disks are flipped. The object of the game is to outflank your opponent and flip your opponent's disks to your color, ending up with the majority of disks on the board in your color. Outflank means to place a disk so that you have a disk of your color at each end of an opponent's row, column, or diagonally in line with of disks of his color For this programa, you will be given a board with both black and white disks already placed on it. You need find the best location to place another white disk, as well as the score (white disks black disks) that will be result. For example, white disk A is already in place on the board. By the placement of white disk B, the black row of disks has been outflanked Figure 1: Before and after a flip by placing disk B A disk may outflank any number of opposing disks in one or more rows. (A row may be one disk or many disks in a straight line. A disk may outflank in any direction: horizontal, vertical, diagonal, forward or backward. A disk may outflank in any number of directions at the same time. (Theoretically, it is possible to flip in up to 8 directions at once.) DISKS MAY ONLY BE FLIPPED AS A DIRECT RESULT OF A MOVE Input The first line of input begins with two positive integers n and m, 0 n mExplanation / Answer
I have developed two games (othello and tic tac toe ) in one program during my college. Because of time constrainst its quite difficult to separate them out. I have give the code below for othello please modify it accordingly.
main.cpp
--------------------------------------------------------------------------------------
#include "GameBoard.h"
#include "GameExceptions.h"
#include "GameMove.h"
#include "GameView.h"
#include "OthelloBoard.h"
#include "OthelloMove.h"
#include "OthelloView.h"
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <limits>
#include <regex>
const int MAX_MOVES_PER_LINE = 13;
const int MOVE_START_INDEX = 5;
using namespace std;
int main(int argc, char* argv[]) {
// Initialization
GameBoard *board; // the state of the game board
GameView *v; // a View for outputting the board via operator<<
int gameChoice=0; // a string to hold the user's game choice
int pos=0; //used to store the starting position of undo number
bool validGameChoice = false;
string userInput; // a string to hold the user's command choice
string moveUndoStr; // a string to hold the # of moves to undo
GameMove *playerMove; //creates and holds the user's desired move
vector<GameMove *> possMoves; // a holder for possible moves
//find out what game the user wants to play
do {
//prompt user to enter what game they want to play
cout << "What Game do you want to play? 1) Othello 2) Tic Tac Toe"
<< endl;//prompt user to enter what game they want to play
//input whole line
getline(cin, userInput);
//make sure user input was a digit
if(!regex_match(userInput, regex("(\+|-)?[[:digit:]]+")))
cout << "You must enter a valid INTEGER NUMBER (1-2)! " << endl;
else {
gameChoice = stoi(userInput);
if(gameChoice < 1 || gameChoice > 2)
cout << "You must enter a number between 1-2! " << endl;
}//end else
//end while
} while(gameChoice < 1 || gameChoice > 2);
//initialize the appropriate board game
if (gameChoice == 1) {
//User indicated that they want to play othello
cout << "Initializing Othello Game ..." << endl;
//Set board and view to appropriate Othello types
board = new OthelloBoard();
v = new OthelloView(board);
}//end if
else {
//User indicated that they want to play Tic Tac Toe
cout << "Initializing Tic Tac Toe Game ..." << endl;
//Set board and view to appropriate TicTacToe types
board = new TicTacToeBoard();
v = new TicTacToeView(board);
}//end else
//itrIndex is for wrap around for possible moves, and userUndos and
//undoLimit are for the undo command
int itrIndex, userUndos, undoLimit;
bool moveIsValid; //used to determine validity of move for move command
string player; //used for showHistory
// Main loop
do {
// Print the game board using the GameView object and all of the
// possible moves. Max number of possible moves per line 13.
cout << *v << (board->GetNextPlayer() == -1 ? ((gameChoice == 1) ?
" Black's" : " X's") : ((gameChoice == 1) ? " White's" :
" O's")) << " move... " << " Possible Moves:" << endl;
itrIndex = 1;
board->GetPossibleMoves(&possMoves);
for (vector<GameMove *>::iterator itr = possMoves.begin();
itr != possMoves.end(); itr++, itrIndex++) {
cout << "move "<< (string)(**itr) << "; ";
if (itrIndex != 0 && itrIndex % MAX_MOVES_PER_LINE == 0)
cout << endl;
delete *itr;
}//end for loop
possMoves.clear();
// Ask to input a command
cout << " Possible commands: move (r,c) undo #moves" <<
" showValue showHistory quit" << endl;
cout << " Please enter a command:" << endl;
getline(cin, userInput);
cout << endl;
// use this inner loop so we do not have to display the gameboard
// and possible moves again after the user has selected the
// showValue and showHistory commands because it would be
//redundant to display the info again since it is still their turn
while (!(userInput == "quit" || board->IsFinished())) {
// Command loop:
// move (r,c) command
if (userInput.find("move") != std::string::npos) {
//Create a game move
playerMove = board->CreateMove();
try {
//Check to see if the move is valid
*playerMove = (string)(userInput.substr(MOVE_START_INDEX));
board->GetPossibleMoves(&possMoves);
moveIsValid = false;
for (vector<GameMove *>::iterator itr = possMoves.begin();
itr != possMoves.end(); itr++) {
moveIsValid = ((**itr == *playerMove) ? true : moveIsValid);
delete *itr;
}//end for
//clear possMoves since it is no longer needed
possMoves.clear();
//if move is valid, apply the move to the board
if (moveIsValid) {
board->ApplyMove(playerMove);
break;
}//end if
//if not, then let the user know that the move is invalid.
cout << "Invalid Move!" << endl;
delete playerMove;
}//end try
catch(OthelloException& e) {
//If there was an exception, display the message and
//delete the move.
cout << e.GetMessage() << endl;
delete playerMove;
}//end catch
}//end if (move (r,c) command)
// undo #moves command
else if (userInput.find("undo") != std::string::npos) {
//split the input to a string containing the number
//portion of the undo command
pos = userInput.find_first_of(' ');
moveUndoStr = (pos > -1) ? userInput.substr(pos+1) :
userInput.substr(userInput.size());
//make sure that the movesStr is an integer
if(!regex_match(moveUndoStr, regex("(\+)?[[:digit:]]+")))
cout << "Invalid command! You must enter the command "
<< "undo followed by a positive number... (Ex: undo 1)" << endl;
else if (board->GetMoveCount() > 0) {
//assign user input to the userUndos variable
userUndos = stoi(moveUndoStr);
undoLimit = board->GetMoveCount();
for (int i = 0; i < userUndos; i++) {
// If the user enters a number that is greater than the
// size of the vector, then we exit the loop right after
// we reach the end of the vector.
if (i == undoLimit)
break;
board->UndoLastMove();
}//end for loop
if (userUndos > undoLimit) {
//Let the user know that they entered a number bigger than
//the size of the vector.
cout << "I have stopped undoing moves because we have " <<
"reached the beginning of the game!" << endl;
}//end if
break;
}//end else if
else
//else, we let the user know that there are no moves to undo.
cout << "There are no moves to undo. " << endl;
}// end if (undo #moves command)
// showValue command
else if (userInput == "showValue")
//display the board value.
cout << "Board Value: " << board->GetValue() << endl;
// showHistory command
else if (userInput == "showHistory") {
//set the player variable to the appropriate value
player = board->GetPlayerString(board->GetNextPlayer());
typedef vector<GameMove *>::const_reverse_iterator constItr;
//iterate through the history vector and display the moves
//according to the order in which they were applied
for (constItr itr = board->GetMoveHistory()->rbegin();
itr != board->GetMoveHistory()->rend(); itr++) {
cout << player << ": " << (string)(**itr) << endl;
//alternate the player
player = (gameChoice == 1 ? (player == "Black" ? "White" :
"Black") : player == "X" ? "O" : "X");
}//close for loop
if (board->GetMoveCount() == 0)
//if the vector is empty, then display the appropriate message
cout << "There are no moves to display." << endl;
}//end if (showHistory command)
// show which player's turn it is
cout << (board->GetNextPlayer() == -1 ? ((gameChoice == 1) ?
" Black's" : " X's") : ((gameChoice == 1) ?
" White's" : " O's")) << " move... " << endl;
// prompt the user to input a command
cout << " Possible commands: move (r,c) undo #moves" <<
" showValue showHistory quit" << endl;
cout << " Please enter a command:" << endl;
getline(cin, userInput);
cout << endl;
}//end command loop
} while (!(userInput == "quit" || board->IsFinished()));
//the game is over. Display the appropriate message / winner
if (gameChoice == 1) {
cout << *v << " Game Over. " << (board->GetValue() == 0 ? "We have a "
"tie!" : board->GetValue() > 0 ? "Black wins!" : "White wins!") << endl;
}//end if
else {
cout << *v << " Game Over. " << (board->GetValue() == 0 ? "We have a"
" tie!" : board->GetValue() > 0 ? "X wins!" : "O wins!") << endl;
}//end else
//now that we are done, we must delete all of the moves that are still
//applied on the board
undoLimit = board->GetMoveCount();
for (int i = 0; i < undoLimit; i++) {
board->UndoLastMove();
}//end for loop
//We must also delete the board and the view pointers that we put
//on the heap.
delete board;
delete v;
}//close main
______________________________________________________________________________
OthelloBoard.cpp
#include "OthelloBoard.h"
#include "OthelloMove.h"
using namespace std;
const int BOARD_INIT_VAR1 = 3;
const int BOARD_INIT_VAR2 = 4;
// Default constructor initializes the board to its starting "new game" state
OthelloBoard::OthelloBoard() {
//initialize the whole board to 0
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
mBoard[i][j] = 0;
}//close inner for loop
}//close outer for loop
//set the 4 middle pieces to their appropriate values
mBoard[BOARD_INIT_VAR1][BOARD_INIT_VAR1] = -1;
mBoard[BOARD_INIT_VAR1][BOARD_INIT_VAR2] = 1;
mBoard[BOARD_INIT_VAR2][BOARD_INIT_VAR1] = 1;
mBoard[BOARD_INIT_VAR2][BOARD_INIT_VAR2] = -1;
//Initialize the Value, PassCount and NextPlayer of the board
mValue = 0, mPassCount = 0;
mNextPlayer = WHITE;
}//close OthelloBoard()
/*
Fills in a vector with all possible moves on the current board state for
the current player. The moves should be ordered based first on row, then on
column. Example ordering: (0, 5) (0, 7) (1, 0) (2, 0) (2, 2) (7, 7)
If no moves are possible, then a single OthelloMove representing a Pass is
put in the vector.
Any code that calls ApplyMove is responsible for first checking that the
requested move is among the possible moves reported by this function.
Precondition: the vector is empty.
Postcondition: the vector contains all valid moves for the current player.
*/
void OthelloBoard::GetPossibleMoves(std::vector<GameMove *> *list) const {
//Local Variables:
//keeps track of the current player
char currentPlayer = (mNextPlayer == WHITE ? BLACK : WHITE);
//these four variables are to determine whether the move is valid or if the
//user must pass
bool validMove = false, mustPass = true;
//used to keep track of the row and column of the direction of the move
int rowVar = 0, colVar = 0;
//Look through all 8 directions on every spot on the board to see if you
//can caputure your opponent's pieces.
for (char i = 0; i < BOARD_SIZE; i++) {
for (char j = 0; j < BOARD_SIZE; j++) {
for (char k = -1; k <= 1; k++) {
for (char l = -1; l <= 1; l++) {
rowVar = 0, colVar = 0;
validMove = false;
//Move one space in the designated direction (i + k), (j + l).
//Make sure that the space is InBounds, is not empty, and is
//not your current location because you do not need to check
//this direction for opponent pieces. Also, make sure that the
//original location was empty, otherwise this would not be a
//valid move.
if (InBounds((i + k), (j + l)) && (!(k == 0 && l == 0))
&& (mBoard[(i + k)][(j + l)] != 0) && mBoard[i][j] == 0) {
//If the space is the enemy, then you set the rowVar and
//colVar equal to i + k and j + l to keep track of where
//you are on the gameboard.
if (mBoard[(i + k)][(j + l)] == mNextPlayer) {
rowVar = i + k;
colVar = j + l;
//while you are InBounds of the board, the current spot
//is an enemy piece, and you originally detected an enemy
//piece, you go one more space in the same direction.
//Repeat until the gameBoard location is no longer the
//enemy.
while(InBounds(rowVar, colVar) && mBoard[rowVar][colVar]
== mNextPlayer) {
rowVar += k;
colVar += l;
}//close while loop
//If the current location is inbounds and is your own
// piece, set the validMove variable to true and the
//mustPass variable to false and then exit the inner loop.
if (InBounds(rowVar, colVar) && mBoard[rowVar][colVar]
== currentPlayer) {
validMove = true;
mustPass = false;
break;
}//end if
}//end if
}//end if
}//close innermost for loop
//if it was a valid move, then push it onto the back of the list
if (validMove) {
OthelloMove *possibleMove = (OthelloMove *) CreateMove();
*possibleMove = OthelloMove(i, j);
list->push_back(possibleMove);
break;
}//end if
}//close second innermost for loop
}//close third innermost for loop
}//close outer for loop
//if the mustPass variable is still true, then the user must pass. We push
//the pass move into the back of the list.
if (mustPass) {
OthelloMove *passMove = (OthelloMove *) CreateMove();
*passMove = OthelloMove();
list->push_back(passMove);
}//end if statement
}//close GetPossibleMoves(...)
/*
Applies a valid move to the board, updating the board state accordingly.
You may assume that this move is valid, and is consistent with the list
of possible moves returned by GetAllMoves. Make sure you account for
changes to the current player, pass count, and board value.
*/
void OthelloBoard::ApplyMove(GameMove *move) {
//Local Variables:
OthelloMove *m = (OthelloMove *) move;
//keeps track of the current player
char currentPlayer = (mNextPlayer == WHITE ? BLACK : WHITE);
//used to keep track of whether the move is valid or not
bool validMove = false;
//used to keep track of the row and column of the direction of the move
int rowVar = 0, colVar = 0;
//keeps track of the number of pieces that were switched per flipset
char switchedPieces = 0;
//Look through all 8 directions to see if you can caputure your
//opponents pieces.
for (char i = -1; i <= 1; i++) {
//If the move was a pass, then we do not need to execute any of the
//following logic. Exit the loop immediately!
if (m->IsPass())
break;
for (char j = -1; j <= 1; j++) {
switchedPieces = 0;
//Move one space in the designated direction (row + i), (col + j).
//Make sure that the space is InBounds, is not empty, and is not
//your current location because you do not need to check this
//direction for opponent pieces being that it will always be you.
if (InBounds((m->mRow + i), (m->mCol + j)) && (!(i == 0 &&
j == 0)) && (mBoard[(m->mRow + i)][(m->mCol + j)] != 0)) {
//If the space is the enemy, then you set the rowVar and colVar
//equal to row + i and col + j to keep track of where you are
//on the gameboard.
if (mBoard[(m->mRow + i)][(m->mCol + j)] == mNextPlayer) {
rowVar = m->mRow + i;
colVar = m->mCol + j;
}//end if
//while you are InBounds of the board and the current spot is an
//enemy piece, you go one more space in the same direction. Repeat
//until the gameBoard location is no longer the enemy.
while(InBounds(rowVar, colVar) && mBoard[rowVar][colVar] ==
mNextPlayer) {
rowVar += i;
colVar += j;
}//close while loop
//If your current location is your own piece, then you go back in
//the opposite direction and set the enemy's pieces to your own.
//You also update the total value of the board, increment the
//switched pieces, set the validMove variable to true, and
//add the flipset to the move's vector of flipsets.
if (InBounds(rowVar, colVar) && mBoard[rowVar][colVar] ==
currentPlayer) {
while (mBoard[rowVar -= i][colVar -= j] == mNextPlayer) {
mValue -= mNextPlayer;
mBoard[rowVar][colVar] = currentPlayer;
switchedPieces+= 1;
mValue += currentPlayer;
}//close while loop
validMove = true;
m->AddFlipSet(OthelloMove::FlipSet(switchedPieces, i, j));
}//end if
}//end if
}//close inner for loop
}//close outer for loop
//if it was a valid move, then we push the move onto the back of the
//mHistory vector
if (validMove)
mHistory.push_back(m);
//if the move is a pass, we add a flipset corresponding to a pass move
if (m->IsPass()) {
m->AddFlipSet(OthelloMove::FlipSet(0, 0, 0));
mHistory.push_back(m);
}//end if
//If it was a valid move, then change the board location (board[row][col])
//to your own piece, otherwise, keep the board location at 0, indicating
//an invalid move.
mBoard[m->mRow][m->mCol] = (validMove ? currentPlayer : 0);
//update the value of the board accordingly
mValue += (validMove ? currentPlayer : 0);
//Increment the pass count if the move was a pass or set it to 0 otherwise
mPassCount = (m->IsPass() ? mPassCount + 1 : 0);
//change the value of mNextPlayer accordingly
mNextPlayer = (mNextPlayer == WHITE ? BLACK : WHITE);
}//close ApplyMove(...)
/*
Undoes the last move applied to the board, restoring it to the state it was
in prior to the most recent move (including whose turn it is, what the
board value is, and what the pass count is).
*/
void OthelloBoard::UndoLastMove() {
//set the currentPlayer variable with the appropriate value
char currentPlayer = (mNextPlayer == WHITE ? BLACK : WHITE);
//set the deleteMove variable to the most recent move
OthelloMove *deleteMove = (OthelloMove *) mHistory.back();
//initialize the rowVar and colVar variables
int rowVar = 0, colVar = 0;
//only delete moves that are not passes
if (!deleteMove->IsPass()) {
//change the piece back to unoccupied
mBoard[deleteMove->mRow][deleteMove->mCol] = 0;
//decrement the board value according to the player
mValue -= mNextPlayer;
//while there are flipsets in the move's flipset vector, iterate
//through them and change the pieces back to their original values
for (vector<OthelloMove::FlipSet>::iterator itr = deleteMove->
mFlips.begin(); itr != deleteMove->mFlips.end(); itr++) {
//set the rowVar and colVar variables to their appropriate values
rowVar = itr->rowDelta + deleteMove->mRow;
colVar = itr->colDelta + deleteMove->mCol;
//while there are still pieces that were switched, go one more
//space in that direction and flip the pieces back to their
//original values and update the board value at the same time
for (itr->switched; itr->switched != 0; itr->switched--) {
mValue -= mNextPlayer;
mBoard[rowVar][colVar] = currentPlayer;
mValue += currentPlayer;
rowVar += itr->rowDelta;
colVar += itr->colDelta;
}//close inner for loop
}//end for loop
}//end if
//delete the move after you are done undoing it and pop it from the back
//of the mHistory vector
delete deleteMove;
mHistory.pop_back();
//set mNextPlayer to the appropriate value and update mPassCount accordingly
mNextPlayer = (mNextPlayer == WHITE ? BLACK : WHITE);
mPassCount = (GetMoveCount() > 0 ? (deleteMove->IsPass() ? 1: 0) : 0);
}//close UndoLastMove()
std::string OthelloBoard::GetPlayerString(char player) {
return (player == 1 ? "Black" : "White");
}//close GetPlayerString(...)
____________________________________________________________________________
OthelloBoard.h
#ifndef __OTHELLOBOARD_H
#define __OTHELLOBOARD_H
#include <vector>
#include "OthelloMove.h"
#include "GameBoard.h"
#include "GameMove.h"
const int BOARD_SIZE = 8;
/*
An OthelloBoard encapsulates data needed to represent a single game of Othello.
This includes the state of the board, tracking the current player, and keeping
a history of moves on the board.
*/
class OthelloBoard : public GameBoard {
public:
enum Player {EMPTY = 0, BLACK = 1, WHITE = -1};
// Default constructor initializes the board to its starting "new game"
// state
OthelloBoard();
/*
Fills in a vector with all possible moves on the current board state for
the current player. The moves should be ordered based first on row, then on
column. Example ordering: (0, 5) (0, 7) (1, 0) (2, 0) (2, 2) (7, 7).
If no moves are possible, then a single OthelloMove representing a Pass is
put in the vector.
Precondition: the vector is empty.
Postcondition: the vector contains all valid moves for the current player.
*/
virtual void GetPossibleMoves(std::vector<GameMove *> *list) const;
/*
Applies a valid move to the board, updating the board state accordingly.
You may assume that this move is valid, and is consistent with the list
of possible moves returned by GetAllMoves.
*/
virtual void ApplyMove(GameMove *move);
/*
Undoes the last move applied to the board, restoring it to the state it was
in prior to the most recent move.
*/
virtual void UndoLastMove();
/*
Creates an OthelloMove object on the heap. Whoever calls this method is
responsible for managing the move's lifetime (or transferring that task to
someone else.)
*/
virtual GameMove *CreateMove() const {return new OthelloMove;}
inline static bool InBounds(int row, int col) {
return row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE;
}//close InBounds(...)
//Represents the player as a string
virtual std::string GetPlayerString(char player);
// Returns true if the game is finished.
virtual bool IsFinished() const {
return mPassCount == 2;
}//close IsFinished()
private:
friend class OthelloView;
char mBoard[BOARD_SIZE][BOARD_SIZE];
static char mWeights[BOARD_SIZE][BOARD_SIZE];
int mPassCount;
}; //close class OthelloBoard
#endif
_______________________________________________________________________________
OthelloMove.cpp
#include "OthelloMove.h"
#include "GameExceptions.h"
#include <string>
#include <sstream>
#define BOARD_SIZE 8
using namespace std;
int OthelloMove::mOutstanding = 0;
// Default constructor: initializes this move as a PASS.
OthelloMove::OthelloMove() : mRow(-1), mCol(-1) {
}//close OthelloMove() default constructor
// 2-parameter constructor: initializes this move with the given
// row and column.
OthelloMove::OthelloMove(int row, int col) : mRow(row), mCol(col) {
}//close OthelloMove(...) 2 - parameter constructor
// Copy Constructor
OthelloMove::OthelloMove(const OthelloMove &other) : mRow(other.mRow),
mCol(other.mCol) {
}//close OthelloMove(...) copy constructor
// Assignment operator taking a const OthelloMove& object.
OthelloMove &OthelloMove::operator=(const OthelloMove &other) {
if(this == &other)
return *this;
mRow = other.mRow;
mCol = other.mCol;
return *this;
}//close operator=(...)
/*
This assignment operator takes a string representation of an Othellomove
and uses it to initialize the move. The string is in the format
(r, c); OR is the string "pass". [The user will not enter (-1,-1) to pass
anymore.]
*/
GameMove &OthelloMove::operator=(const string &string) {
char temp;
if (string == "pass") {
mRow = -1;
mCol = -1;
}// end if
else {
istringstream stringBuffer(string);
stringBuffer >> temp >> mRow >> temp >> mCol >> temp;
if (mRow < 0 || mRow >= BOARD_SIZE || mCol < 0 || mCol >= BOARD_SIZE)
throw OthelloException("Invalid Move!");
}//end else
return *this;
}//close operator=(...) (string input)
// Compares two OthelloMove objects for equality (if rows and cols are same).
bool OthelloMove::Equals(const GameMove &other) const {
OthelloMove &casted = (OthelloMove&) other;
return mRow == casted.mRow && mCol == casted.mCol;
}//close Equals(...)
/*
Converts the OthelloMove into a string representation, one that could be
used correctly with operator=(string). Returns "pass" if move is a pass.
*/
OthelloMove::operator string() const {
ostringstream format;
format << "(" << mRow << "," << mCol << ")";
return (IsPass() ? "pass" : format.str());
}//close operator string()
_________________________________________________________________________________
OthelloMove.h
#ifndef __OTHELLOMOVE_H
#define __OTHELLOMOVE_H
#include "GameMove.h"
#include <string>
#include <vector>
#include <iostream>
/*
An OthelloMove encapsulates a single potential move on an OthelloBoard. It
is represented internally by a row and column, both 0-based.
*/
class OthelloMove : public GameMove {
private:
// OthelloBoard is a friend so it can access mRow and mCol.
friend class OthelloBoard;
/*
A FlipSet tracks a direction and # of pieces that got flipped when this
move was applied. See spec.
*/
struct FlipSet {
FlipSet(char sw, char row, char col) : switched(sw), rowDelta(row),
colDelta(col) {}
char switched;
char rowDelta, colDelta;
}; //close struct FlipSet
int mRow, mCol;
std::vector<FlipSet> mFlips;
// KEEP THESE CONSTRUCTORS PRIVATE.
// Default constructor: initializes this move as a PASS.
OthelloMove();
/*
2-parameter constructor: initializes this move with the given
row and column.
*/
OthelloMove(int row, int col);
void AddFlipSet(FlipSet set) {mFlips.push_back(set);}
static int mOutstanding;
public:
static void* operator new(std::size_t sz) {
mOutstanding++;
std::cout << "operator new: " << mOutstanding << " moves outstanding"
<< std::endl;
return ::operator new(sz);
}//close new(...)
static void operator delete(void* ptr, std::size_t sz) {
mOutstanding--;
std::cout << "operator delete: " << mOutstanding << " moves oustanding"
<< std::endl;
::operator delete(ptr);
}//close delete(...)
virtual ~OthelloMove() {}
OthelloMove(const OthelloMove &);
OthelloMove& operator=(const OthelloMove &rhs);
/*
This assignment operator takes a string representation of an Othellomove
and uses it to initialize the move. The string is in the format
(r, c); OR is the string "pass". [The user will not enter (-1,-1) to pass
anymore.]
*/
virtual GameMove& operator=(const std::string &);
/*
Compares two OthelloMove objects for equality.
*/
virtual bool Equals(const GameMove &other) const;
// Converts the OthelloMove into a string representation, one that could be
// used correctly with operator=(string). Returns "pass" if move is a pass.
virtual operator std::string() const;
// Returns true if the move represents a Pass.
// TO DO: fill in this method.
inline bool IsPass() const {return mRow == -1 && mCol == -1;}
virtual GameMove *Clone() const {
return new OthelloMove(*this);
}//close *Clone()
}; //close class OthelloMove
//int OthelloMove::mOutstanding = 0;
#endif
________________________________________________________________________________
OthelloView.cpp
#include "OthelloView.h"
#include <string>
#include <sstream>
using namespace std;
// The method that does the actual printing to a stream.
void OthelloView::PrintBoard(ostream &s) const {
//Print the contents of the gameboard
s << " Gameboard: - 0 1 2 3 4 5 6 7";
for (int i = 0; i < BOARD_SIZE; i++) {
s << " " << i << " ";
for (int j = 0; j < BOARD_SIZE; j++) {
s << (mOthelloBoard->mBoard[i][j] == 0 ? ". " :
mOthelloBoard->mBoard[i][j] > 0 ? "B " : "W ");
}//close inner for loop
}//close outer for loop
s << endl;
}//close PrintBoard(...)
_______________________________________________________________________
OthelloView.h
__#ifndef __OTHELLOVIEW_H
#define __OTHELLOVIEW_H
#include "OthelloBoard.h"
#include "GameView.h"
#include <iostream>
/*
An MVC "View" class for printing the model of the othello board. Acts as a
"wrapper" around an OthelloBoard pointer and handles requests to print that
board to a stream by overloading operator<<. Friend of OthelloBoard.
*/
class OthelloView : public GameView {
private:
// The actual OthelloBoard pointer.
OthelloBoard *mOthelloBoard;
public:
// The method that does the actual printing to a stream.
virtual void PrintBoard(std::ostream &s) const;
OthelloView(GameBoard *b) : mOthelloBoard((OthelloBoard *) b) {}
};
#endif
________________________________________________________________________
GameBoard.h
#ifndef __GAMEBOARD_H
#define __GAMEBOARD_H
#include "GameMove.h"
#include <vector>
#include <string>
class GameBoard {
public:
// Virtual destructors are important for class hierarchies. Add a virtual
// destructor to all your classes; the destructor can be empty like this.
virtual ~GameBoard() {}
// Initializes a GameBoard with a NextPlayer of 1 and a Value of 0.
GameBoard() : mNextPlayer(1), mValue(0) {}
/*
Fills a vector with all possible GameMoves that can be applied to this
board. The moves returned must be deleted by whoever calls the function.
*/
virtual void GetPossibleMoves(std::vector<GameMove *> *list) const = 0;
/*
Applies a given move to the board, updating its game state and history
accordingly. The board takes ownership of the move pointer given. The
GameMove must an appropriate type for this GameBoard.
*/
virtual void ApplyMove(GameMove *move) = 0;
//Undoes the last move on the board.
virtual void UndoLastMove() = 0;
/*
Creates an appropriate GameMove-derived object representing a "blank" move
on this type of board. This object can be assigned to with a string.
*/
virtual GameMove *CreateMove() const = 0;
/*
Returns true if the game board is "finished", e.g., if one player has won
and no more moves should be allowed.
*/
virtual bool IsFinished() const = 0;
/*
Returns a string representation for the given player value. For most games
this should be "Black" or "White", but this can be customized, e.g. for
Tic-Tac-Toe.
*/
virtual std::string GetPlayerString(char player) {
return (player == 1 ? "Black:" : "White:");
}//close GetPlayerString(...)
inline int GetValue() const {return mValue;}
inline int GetNextPlayer() const {return mNextPlayer;}
/*
Gets a vector of all moves applied to this board. The last move in the
vector is the most recent move applied to the board.
*/
inline const std::vector<GameMove *>* GetMoveHistory() const {
return &mHistory;
}//close GetMoveHistory()
inline int GetMoveCount() const {
return mHistory.size();
}//close GetMoveCount()
protected:
char mNextPlayer;
int mValue;
std::vector<GameMove *> mHistory;
};
#endif
________________________________________________________________________
GameExceptions.h
#ifndef __GAMEEXCEPTIONS_H
#define __GAMEEXCEPTIONS_H
#include <string>
class GameException {
protected:
std::string mMessage;
public:
GameException(const std::string &m) : mMessage(m) {}
inline std::string GetMessage() const {return mMessage;}
}; //close class GameException
class OthelloException : public GameException {
public:
OthelloException(const std::string &m) : GameException(m) {}
}; //close class OthelloException
class TicTacToeException : public GameException {
public:
TicTacToeException(const std::string &m) : GameException(m) {}
}; //close class TicTacToeException
#endif
_________________________________________________________________________
GameMove.h
#ifndef __GAMEMOVE_H
#define __GAMEMOVE_H
#include <string>
class GameMove {
public:
// Virtual destructors are important for class hierarchies. Add a virtual
// destructor to all your classes; the destructor can be empty like this.
virtual ~GameMove() {}
/*
Assigns a string-formatted value to this GameMove. The string value should
be formatted in the same way that operator std::string returns.
*/
virtual GameMove &operator=(const std::string &) = 0;
// Converts the GameMove to a string for output.
virtual operator std::string() const = 0;
/*
Compares one GameMove to another, assuming they are of the same
derived type.
*/
virtual bool Equals(const GameMove &other) const = 0;
/*
Helper method for doing == comparison on derived GameMove types. This
method will be called any time you use == to compare two GameMove objects;
the operator will in turn call the virtual Equals method to support
base-class comparisons.
*/
friend bool operator==(const GameMove &lhs, const GameMove &rhs) {
return lhs.Equals(rhs);
}//close operator==(...)
}; //close class GameMove
#endif
_________________________________________________________________________
GameView.h
#ifndef __GAMEVIEW_H
#define __GAMEVIEW_H
#include "GameBoard.h"
#include <iostream>
class GameView {
public:
// Prints the View's member GameBoard to the ostream parameter.
virtual void PrintBoard(std::ostream &s) const = 0;
/*
Helper method for doing operator<< on derived GameView types. This method
will be called any time you use << to output a GameView object; the
operator will in turn call the virtual PrintBoard method to support
base-class output.
*/
friend std::ostream& operator<< (std::ostream &os, const GameView &v) {
v.PrintBoard(os);
return os;
}//close operator<<(...)
}; //close class GameView
#endif
_________________________________________________________________________
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.