bugfixes for starting new round / finishing game

also rename some variables for clarity
This commit is contained in:
eay 2023-06-04 15:41:56 -07:00
parent 0f5928266b
commit 6d6716acbf
4 changed files with 48 additions and 41 deletions

View File

@ -17,7 +17,7 @@ public:
void finalizeScore(); void finalizeScore();
int getScore() const { return myScore; } int getScore() const { return myScore; }
std::string printMyBoard() const; std::string printMyBoard() const;
bool tookPenalty() const { return myTookPoolPenaltyThisTurn; } bool tookPenalty() const { return myTookPoolPenaltyThisRound; }
const std::string getPlayerName() const { return myName; } const std::string getPlayerName() const { return myName; }
private: private:
@ -33,8 +33,8 @@ private:
TileRow myRows[azool::NUMCOLORS]; TileRow myRows[azool::NUMCOLORS];
GameBoard* const myBoardPtr; GameBoard* const myBoardPtr;
int myScore; int myScore;
int myNumPenaltiesForTurn; int myNumPenaltiesForRound;
bool myTookPoolPenaltyThisTurn; bool myTookPoolPenaltyThisRound;
const std::vector<int> PenaltyPoints = {0, 1, 2, 3, 5, 7, 10, 13, 15}; const std::vector<int> PenaltyPoints = {0, 1, 2, 3, 5, 7, 10, 13, 15};
std::string myName; std::string myName;
}; // class Player }; // class Player

View File

