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)
This commit is contained in:
eay 2023-06-01 17:14:02 -07:00
parent b71d81d8d6
commit 0f5928266b
5 changed files with 35 additions and 48 deletions

View File

@ -3,6 +3,7 @@
#include <vector> #include <vector>
#include <ostream> #include <ostream>
#include <cstring> #include <cstring>
#include <random>
#include "tile_utils.h" #include "tile_utils.h"
class GameBoard { class GameBoard {
@ -14,8 +15,7 @@ public:
int tileCounts[azool::NUMCOLORS]; int tileCounts[azool::NUMCOLORS];
}; // struct Factory }; // struct Factory
GameBoard(); GameBoard(int nPlayers=2);
GameBoard(int factories);
friend std::ostream& operator<<(std::ostream& out, const GameBoard& board); friend std::ostream& operator<<(std::ostream& out, const GameBoard& board);
bool validFactoryRequest(int factoryIdx, azool::TileColor color); bool validFactoryRequest(int factoryIdx, azool::TileColor color);
bool takeTilesFromFactory(int factoryIdx, azool::TileColor color, int& numTiles); bool takeTilesFromFactory(int factoryIdx, azool::TileColor color, int& numTiles);
@ -31,6 +31,8 @@ public:
return tileFactories.empty(); return tileFactories.empty();
} }
private: private:
GameBoard(const GameBoard&) = delete;
GameBoard operator=(const GameBoard&) = delete;
void resetBoard(); void resetBoard();
// - vector of factories? // - vector of factories?
std::vector<Factory> tileFactories; std::vector<Factory> tileFactories;
@ -39,5 +41,6 @@ private:
bool whiteTileInPool; // initialize to true bool whiteTileInPool; // initialize to true
std::vector<azool::TileColor> tileBag; // initialize to 20 of each color std::vector<azool::TileColor> tileBag; // initialize to 20 of each color
bool lastRound; // initialize to false bool lastRound; // initialize to false
std::default_random_engine rng;
}; };
#endif // GAMEBOARD_H_ #endif // GAMEBOARD_H_

View File

@ -16,7 +16,7 @@ public:
void endRound(bool& fullRow); void endRound(bool& fullRow);
void finalizeScore(); void finalizeScore();
int getScore() const { return myScore; } int getScore() const { return myScore; }
void printMyBoard() const; std::string printMyBoard() const;
bool tookPenalty() const { return myTookPoolPenaltyThisTurn; } bool tookPenalty() const { return myTookPoolPenaltyThisTurn; }
const std::string getPlayerName() const { return myName; } const std::string getPlayerName() const { return myName; }

View File

