Compare commits

...

3 Commits
1.0 ... master

Author SHA1 Message Date
eay
7ba82b569b add license and readme 2023-06-04 15:59:18 -07:00
eay
6d6716acbf bugfixes for starting new round / finishing game
also rename some variables for clarity
2023-06-04 15:42:43 -07:00
eay
0f5928266b 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)
2023-06-01 17:14:02 -07:00
8 changed files with 103 additions and 227 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 emclrk
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1
README.md Normal file
View File

@ -0,0 +1 @@
TODO: write readme :)

View File

@ -1,140 +0,0 @@
Classes:
class Factory {
public:
Factory() : tileCounts(), isEmpty(false) {}
private:
int tileCounts[NUMCOLORS]; // initialize to 0s
bool isEmpty; // initialize to false
}
class Player {
public:
Player();
void checkValidMove(TileColor color, int rowIdx) {
// check if valid move (color exists on selected factory, grid doesn't already have this color on that row,
// row is either empty or already has the same color)
}
void takeTilesFromFactory(int factoryIdx, TileColor color, int rowIdx) {
// call game board -> takeTiles(factoryIdx, color)
placeTiles(color, rowIdx);
}
void takeTilesFromPool(TileColor color, int rowIdx) {
// call game board -> takeTilesFromPool
int numTiles = 0;
bool poolPenalty = myGameBoardPtr->takeTilesFromPool(color, numTiles);
placeTiles(rowIdx, numTiles);
} // takeTilesFromPool
void placeTiles(int rowIdx, int numTiles) {
// increment row with # of new tiles
rows[rowIdx] += numTiles;
int maxNumInRow = rowIdx + 1;
// if tiles overflow the row, take penalty(ies)
if (rows[rowIdx] > maxNumInRow) {
myNumPenaltiesForTurn += (rows[rowIdx] - maxNumInRow);
rows[rowIdx] = maxNumInRow;
}
} // placeTiles
void endRound() {
// determine which rows are full of tiles
// update the grid
// send extra tiles back to the game board
// find the score for each tile placed
for (int ii = 0; ii < NUMCOLORS; ++ii) {
if (myRows[ii].first == (ii+1)) {
// filled a row. now place a tile on the grid
// determine which column it belongs to
int col = (ii + 5 - myRows[ii].second) % 5;
grid[ii][col] = true;
// search horizontally and vertically for points
myScore += scoreTile(ii, col);
// return extra tiles
myBoardPtr->returnTilesToBag(ii, myRows[ii].second);
// reset rows for next turn
myRows[ii].first = 0;
myRows[ii].second = NONE;
}
}
// Account for penalties
} // endRound
int scoreTile(int row, int col) {
int tileScore = 1;
// Get column score
for (int ii = row - 1; ii > -1; --ii) {
if (!grid[ii][col]) {
break;
}
tileScore++;
} // iterate above current row
for (int ii = row; ii < NUMCOLORS; ++ii) {
if (!grid[ii][col]) {
break;
}
tileScore++;
} // iterate from current row down
// Get row score
for (int ii = col - 1; ii > -1; --ii) {
if (!grid[row][ii]) {
break;
}
tileScore++;
} // iterate left of current column
for (int ii = col; ii < NUMCOLORS; ++ii) {
if (!grid[row][ii]) {
break;
}
tileScore++;
} // iterate from current column to right
} // scoreTile
void finalScore() {
// compute bonuses for rows, columns, 5 of a kind
}
private:
// color = r + c % 5
bool myGrid[5][5];
std::pair<int, TileColor> myRows[NUMCOLORS]; // first - # of tiles on that row, second - color of tiles on row
GameBoard* myBoardPtr;
int myScore;
int myNumPenaltiesForTurn;
};
// who manages turns and rounds? probably the main function
class GameBoard {
public:
enum TileColor {
NONE = -1,
RED = 0,
BLUE,
GREEN,
YELLOW,
BLACK,
NUMCOLORS
};
GameBoard();
bool takeTilesFromFactory(int factoryIdx, TileColor color, uint6_t& numTiles) {
// clear factory
// add other tiles to pool
// return # of tiles given to player
// if failed, return false
}
bool takeTilesFromPool(TileColor color, uint6_t& numTiles) {
// zero color count in pool
// return # of tiles given to player (-1 if failed)
// if failed, return false
}
bool returnTilesToBag(uint6_t numTiles, TileColor color);
void endGame(); // called by a player if they get a row
private:
void dealTiles();
void resetTiles();
members:
- vector of factories?
int pool[NUMCOLORS]; // stores the count of each color currently in the pool; initialize to 0s
bool whiteTileInPool; // initialize to true
std::vector<TileColor> tileBag; // initialize to 20 of each color
bool lastRound; // initialize to false
};

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,8 +16,8 @@ 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 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,34 +1,19 @@
#include "GameBoard.h" #include "GameBoard.h"
#include <algorithm> #include <algorithm>
#include <random> #include <chrono>
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(
std::chrono::system_clock::now().time_since_epoch().count())) {
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 +87,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(),
@ -8,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) {
@ -61,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;
@ -75,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
@ -102,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;
@ -175,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
@ -183,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) {
@ -228,48 +234,49 @@ 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: " << myNumPenaltiesForRound << "\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
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;
@ -280,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;
@ -291,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;
} }
@ -328,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;
} }
@ -342,9 +349,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 +409,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,12 +445,14 @@ 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;
} }
} // 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

@ -7,27 +7,26 @@
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;
} }
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();
players[0]->printMyBoard(); std::cout << players[1]->printMyBoard();
std::cout << players[0]->getScore() << "\n" << std::flush; for (auto player : players) {
players[1]->printMyBoard(); if (player) delete player;
if (players[0]) delete players[0]; }
if (players[1]) delete players[1];
} }
int main() { int main() {