@ -1,5 +1,6 @@
#include "GameBoard.h" #include "GameBoard.h"
#include <algorithm> #include <algorithm>
#include <chrono>
GameBoard::GameBoard(int numPlayers) : GameBoard::GameBoard(int numPlayers) :
tileFactories(), tileFactories(),
@ -8,7 +9,8 @@ GameBoard::GameBoard(int numPlayers) :
whiteTileInPool(true), whiteTileInPool(true),
tileBag(), tileBag(),
lastRound(false), lastRound(false),
rng(std::default_random_engine()) { rng(std::default_random_engine(
std::chrono::system_clock::now().time_since_epoch().count())) {
resetBoard(); resetBoard();
} // GameBoard::GameBoard } // GameBoard::GameBoard

View File

@ -9,8 +9,8 @@ Player::Player(GameBoard* const board, std::string name) :
myBoardPtr(board), myBoardPtr(board),
myName(name), myName(name),
myScore(0), myScore(0),
myNumPenaltiesForTurn(0), myNumPenaltiesForRound(0),
myTookPoolPenaltyThisTurn(false) { myTookPoolPenaltyThisRound(false) {
int gridSize = azool::NUMCOLORS * azool::NUMCOLORS; int gridSize = azool::NUMCOLORS * azool::NUMCOLORS;
memset(myGrid, 0, gridSize*sizeof(bool)); memset(myGrid, 0, gridSize*sizeof(bool));
for (int ii = 0; ii < azool::NUMCOLORS; ++ii) { for (int ii = 0; ii < azool::NUMCOLORS; ++ii) {
@ -62,12 +62,13 @@ bool Player::takeTilesFromPool(azool::TileColor color, int rowIdx) {
return false; // couldn't get that tile from the pool return false; // couldn't get that tile from the pool
} }
if (poolPenalty) { if (poolPenalty) {
myTookPoolPenaltyThisTurn = poolPenalty; myTookPoolPenaltyThisRound = true;
myNumPenaltiesForTurn++; myNumPenaltiesForRound++;
} }
placeTiles(rowIdx, color, numTiles); placeTiles(rowIdx, color, numTiles);
return true; return true;
} // Player::takeTilesFromPool } // Player::takeTilesFromPool
void Player::placeTiles(int rowIdx, azool::TileColor color, int numTiles) { void Player::placeTiles(int rowIdx, azool::TileColor color, int numTiles) {
// increment row with # of new tiles // increment row with # of new tiles
myRows[rowIdx].first += numTiles; myRows[rowIdx].first += numTiles;
@ -76,7 +77,7 @@ void Player::placeTiles(int rowIdx, azool::TileColor color, int numTiles) {
int maxNumInRow = rowIdx + 1; int maxNumInRow = rowIdx + 1;
// if tiles overflow the row, take penalty(ies) // if tiles overflow the row, take penalty(ies)
if (myRows[rowIdx].first > maxNumInRow) { if (myRows[rowIdx].first > maxNumInRow) {
myNumPenaltiesForTurn += (myRows[rowIdx].first - maxNumInRow); myNumPenaltiesForRound += (myRows[rowIdx].first - maxNumInRow);
myRows[rowIdx].first = maxNumInRow; myRows[rowIdx].first = maxNumInRow;
} }
} // Player::placeTiles } // Player::placeTiles
@ -103,18 +104,19 @@ void Player::endRound(bool& fullRow) {
myRows[rowIdx].second = azool::NONE; myRows[rowIdx].second = azool::NONE;
} }
} }
#ifdef DEBUG if (myNumPenaltiesForRound >= PenaltyPoints.size()) {
std::cout << "Had " << myNumPenaltiesForTurn << " penalties this turn" << std::endl;
#endif
if (myNumPenaltiesForTurn >= PenaltyPoints.size()) {
myScore -= PenaltyPoints[PenaltyPoints.size() - 1]; myScore -= PenaltyPoints[PenaltyPoints.size() - 1];
} }
else { else {
myScore -= PenaltyPoints[myNumPenaltiesForTurn]; myScore -= PenaltyPoints[myNumPenaltiesForRound];
} }
// reset for next turn // reset for next turn
myTookPoolPenaltyThisTurn = false; // FOR THIS REASON
myNumPenaltiesForTurn = 0; // main loop needs to check who took penalty BEFORE calling this function
// I don't love that, but not sure what else to do
myTookPoolPenaltyThisRound = false;
myNumPenaltiesForRound = 0;
// Check if there's a full row on the grid // Check if there's a full row on the grid
for (int rowIdx = 0; rowIdx < azool::NUMCOLORS; ++rowIdx) { for (int rowIdx = 0; rowIdx < azool::NUMCOLORS; ++rowIdx) {
fullRow = true; fullRow = true;
@ -176,7 +178,9 @@ int Player::scoreTile(int tileRow, int tileCol) {
} }
tileScore++; tileScore++;
} // iterate from current column to right } // iterate from current column to right
#ifdef DEBUG
std::cout << " Final Tile Score: " << tileScore << std::endl; std::cout << " Final Tile Score: " << tileScore << std::endl;
#endif
return tileScore; return tileScore;
} // Player::scoreTile } // Player::scoreTile
@ -184,6 +188,7 @@ void Player::finalizeScore() {
int numRows = 0; int numRows = 0;
int numCols = 0; int numCols = 0;
// compute bonus for rows // compute bonus for rows
// TODO: print bonus info
for (int rowIdx = 0; rowIdx < azool::NUMCOLORS; ++rowIdx) { for (int rowIdx = 0; rowIdx < azool::NUMCOLORS; ++rowIdx) {
bool fullRow = true; bool fullRow = true;
for (int colIdx = 0; colIdx < azool::NUMCOLORS; ++colIdx) { for (int colIdx = 0; colIdx < azool::NUMCOLORS; ++colIdx) {
@ -262,7 +267,7 @@ std::string Player::printMyBoard() const {
} }
oss << "\n"; oss << "\n";
} // iterate over rows } // iterate over rows
oss << "Penalties: " << myNumPenaltiesForTurn << "\n"; oss << "Penalties: " << myNumPenaltiesForRound << "\n";
oss << "Score: " << myScore << "\n"; oss << "Score: " << myScore << "\n";
return oss.str(); return oss.str();
// TODO(feature) - print penalty tiles (?) // TODO(feature) - print penalty tiles (?)
@ -271,7 +276,7 @@ std::string Player::printMyBoard() const {
bool Player::discardFromFactory(int factoryIdx, azool::TileColor color) { bool Player::discardFromFactory(int factoryIdx, azool::TileColor color) {
int numTiles = -1; int numTiles = -1;
if (myBoardPtr->takeTilesFromFactory(factoryIdx, color, numTiles)) { if (myBoardPtr->takeTilesFromFactory(factoryIdx, color, numTiles)) {
myNumPenaltiesForTurn += numTiles; myNumPenaltiesForRound += numTiles;
return true; return true;
} }
return false; return false;
@ -282,9 +287,9 @@ bool Player::discardFromPool(azool::TileColor color) {
int numTiles = -1; int numTiles = -1;
if (myBoardPtr->takeTilesFromPool(color, numTiles, poolPenalty)) { if (myBoardPtr->takeTilesFromPool(color, numTiles, poolPenalty)) {
if (poolPenalty) { if (poolPenalty) {
myNumPenaltiesForTurn++; myNumPenaltiesForRound++;
} }
myNumPenaltiesForTurn += numTiles; myNumPenaltiesForRound += numTiles;
return true; return true;
} }
return false; return false;
@ -293,10 +298,10 @@ bool Player::discardFromPool(azool::TileColor color) {
namespace { namespace {
int promptForFactoryIdx(int maxNumFactories) { int promptForFactoryIdx(int maxNumFactories) {
static const char* promptFactoryIdxDraw = "Which factory? enter index\n"; static const char* promptFactoryIdxDraw = "Which factory? enter index\n";
char factInput[256]; // wayy more than we need char factInput; // TODO can we safely say there will never be more than 9 possible?
std::cout << promptFactoryIdxDraw << std::flush; std::cout << promptFactoryIdxDraw << std::flush;
std::cin >> factInput; std::cin >> factInput;
int factIdx = std::atoi(factInput); int factIdx = std::atoi(&factInput);
if (factIdx < 1 or factIdx > maxNumFactories) { if (factIdx < 1 or factIdx > maxNumFactories) {
return -1; return -1;
} }
@ -330,10 +335,10 @@ namespace {
} }
int promptForRow() { int promptForRow() {
static const char* promptRowPlacement = "Place on which row? enter number [1-5]\n"; static const char* promptRowPlacement = "Place on which row? enter number [1-5]\n";
char rowInput[256] = {0}; char rowInput;
std::cout << promptRowPlacement; std::cout << promptRowPlacement << std::flush;
std::cin >> rowInput; std::cin >> rowInput;
int rowIdx = std::atoi(rowInput); int rowIdx = std::atoi(&rowInput);
if (rowIdx < 1 or rowIdx > azool::NUMCOLORS) { if (rowIdx < 1 or rowIdx > azool::NUMCOLORS) {
return -1; return -1;
} }
@ -447,5 +452,7 @@ void Player::takeTurn() {
} }
} // while !fullinput } // while !fullinput
// options: take tile from pool or take tile from factory // options: take tile from pool or take tile from factory
// TODO(feature) - temporary...reprint board and hold briefly? std::cout << printMyBoard() << std::flush;
// flush out any inputs still in the buffer
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
} // Player::takeTurn } // Player::takeTurn

View File

@ -12,22 +12,21 @@ void testPrint(GameBoard* game) {
} }
void playGame(GameBoard* game) { void playGame(GameBoard* game) {
game->dealTiles();
std::vector<Player*> players = {new Player(game, "P1"), new Player(game, "P2")}; std::vector<Player*> players = {new Player(game, "P1"), new Player(game, "P2")};
bool endOfGame = false; bool endOfGame = false;
Player* firstPlayer = players[0]; // pointers to keep track of first and second player Player* firstPlayer = players[0]; // pointers to keep track of first and second player
Player* secondPlayer = players[1]; Player* secondPlayer = players[1];
while (!endOfGame) { bool p0EndsGame = false;
bool p1EndsGame = false;
while (!(p0EndsGame or p1EndsGame)) {
game->dealTiles();
while (!game->endOfRound()) { while (!game->endOfRound()) {
// TODO figure out how order will work for > 2 players // TODO figure out how order will work for > 2 players
firstPlayer->takeTurn(); firstPlayer->takeTurn();
secondPlayer->takeTurn(); secondPlayer->takeTurn();
} }
std::cout << "End of round!" << std::endl; // check who took penalty
bool p0EndsGame = false; // nees to be done before claling player->endRound()
bool p1EndsGame = false;
players[0]->endRound(p0EndsGame);
players[1]->endRound(p1EndsGame);
if (players[0]->tookPenalty()) { if (players[0]->tookPenalty()) {
firstPlayer = players[0]; firstPlayer = players[0];
secondPlayer = players[1]; secondPlayer = players[1];
@ -41,19 +40,18 @@ void playGame(GameBoard* game) {
firstPlayer = players[0]; firstPlayer = players[0];
secondPlayer = players[1]; secondPlayer = players[1];
} }
if (!(p0EndsGame or p1EndsGame)) { std::cout << "End of round!" << std::endl;
game->dealTiles(); players[0]->endRound(p0EndsGame);
} players[1]->endRound(p1EndsGame);
} }
players[0]->finalizeScore(); players[0]->finalizeScore();
players[1]->finalizeScore(); players[1]->finalizeScore();
std::cout << " Final scores:\n" std::cout << " Final scores:\n" << players[0]->getScore() << "\n" << players[1]->getScore() << "\n" << std::flush;
<< players[0]->getScore() << "\n" << std::flush;
std::cout << players[0]->printMyBoard(); std::cout << players[0]->printMyBoard();
std::cout << players[0]->getScore() << "\n" << std::flush;
std::cout << players[1]->printMyBoard(); std::cout << players[1]->printMyBoard();
if (players[0]) delete players[0]; for (auto player : players) {
if (players[1]) delete players[1]; if (player) delete player;
}
} }
int main() { int main() {