@ -1,34 +1,17 @@
#include "GameBoard.h" #include "GameBoard.h"
#include <algorithm> #include <algorithm>
#include <random>
GameBoard::GameBoard() : GameBoard::GameBoard(int numPlayers) :
tileFactories(), tileFactories(),
maxNumFactories(5), // TODO(feature) base on # of players? 2n+1 maxNumFactories(numPlayers*2+1),
pool(), pool(),
whiteTileInPool(true), whiteTileInPool(true),
tileBag(), tileBag(),
lastRound(false) { lastRound(false),
rng(std::default_random_engine()) {
resetBoard(); resetBoard();
} // GameBoard::GameBoard } // 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<azool::TileColor>(ii);
}
}
} // GameBoard::GameBoard
std::ostream& operator<<(std::ostream& out, const GameBoard& board) { std::ostream& operator<<(std::ostream& out, const GameBoard& board) {
// user will input 1-indexed value, even though we 0-index internally // user will input 1-indexed value, even though we 0-index internally
int factCt = 1; int factCt = 1;
@ -102,8 +85,7 @@ void GameBoard::dealTiles() {
if (tileBag.size() < 4*numFactories) { if (tileBag.size() < 4*numFactories) {
numFactories++; numFactories++;
} }
// TODO(implementation) - set random seed (probably somewhere else) std::shuffle(tileBag.begin(), tileBag.end(), rng);
std::shuffle(tileBag.begin(), tileBag.end(), std::default_random_engine(590));
auto itr = tileBag.begin(); auto itr = tileBag.begin();
for (int ii = 0; ii < numFactories and itr != tileBag.end(); ++ii) { for (int ii = 0; ii < numFactories and itr != tileBag.end(); ++ii) {
Factory fact; Factory fact;

View File

@ -1,6 +1,7 @@
#include "Player.h" #include "Player.h"
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include <sstream>
Player::Player(GameBoard* const board, std::string name) : Player::Player(GameBoard* const board, std::string name) :
myGrid(), myGrid(),
@ -228,41 +229,42 @@ void Player::finalizeScore() {
myScore += (numFives*10); myScore += (numFives*10);
} // Player::finalizeScore } // Player::finalizeScore
void Player::printMyBoard() const { std::string Player::printMyBoard() const {
// TODO(implementation) - replace cout with ostream std::ostringstream oss;
std::cout << "*******************************\n"; oss << "*******************************\n";
std::cout << "PLAYER: " << myName << "\n"; oss << "PLAYER: " << myName << "\n";
std::cout << *myBoardPtr << "\n\n"; oss << *myBoardPtr << "\n\n";
for (int ii = 0; ii < azool::NUMCOLORS; ++ii) { for (int ii = 0; ii < azool::NUMCOLORS; ++ii) {
std::cout << ii+1 << ") "; oss << ii+1 << ") ";
for (int jj = azool::NUMCOLORS; jj > (ii+1); --jj) { for (int jj = azool::NUMCOLORS; jj > (ii+1); --jj) {
std::cout << " "; oss << " ";
} }
for (int jj = ii; jj > -1; --jj) { for (int jj = ii; jj > -1; --jj) {
if (myRows[ii].second == azool::NONE or if (myRows[ii].second == azool::NONE or
jj >= myRows[ii].first) { jj >= myRows[ii].first) {
std::cout << "_"; oss << "_";
} }
else if (jj < myRows[ii].first) { else if (jj < myRows[ii].first) {
std::cout << azool::TileColorSyms[myRows[ii].second]; oss << azool::TileColorSyms[myRows[ii].second];
} }
} }
// print grid row // print grid row
std::cout << " |"; oss << " |";
for (int jj = 0; jj < azool::NUMCOLORS; ++jj) { for (int jj = 0; jj < azool::NUMCOLORS; ++jj) {
// color = row + column % 5 // color = row + column % 5
char color = (ii + jj) % 5; char color = (ii + jj) % 5;
if (myGrid[ii][jj]) { if (myGrid[ii][jj]) {
std::cout << static_cast<char>(azool::TileColorSyms[color] - 32) << "|"; oss << static_cast<char>(azool::TileColorSyms[color] - 32) << "|";
} }
else { else {
std::cout << azool::TileColorSyms[color] << "|"; oss << azool::TileColorSyms[color] << "|";
} }
} }
std::cout << "\n"; oss << "\n";
} // iterate over rows } // iterate over rows
std::cout << "Penalties: " << myNumPenaltiesForTurn << std::endl; oss << "Penalties: " << myNumPenaltiesForTurn << "\n";
std::cout << "Score: " << myScore << std::endl; oss << "Score: " << myScore << "\n";
return oss.str();
// TODO(feature) - print penalty tiles (?) // TODO(feature) - print penalty tiles (?)
} // Player::printMyBoard } // Player::printMyBoard
@ -342,9 +344,10 @@ namespace {
void Player::takeTurn() { void Player::takeTurn() {
// print game board, handle user input // print game board, handle user input
if (myBoardPtr->endOfRound()) return; if (myBoardPtr->endOfRound()) return;
printMyBoard(); std::cout << printMyBoard();
static const char* promptDrawInput = "What would you like to do?\n" 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) " "[d] discard tile(s) "
"[P] print game board again\n"; "[P] print game board again\n";
static const char* promptDiscardInput = "From factory or pool? [f|p]\n"; static const char* promptDiscardInput = "From factory or pool? [f|p]\n";
@ -401,7 +404,6 @@ void Player::takeTurn() {
fullInput = true; fullInput = true;
} }
else if (drawType == 'd') { else if (drawType == 'd') {
// TODO(implementation) (make these strings more betterer)
std::cout << promptDiscardInput << std::flush; std::cout << promptDiscardInput << std::flush;
char discardFrom = '\0'; char discardFrom = '\0';
std::cin >> discardFrom; std::cin >> discardFrom;
@ -438,7 +440,7 @@ void Player::takeTurn() {
} // discard from pool } // discard from pool
} }
else if (drawType == 'P') { else if (drawType == 'P') {
printMyBoard(); std::cout << printMyBoard();
} }
else { else {
std::cout << invalidEntryMessage << std::flush; std::cout << invalidEntryMessage << std::flush;

View File

@ -7,7 +7,7 @@
void testPrint(GameBoard* game) { void testPrint(GameBoard* game) {
game->dealTiles(); game->dealTiles();
Player p1(game); Player p1(game);
p1.printMyBoard(); std::cout << p1.printMyBoard();
return; return;
} }
@ -49,9 +49,9 @@ void playGame(GameBoard* game) {
players[1]->finalizeScore(); players[1]->finalizeScore();
std::cout << " Final scores:\n" std::cout << " Final scores:\n"
<< players[0]->getScore() << "\n" << std::flush; << players[0]->getScore() << "\n" << std::flush;
players[0]->printMyBoard(); std::cout << players[0]->printMyBoard();
std::cout << players[0]->getScore() << "\n" << std::flush; std::cout << players[0]->getScore() << "\n" << std::flush;
players[1]->printMyBoard(); std::cout << players[1]->printMyBoard();
if (players[0]) delete players[0]; if (players[0]) delete players[0];
if (players[1]) delete players[1]; if (players[1]) delete players[1];
} }