From 0f5928266b7197cf95c4ca89de70e2446245232e Mon Sep 17 00:00:00 2001 From: eay Date: Thu, 1 Jun 2023 17:14:02 -0700 Subject: [PATCH] Clean up some todos - print player's board by creating string (not using cout) dynamically set # of factories based on # of players reuse random number generator (no hard code seed) --- include/GameBoard.h | 7 +++++-- include/Player.h | 2 +- src/GameBoard.cc | 28 +++++----------------------- src/Player.cc | 40 +++++++++++++++++++++------------------- src/main.cc | 6 +++--- 5 files changed, 35 insertions(+), 48 deletions(-) diff --git a/include/GameBoard.h b/include/GameBoard.h index 473f30b..4ed03dc 100644 --- a/include/GameBoard.h +++ b/include/GameBoard.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "tile_utils.h" class GameBoard { @@ -14,8 +15,7 @@ public: int tileCounts[azool::NUMCOLORS]; }; // struct Factory - GameBoard(); - GameBoard(int factories); + GameBoard(int nPlayers=2); friend std::ostream& operator<<(std::ostream& out, const GameBoard& board); bool validFactoryRequest(int factoryIdx, azool::TileColor color); bool takeTilesFromFactory(int factoryIdx, azool::TileColor color, int& numTiles); @@ -31,6 +31,8 @@ public: return tileFactories.empty(); } private: + GameBoard(const GameBoard&) = delete; + GameBoard operator=(const GameBoard&) = delete; void resetBoard(); // - vector of factories? std::vector tileFactories; @@ -39,5 +41,6 @@ private: bool whiteTileInPool; // initialize to true std::vector tileBag; // initialize to 20 of each color bool lastRound; // initialize to false + std::default_random_engine rng; }; #endif // GAMEBOARD_H_ diff --git a/include/Player.h b/include/Player.h index 484a4b7..de82911 100644 --- a/include/Player.h +++ b/include/Player.h @@ -16,7 +16,7 @@ public: void endRound(bool& fullRow); void finalizeScore(); int getScore() const { return myScore; } - void printMyBoard() const; + std::string printMyBoard() const; bool tookPenalty() const { return myTookPoolPenaltyThisTurn; } const std::string getPlayerName() const { return myName; } diff --git a/src/GameBoard.cc b/src/GameBoard.cc index 6d0de99..90fe60d 100644 --- a/src/GameBoard.cc +++ b/src/GameBoard.cc @@ -1,34 +1,17 @@ #include "GameBoard.h" #include -#include -GameBoard::GameBoard() : +GameBoard::GameBoard(int numPlayers) : tileFactories(), - maxNumFactories(5), // TODO(feature) base on # of players? 2n+1 + maxNumFactories(numPlayers*2+1), pool(), whiteTileInPool(true), tileBag(), - lastRound(false) { + lastRound(false), + rng(std::default_random_engine()) { resetBoard(); } // GameBoard::GameBoard -GameBoard::GameBoard(int factories) : - tileFactories(), - maxNumFactories(factories), - pool(), - whiteTileInPool(true), - tileBag(), - lastRound(false) { - tileBag.reserve(azool::NUMCOLORS * 20); - for (int ii = 0; ii < azool::NUMCOLORS; ++ii) { - pool[ii] = 0; // initialize pool to 0s - // initialize tile bag to 20 of each color - for (int jj = 0; jj < 20; jj++) { - tileBag[ii * 20 + jj] = static_cast(ii); - } - } - } // GameBoard::GameBoard - std::ostream& operator<<(std::ostream& out, const GameBoard& board) { // user will input 1-indexed value, even though we 0-index internally int factCt = 1; @@ -102,8 +85,7 @@ void GameBoard::dealTiles() { if (tileBag.size() < 4*numFactories) { numFactories++; } - // TODO(implementation) - set random seed (probably somewhere else) - std::shuffle(tileBag.begin(), tileBag.end(), std::default_random_engine(590)); + std::shuffle(tileBag.begin(), tileBag.end(), rng); auto itr = tileBag.begin(); for (int ii = 0; ii < numFactories and itr != tileBag.end(); ++ii) { Factory fact; diff --git a/src/Player.cc b/src/Player.cc index caac017..d1f9dbe 100644 --- a/src/Player.cc +++ b/src/Player.cc @@ -1,6 +1,7 @@ #include "Player.h" #include #include +#include Player::Player(GameBoard* const board, std::string name) : myGrid(), @@ -228,41 +229,42 @@ void Player::finalizeScore() { myScore += (numFives*10); } // Player::finalizeScore -void Player::printMyBoard() const { - // TODO(implementation) - replace cout with ostream - std::cout << "*******************************\n"; - std::cout << "PLAYER: " << myName << "\n"; - std::cout << *myBoardPtr << "\n\n"; +std::string Player::printMyBoard() const { + std::ostringstream oss; + oss << "*******************************\n"; + oss << "PLAYER: " << myName << "\n"; + oss << *myBoardPtr << "\n\n"; for (int ii = 0; ii < azool::NUMCOLORS; ++ii) { - std::cout << ii+1 << ") "; + oss << ii+1 << ") "; for (int jj = azool::NUMCOLORS; jj > (ii+1); --jj) { - std::cout << " "; + oss << " "; } for (int jj = ii; jj > -1; --jj) { if (myRows[ii].second == azool::NONE or jj >= myRows[ii].first) { - std::cout << "_"; + oss << "_"; } else if (jj < myRows[ii].first) { - std::cout << azool::TileColorSyms[myRows[ii].second]; + oss << azool::TileColorSyms[myRows[ii].second]; } } // print grid row - std::cout << " |"; + oss << " |"; for (int jj = 0; jj < azool::NUMCOLORS; ++jj) { // color = row + column % 5 char color = (ii + jj) % 5; if (myGrid[ii][jj]) { - std::cout << static_cast(azool::TileColorSyms[color] - 32) << "|"; + oss << static_cast(azool::TileColorSyms[color] - 32) << "|"; } else { - std::cout << azool::TileColorSyms[color] << "|"; + oss << azool::TileColorSyms[color] << "|"; } } - std::cout << "\n"; + oss << "\n"; } // iterate over rows - std::cout << "Penalties: " << myNumPenaltiesForTurn << std::endl; - std::cout << "Score: " << myScore << std::endl; + oss << "Penalties: " << myNumPenaltiesForTurn << "\n"; + oss << "Score: " << myScore << "\n"; + return oss.str(); // TODO(feature) - print penalty tiles (?) } // Player::printMyBoard @@ -342,9 +344,10 @@ namespace { void Player::takeTurn() { // print game board, handle user input if (myBoardPtr->endOfRound()) return; - printMyBoard(); + std::cout << printMyBoard(); static const char* promptDrawInput = "What would you like to do?\n" - "[f] take from factory [p] take from pool " + "[f] take from factory " + "[p] take from pool " "[d] discard tile(s) " "[P] print game board again\n"; static const char* promptDiscardInput = "From factory or pool? [f|p]\n"; @@ -401,7 +404,6 @@ void Player::takeTurn() { fullInput = true; } else if (drawType == 'd') { - // TODO(implementation) (make these strings more betterer) std::cout << promptDiscardInput << std::flush; char discardFrom = '\0'; std::cin >> discardFrom; @@ -438,7 +440,7 @@ void Player::takeTurn() { } // discard from pool } else if (drawType == 'P') { - printMyBoard(); + std::cout << printMyBoard(); } else { std::cout << invalidEntryMessage << std::flush; diff --git a/src/main.cc b/src/main.cc index 517e1ed..d52f23f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -7,7 +7,7 @@ void testPrint(GameBoard* game) { game->dealTiles(); Player p1(game); - p1.printMyBoard(); + std::cout << p1.printMyBoard(); return; } @@ -49,9 +49,9 @@ void playGame(GameBoard* game) { players[1]->finalizeScore(); std::cout << " Final scores:\n" << players[0]->getScore() << "\n" << std::flush; - players[0]->printMyBoard(); + std::cout << players[0]->printMyBoard(); std::cout << players[0]->getScore() << "\n" << std::flush; - players[1]->printMyBoard(); + std::cout << players[1]->printMyBoard(); if (players[0]) delete players[0]; if (players[1]) delete players[1]; }