/* Program Name: Go Fish Process: Does the following according to spec: Players take turns asking their opponent for a specific card. The game will continue until all sets are collected. Here are the rules of the game: ● Use a 52-card deck ● Deal 7 cards to each player (human and computer). Each play will take turns asking for a card rank/number from the opponent. If the opponent has the card that is requested, they must hand over all the cards of that rank/number. If the opponent does not have the card requested, then the player number “go fish” meaning they must draw a card from the deck. If a player collects a set of four cards of the same rank, they will lay down the set and earn a point. The game will end when all sets have been collected. Function requirements: ● humanTurn ○ Handles the human’s turn. It will prompt the player to ask for a card rank/number and check if the computer has the requested rank/number. If the card is available in the computer’s hand, it will transfer the card to the human’s hand otherwise, it will draw a card. The function should return the number of sets collected during the turn ● computerTurn ○ Handles the computer’s turn and it should do the same actions as the human but for the computer. The function should return the number of set that is collected during its turn. Function Input/Parameters: ??? Function Output/Parameters: ??? Function Output/Returned: ??? Device Input/Device: ??? Device Output/Monitor: ??? Dependencies: ??? */ #include #include #include #include #include #include #include #include using namespace std; // class definitions class Card { // public: Card(char value, char suit) { // store the value and suit. (possible values 2-9, T, J, Q, K, A) cardValue = value; cardSuit = suit; // get the numerical value of the card, casting from string to num where possible. (2-9) if((cardValue >= 2) || (cardValue <= 9)) { // cast the character to number. cardNumericalValue = (int)cardValue - 48; // numerical values 2-9 only } // face values here. if(cardValue == 'T') { // 'ten' card cardNumericalValue = 10; } if(cardValue == 'J') { // jack cardNumericalValue = 11; } if(cardValue == 'Q') { // queen cardNumericalValue = 12; } if(cardValue == 'K') { // king cardNumericalValue = 13; } // special 1/Ace card here if (cardValue == 'A') { cardNumericalValue = 1; } // add the cardValue and cardSuit to the string fullCard = fullCard + cardValue; fullCard = fullCard + cardSuit; } int getCardValue() { // return cardNumericalValue; } char getCardRawValue() { // return cardValue; } char getCardSuit() { // return cardSuit; } string getFullCard() { return fullCard; } friend bool operator==(const Card &cardOne, const Card &cardTwo) { // compare cardOne's value to cardTwo's value. // THIS WILL ONLY CHECK NUMERICAL VALUE // If I was doing this for a REAL card game, I would add an // && (cardOne.cardSuit == cardTwo.cardSuit) // to make sure that the suit AND value are the same. return (cardOne.cardNumericalValue == cardTwo.cardNumericalValue); } friend bool operator<(const Card &cardOne, const Card &cardTwo) { // compare cardOne's value to cardTwo's value with less than function. // THIS WILL ONLY CHECK NUMERICAL VALUE return (cardOne.cardNumericalValue < cardTwo.cardNumericalValue); } private: char cardValue; char cardSuit; int cardNumericalValue; string fullCard; }; // function prototypes int humanTurn(vector &human, vector &computer, vector &cardDeck); int computerTurn(vector &human, vector &computer, vector &cardDeck); // main program int main(int argc, char **argv) { // create array of cards called deck. vector deck; // have two hands for cards vector humanHand; vector computerHand; // keep count of the number of sets collected. ends when number is 13. int currentNumSets = 0; // char array for the setups char suits[] = {'C','D','H','S'}; int suitsLen = sizeof(suits)/sizeof(suits[0]); // char values[] = {'A','2','3','4','5','6','7','8','9','T','J','Q','K'}; char values[] = {'K','Q','J','T','9','8','7','6','5','4','3','2','A'}; int valuesLen = (sizeof(values)/sizeof(values[0])); // game setup // create deck by loop for 1 - 13 with each suit {(H)earts, S(pades), C(lubs), D(iamonds)}. // use double for loop, outer for suits, inner for values. for (int deckCounter = 0; deckCounter < suitsLen; deckCounter++) { // creates each suit for (int suitCounter = 0; suitCounter < valuesLen; suitCounter++) { // creates each card/value deck.push_back(Card(values[suitCounter], suits[deckCounter])); } } // shuffle deck randomly? (use shuffle function from algorithm library) // generate a random number (which is so much harder in CPP because they 'frown upon' using the C STL rand stuff) default_random_engine randNumGen(time(NULL)); // shuffle the deck using that rng engine. shuffle(deck.begin(), deck.end(), randNumGen); // deal hands by taking each card from the deck, one by one (7x) (for loop here.) for(int dealIterator = 0; dealIterator < 7; dealIterator++) { // grab the last card from the deck, put it in the human's hand humanHand.push_back(deck.back()); deck.pop_back(); // grab the last card from the deck, put it in the computer's hand computerHand.push_back(deck.back()); deck.pop_back(); } // tell the user the game has started. cout << "Game Start." << endl; // output the human's hand to the screen cout << "Here is your starting hand:" << endl << "| "; int handSize = humanHand.size(); for(int handDisplayIterator = 0; handDisplayIterator < handSize; handDisplayIterator++) { cout << humanHand[handDisplayIterator].getFullCard() << " | "; } cout << endl; // main gameplay loop (while?) while(currentNumSets != 13) { // switch back and forth between human and computer. currentNumSets = currentNumSets + humanTurn(humanHand, computerHand, deck); currentNumSets = currentNumSets + computerTurn(humanHand, computerHand, deck); } // return 0 return 0; } /* THIS BELOW CODE IS FOR CHECKING THE DECK for (int tempIterator = 0; tempIterator < 52; tempIterator++) { // print off each card to see if it was correctly made. cout << tempIterator << ": " << deck[tempIterator].getFullCard() << " | "; } cout << endl; */ // compiles using "g++ -Wall -pedantic go_fish.cpp -o go_fish" - note to programmer /* Function Name: humanTurn Process: ??? Function Input/Parameters: ??? Function Output/Parameters: ??? Function Output/Returned: ??? Device Input/Device: ??? Device Output/Monitor: ??? Dependencies: ??? */ int humanTurn(vector &human, vector &computer, vector &cardDeck) { /* Handles the human’s turn. It will prompt the player to ask for a card rank/number and check if the computer has the requested rank/number. If the card is available in the computer’s hand, it will transfer the card to the human’s hand otherwise, it will draw a card. The function should return the number of sets collected during the turn */ int numSets = 0; int maxCountCard = 0; char inputChar; bool foundCard = false; // ask for card rank/number/value cout << "Your turn. Ask for a card (2-9, J/Q/K/A): " << endl; cin.ignore(); cout << ">"; cin >> inputChar; Card valueOnlyCard(inputChar, 'X'); // if card is in opposite hand, remove from and give to the other. (loop through computer hand looking for card) for(int checkHandIterator = 0; checkHandIterator < computer.size(); checkHandIterator++) { // checking if value of card is equal to any of the other ones. if(computer[checkHandIterator].getCardRawValue() == inputChar) { // copy the card into the human's hand. human.push_back(computer[checkHandIterator]); // set the card find to true. foundCard = true; } } // remove the cards that had been drawn from the other hand (use remove/remove if and erase with the vector iterators) // NOTE: https://stackoverflow.com/questions/72179264/classes-remove-a-specific-object-from-a-vector-of-objects if(foundCard) { // remove cards if found computer.erase(remove_if(computer.begin(), computer.end(), [&](Card &remCard){return remCard.getCardValue() == inputChar;}), computer.end()); } // if not, draw a card from the top of the deck. else { // draw a card if not found. human.push_back(cardDeck.back()); cardDeck.pop_back(); } // check to see if sets exist in the vector, aka is there four of a value. // if there is four of a value, increase the number of sets to return, remove the cards from hand. // NOTE: https://stackoverflow.com/questions/39906504/how-to-count-duplicates-in-a-vector-c for (int setCounter = 0; setCounter < human.size(); setCounter++) { /* code */ } // return the number of sets return numSets; } /* Function Name: computerTurn Process: ??? Function Input/Parameters: ??? Function Output/Parameters: ??? Function Output/Returned: ??? Device Input/Device: ??? Device Output/Monitor: ??? Dependencies: ??? */ int computerTurn(vector &human, vector &computer, vector &cardDeck) { /* Handles the computer’s turn and it should do the same actions as the human but for the computer. The function should return the number of set that is collected during its turn. */ // return the number of sets return 0; }