#include "ColorsGameState.h" #include #include using namespace std; ColorsGameState::ColorsGameState(int numberOfPlayers) { //the only constructor //Note number of players is maxed out at 5, min of 2 //if they request more, we will set it to 5 //if they request less than 2, we set it to 2 if (numberOfPlayers<2) {numPlayers = 2;} if (numberOfPlayers>5) {numPlayers = 5;} if ((numberOfPlayers>=2)&&(numberOfPlayers<=5)) {numPlayers = numberOfPlayers;} //Set up the playerHands vector, zero out each for (int i=0; i playersColoredCards; for (int i=0; i<7; i++) {playersColoredCards.push_back(playerHands[player].coloredCards[i]);} sort(playersColoredCards.begin(), playersColoredCards.end()); //Now the 0th-3rd hold the negative colors and 4th-6th hold the colors //of the top three scoring colors for the player, //these are the ones scored positively //Next check to see if we have wilds, if so, increase the size of the //top scoring color, pCC[6] provided it's not already 6==the max score, //else, add the wilds to some of the other positively scoring colors. while (unscoredWilds>0) { if (playersColoredCards[6]<6) { playersColoredCards[6] = playersColoredCards[6]+1; unscoredWilds--; continue; } if (playersColoredCards[5]<6) { playersColoredCards[5] = playersColoredCards[5]+1; unscoredWilds--; continue; } if (playersColoredCards[4]<6) { playersColoredCards[4] = playersColoredCards[4]+1; unscoredWilds--; continue; } //if we fall through to here then they amazingly have a perfect //hand maxed out with 6 of 3 different colors so the wilds are //useless unscoredWilds--; } //Now the wilds are taken care of so let us score the colors! int scoreTable[] = {0, 1, 3, 6, 10, 15, 21, 21, 21, 21}; //Note the score table gives the conversion between the number of //cards in the color and the number of points that color is then worth //Remember, the first 4 colors, the ones we have the fewest of, score neg. //The last 3, the ones we have the most of, score positively int score=0; for (int i=0; i<4; i++) {score -= scoreTable[playersColoredCards[i]];} score += scoreTable[playersColoredCards[4]]; score += scoreTable[playersColoredCards[5]]; score += scoreTable[playersColoredCards[6]]; //Lastly score the +2's while (unscoredPlusTwos > 0) { score += 2; unscoredPlusTwos--; } return score; } bool ColorsGameState::verifyTypeMove(bool takeMove) { //Verifies if the type of move is acceptable //Default is false bool acceptable = false; //A take move is always valid if there is a non-empty, non-taken row. if (takeMove==true) { //We'll loop thru the rows and if we find one that is non-empty and nontaken, bingo! for (int i=0; inumPlayers-1)) {return false;} //A take move is always valid if the row is non-empty & non-taken. if (takeMove==true) { if (board[rowMove].taken==true) {return false;} //taken == invalid move if (board[rowMove].cards[0] == -1) {return false;} //row empty ==invalid move return true; //else it's a-ok! } //else, the move is a draw. Draw is valid provided row is nonfull, nontaken if (board[rowMove].taken==true) {return false;} //If taken already, invalid move if (board[rowMove].full == true) {return false;} //Row is full, can't play here return true; //else it's a-ok! } int ColorsGameState::acceptMove(bool take, int row) { //Enter the move into the gamestate for the current player //take is a boolean representing whether a player takes a row=0 //or puts adds the top card of the deck on that row=1 //row is the row number //Returns 1 if the game is won, 0 normally. //Note error checking is already done! //A)Process the move, remember there are two possiblities //0)The player took a row //Here we need to update the player's hand and the row if (take==true) { for (int i=0; i<3; i++) { int cardTaken = board[row].cards[i]; if (cardTaken == -1) {break;} //else it's a real card if (cardTaken == 7) {playerHands[currentPlayer].wilds++; continue;} if (cardTaken == 8) {playerHands[currentPlayer].plusTwos++; continue;} playerHands[currentPlayer].coloredCards[cardTaken]++; } board[row].taken = true; playerHands[currentPlayer].taken=true; } //1)The player added a card to a row //Here we need to update the row and the deck pointer else { //Now starting at place 0, find the first empty spot in the row (=-1) //and put the top deck card there bool cardPlayed = false; int *rowSpotPtr = &(board[row].cards[0]); while (cardPlayed==false) { if ((*rowSpotPtr)==-1) { (*rowSpotPtr) = *topOfDeck; cardPlayed=true; } rowSpotPtr++; } if (board[row].cards[2] != -1) {board[row].full =true;} //Row now full topOfDeck++; //Move the top of the deck pointer to the new top of deck } //B)Is the game over? Check and process if so //The game is over if every player has taken AND the top of deck is //close to the bottom if (&(deck[75])-topOfDeck <= numPlayers*3) { bool anyPlayerLeft = false; for (int i=0; i ColorsGameState::scoreAllPlayers() { //Returns a vector in player order of all scores vector scores; for (int i=0; i allPlayersScores) { //Gives the top score among all players //Given as input the output of scoreAllPlayers; //Yeah it's a little awkward but I wanted to keep things modular including the UI int winningScore = allPlayersScores[0]; for (int i=1; i winningScore) {winningScore = currentPlayersScore;} } return winningScore; } vector ColorsGameState::getWinners(int winningScore) { //Gives the player numbers of the winner(s) starting counting at 1!! vector winningPlayers; for (int i=0; i