#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