/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Champlain College SDEV-345-81 * * C++ Week 4: Discussion (first semester) - Go Fish (2020/09/20) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Collaborate on the discussion to develop a card game. * “Go Fish” is a classic children’s card game * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Written by Llewellyn van der Merwe , September 2020 * Copyright (C) 2020. All Rights Reserved * License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include using namespace std; class cardDB { protected: /** * The Mapper of Specifics **/ map deck_specifics_a; /** * The Mapper for Reverse Specifics **/ map deck_specifics_b; /** * The Mapper for Ranks **/ map deck_ranks_a; /** * The Mapper for Reverse Ranks **/ map deck_ranks_b; /** * The Mapper for Display **/ map deck_display; public: /** * for debugging **/ bool debug = false; // just change this to true to see debug info /** * Constructor to setup the mapper **/ cardDB() { // for display this->deck_display["H1"] = "Ace of Hearts"; this->deck_display["D1"] = "Ace of Diamonds"; this->deck_display["S1"] = "Ace of Spades"; this->deck_display["C1"] = "Ace of Clubs"; this->deck_display["H2"] = "Two of Hearts"; this->deck_display["D2"] = "Two of Diamonds"; this->deck_display["S2"] = "Two of Spades"; this->deck_display["C2"] = "Two of Clubs"; this->deck_display["H3"] = "Three of Hearts"; this->deck_display["D3"] = "Three of Diamonds"; this->deck_display["S3"] = "Three of Spades"; this->deck_display["C3"] = "Three of Clubs"; this->deck_display["H4"] = "Four of Hearts"; this->deck_display["D4"] = "Four of Diamonds"; this->deck_display["S4"] = "Four of Spades"; this->deck_display["C4"] = "Four of Clubs"; this->deck_display["H5"] = "Five of Hearts"; this->deck_display["D5"] = "Five of Diamonds"; this->deck_display["S5"] = "Five of Spades"; this->deck_display["C5"] = "Five of Clubs"; this->deck_display["H6"] = "Six of Hearts"; this->deck_display["D6"] = "Six of Diamonds"; this->deck_display["S6"] = "Six of Spades"; this->deck_display["C6"] = "Six of Clubs"; this->deck_display["H7"] = "Seven of Hearts"; this->deck_display["D7"] = "Seven of Diamonds"; this->deck_display["S7"] = "Seven of Spades"; this->deck_display["C7"] = "Seven of Clubs"; this->deck_display["H8"] = "Eight of Hearts"; this->deck_display["D8"] = "Eight of Diamonds"; this->deck_display["S8"] = "Eight of Spades"; this->deck_display["C8"] = "Eight of Clubs"; this->deck_display["H9"] = "Nine of Hearts"; this->deck_display["D9"] = "Nine of Diamonds"; this->deck_display["S9"] = "Nine of Spades"; this->deck_display["C9"] = "Nine of Clubs"; this->deck_display["H10"] = "Ten of Hearts"; this->deck_display["D10"] = "Ten of Diamonds"; this->deck_display["S10"] = "Ten of Spades"; this->deck_display["C10"] = "Ten of Clubs"; this->deck_display["HJ"] = "Jack of Hearts"; this->deck_display["DJ"] = "Jack of Diamonds"; this->deck_display["SJ"] = "Jack of Spades"; this->deck_display["CJ"] = "Jack of Clubs"; this->deck_display["HQ"] = "Queen of Hearts"; this->deck_display["DQ"] = "Queen of Diamonds"; this->deck_display["SQ"] = "Queen of Spades"; this->deck_display["CQ"] = "Queen of Clubs"; this->deck_display["HK"] = "King of Hearts"; this->deck_display["DK"] = "King of Diamonds"; this->deck_display["SK"] = "King of Spades"; this->deck_display["CK"] = "King of Clubs"; this->deck_specifics_a["H1"] = 1.1; // Ace of Hearts this->deck_specifics_a["D1"] = 1.2; // Ace of Diamonds this->deck_specifics_a["S1"] = 1.3; // Ace of Spades this->deck_specifics_a["C1"] = 1.4; // Ace of Clubs this->deck_specifics_a["H2"] = 2.1; // Two of Hearts this->deck_specifics_a["D2"] = 2.2; // Two of Diamonds this->deck_specifics_a["S2"] = 2.3; // Two of Spades this->deck_specifics_a["C2"] = 2.4; // Two of Clubs this->deck_specifics_a["H3"] = 3.1; // Three of Hearts this->deck_specifics_a["D3"] = 3.2; // Three of Diamonds this->deck_specifics_a["S3"] = 3.3; // Three of Spades this->deck_specifics_a["C3"] = 3.4; // Three of Clubs this->deck_specifics_a["H4"] = 4.1; // Four of Hearts this->deck_specifics_a["D4"] = 4.2; // Four of Diamonds this->deck_specifics_a["S4"] = 4.3; // Four of Spades this->deck_specifics_a["C4"] = 4.4; // Four of Clubs this->deck_specifics_a["H5"] = 5.1; // Five of Hearts this->deck_specifics_a["D5"] = 5.2; // Five of Diamonds this->deck_specifics_a["S5"] = 5.3; // Five of Spades this->deck_specifics_a["C5"] = 5.4; // Five of Clubs this->deck_specifics_a["H6"] = 6.1; // Six of Hearts this->deck_specifics_a["D6"] = 6.2; // Six of Diamonds this->deck_specifics_a["S6"] = 6.3; // Six of Spades this->deck_specifics_a["C6"] = 6.4; // Six of Clubs this->deck_specifics_a["H7"] = 7.1; // Seven of Hearts this->deck_specifics_a["D7"] = 7.2; // Seven of Diamonds this->deck_specifics_a["S7"] = 7.3; // Seven of Spades this->deck_specifics_a["C7"] = 7.4; // Seven of Clubs this->deck_specifics_a["H8"] = 8.1; // Eight of Hearts this->deck_specifics_a["D8"] = 8.2; // Eight of Diamonds this->deck_specifics_a["S8"] = 8.3; // Eight of Spades this->deck_specifics_a["C8"] = 8.4; // Eight of Clubs this->deck_specifics_a["H9"] = 9.1; // Nine of Hearts this->deck_specifics_a["D9"] = 9.2; // Nine of Diamonds this->deck_specifics_a["S9"] = 9.3; // Nine of Spades this->deck_specifics_a["C9"] = 9.4; // Nine of Clubs this->deck_specifics_a["H10"] = 10.1; // Ten of Hearts this->deck_specifics_a["D10"] = 10.2; // Ten of Diamonds this->deck_specifics_a["S10"] = 10.3; // Ten of Spades this->deck_specifics_a["C10"] = 10.4; // Ten of Clubs this->deck_specifics_a["HJ"] = 11.1; // Jack of Hearts this->deck_specifics_a["DJ"] = 11.2; // Jack of Diamonds this->deck_specifics_a["SJ"] = 11.3; // Jack of Spades this->deck_specifics_a["CJ"] = 11.4; // Jack of Clubs this->deck_specifics_a["HQ"] = 12.1; // Queen of Hearts this->deck_specifics_a["DQ"] = 12.2; // Queen of Diamonds this->deck_specifics_a["SQ"] = 12.3; // Queen of Spades this->deck_specifics_a["CQ"] = 12.4; // Queen of Clubs this->deck_specifics_a["HK"] = 13.1; // King of Hearts this->deck_specifics_a["DK"] = 13.2; // King of Diamonds this->deck_specifics_a["SK"] = 13.3; // King of Spades this->deck_specifics_a["CK"] = 13.4; // King of Clubs // setup the reverse map for (map::iterator i = this->deck_specifics_a.begin(); i != this->deck_specifics_a.end(); ++i) { this->deck_specifics_b[i->second] = i->first; } // set the deck ranks this->deck_ranks_a["1"] = 1; // Ace this->deck_ranks_a["2"] = 2; // Two this->deck_ranks_a["3"] = 3; // Three this->deck_ranks_a["4"] = 4; // Four this->deck_ranks_a["5"] = 5; // Five this->deck_ranks_a["6"] = 6; // Six this->deck_ranks_a["7"] = 7; // Seven this->deck_ranks_a["8"] = 8; // Eight this->deck_ranks_a["9"] = 9; // Nine this->deck_ranks_a["10"] = 10; // Ten this->deck_ranks_a["J"] = 11; // Jack this->deck_ranks_a["Q"] = 12; // Queen this->deck_ranks_a["K"] = 13; // King // setup the reverse map for (map::iterator i = this->deck_ranks_a.begin(); i != this->deck_ranks_a.end(); ++i) { this->deck_ranks_b[i->second] = i->first; } } // get the double KEY double getDoubleKey(int rank, int shape) { return (double) rank + ((double) shape / 10.0f); } // check if we can find the card bool searchDeck(string key) { // the iterator search map::iterator found = this->deck_specifics_a.find(key); // check if it is found if (found != this->deck_specifics_a.end()) { // element found; return true; } // the iterator search map::iterator rfound = this->deck_ranks_a.find(key); // check if it is found if (rfound != this->deck_ranks_a.end()) { // element found; return true; } // element not found return false; } // check if we can find the card bool searchDeck(double key) { // the iterator search map::iterator found = this->deck_specifics_b.find(key); // check if it is found if (found != this->deck_specifics_b.end()) { // element found; return true; } // element not found return false; } // get the card double get(string key) { // the iterator search map::iterator found = this->deck_specifics_a.find(key); // check if it is found if (found != this->deck_specifics_a.end()) { // element found; return found->second; } // element not found return 0; } }; class deck : public cardDB { protected: /** * mode 1 = RANK; 2 = SPECIFIC; **/ int mode = 1; // default is RANK /** * To Shuffle Deck */ stack deck_1; stack deck_2; stack deck_3; stack deck_4; stack deck_5; public: /** * The Deck **/ stack mixed; deck() { // setup the mixed deck for (map::iterator i = this->deck_specifics_a.begin(); i != this->deck_specifics_a.end(); ++i) { // random sort the cards int deck_n = this->getRandom(1, 5, 0); switch (deck_n) { case 1: this->deck_1.push(i->second); break; case 2: this->deck_2.push(i->second); break; case 3: this->deck_3.push(i->second); break; case 4: this->deck_4.push(i->second); break; case 5: this->deck_5.push(i->second); break; } } // if debug mode we check the shuffle vector debug_deck; // complete the shuffle int not_again[] = {0, 0, 0, 0, 0}; int deck_n = 0; while (true) { // random sort the cards deck_n = this->getRandom(1, 5, deck_n); if (not_again[deck_n - 1] == 0) { if (1 == deck_n && !this->deck_1.empty()) { // add to real deck this->mixed.push(this->deck_1.top()); if (this->debug) { debug_deck.push_back(this->deck_1.top()); } // remove from tem deck this->deck_1.pop(); } else if (2 == deck_n && !this->deck_2.empty()) { // add to real deck this->mixed.push(this->deck_2.top()); if (this->debug) { debug_deck.push_back(this->deck_2.top()); } // remove from tem deck this->deck_2.pop(); } else if (3 == deck_n && !this->deck_3.empty()) { // add to real deck this->mixed.push(this->deck_3.top()); if (this->debug) { debug_deck.push_back(this->deck_3.top()); } // remove from tem deck this->deck_3.pop(); } else if (4 == deck_n && !this->deck_4.empty()) { // add to real deck this->mixed.push(this->deck_4.top()); if (this->debug) { debug_deck.push_back(this->deck_4.top()); } // remove from tem deck this->deck_4.pop(); } else if (5 == deck_n && !this->deck_5.empty()) { // add to real deck this->mixed.push(this->deck_5.top()); if (this->debug) { debug_deck.push_back(this->deck_5.top()); } // remove from tem deck this->deck_5.pop(); } else { not_again[deck_n - 1] = 1; } } else { // check we still have a zero bool exists = std::find(begin(not_again), end(not_again), 0) != end(not_again); // if no 0 exists then we are done if (!exists) { break; } } } // if debug mode we check the shuffle if (this->debug) { // this is the current deck cout << __LINE__ << " This is the current deck" << endl; // setup the reverse map for(double i : debug_deck) cout << i << " = " << this->deck_specifics_b[i] << endl; } } /** * A Basic Random */ int getRandom(int min, int max, int n) { random_device rd; mt19937 g(rd()); uniform_int_distribution my_random(min, max); // get random but make sure // it is not the same as n int r = my_random(g); while (r == n) { r = my_random(g); } return r; } /** * get the card rank key */ int getRankKey(string key) { // the iterator search map::iterator found = this->deck_ranks_a.find(key); // check if it is found if (found != this->deck_ranks_a.end()) { // show values in debugging if (this->debug){ cout << __LINE__ << " getRankKey [" << key << "] => " << found->second << endl; } // element found; return found->second; } // show values in debugging if (this->debug){ cout << __LINE__ << " getRankKey [" << key << "] => not found" << endl; } // element not found return 0; } /** * 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K KEYS * H1, H2, H3 ,H4, H5, H6, H7, H8, H9, H10, HJ, HQ, HK 1 = Hearts * D1, D2, D3 ,D4, D5, D6, D7, D8, D9, D10, DJ, DQ, DK 2 = Diamonds * S1, S2, S3 ,S4, S5, S6, S7, S8, S9, S10, SJ, SQ, SK 3 = Spades * C1, C2, C3 ,C4, C5, C6, C7, C8, C9, C10, CJ, CQ, CK 4 = Clubs **/ void showSelection() { // show all SPECIFIC options if (this->mode == 2) { cout << "H1 = Ace of Hearts" << endl; cout << "H2 = Two of Hearts" << endl; cout << "H3 = Three of Hearts" << endl; cout << "H4 = Four of Hearts" << endl; cout << "H5 = Five of Hearts" << endl; cout << "H6 = Six of Hearts" << endl; cout << "H7 = Seven of Hearts" << endl; cout << "H8 = Eight of Hearts" << endl; cout << "H9 = Nine of Hearts" << endl; cout << "H10 = Ten of Hearts" << endl; cout << "HJ = Jack of Hearts" << endl; cout << "HQ = Queen of Hearts" << endl; cout << "HK = King of Hearts" << endl; cout << "D1 = Ace of Diamonds" << endl; cout << "D2 = Two of Diamonds" << endl; cout << "D3 = Tree of Diamonds" << endl; cout << "D4 = Four of Diamonds" << endl; cout << "D5 = Five of Diamonds" << endl; cout << "D6 = Six of Diamonds" << endl; cout << "D7 = Seven of Diamonds" << endl; cout << "D8 = Eight of Diamonds" << endl; cout << "D9 = Nine of Diamonds" << endl; cout << "D10 = Ten of Diamonds" << endl; cout << "DJ = Jack of Diamonds" << endl; cout << "DQ = Queen of Diamonds" << endl; cout << "DK = King of Diamonds" << endl; cout << "S1 = Ace of Spades" << endl; cout << "S2 = Two of Spades" << endl; cout << "S3 = Tree of Spades" << endl; cout << "S4 = Four of Spades" << endl; cout << "S5 = Five of Spades" << endl; cout << "S6 = Six of Spades" << endl; cout << "S7 = Seven of Spades" << endl; cout << "S8 = Eight of Spades" << endl; cout << "S9 = Nine of Spades" << endl; cout << "S10 = Ten of Spades" << endl; cout << "SJ = Jack of Spades" << endl; cout << "SQ = Queen of Spades" << endl; cout << "SK = King of Spades" << endl; cout << "C1 = Ace of Clubs" << endl; cout << "C2 = Two of Clubs" << endl; cout << "C3 = Tree of Clubs" << endl; cout << "C4 = Four of Clubs" << endl; cout << "C5 = Five of Clubs" << endl; cout << "C6 = Six of Clubs" << endl; cout << "C7 = Seven of Clubs" << endl; cout << "C8 = Eight of Clubs" << endl; cout << "C9 = Nine of Clubs" << endl; cout << "C10 = Ten of Clubs" << endl; cout << "CJ = Jack of Clubs" << endl; cout << "CQ = Queen of Clubs" << endl; cout << "CK = King of Clubs" << endl; } else { // show all RANK options cout << "1 = Ace" << endl; cout << "2 = Two" << endl; cout << "3 = Three" << endl; cout << "4 = Four" << endl; cout << "5 = Five" << endl; cout << "6 = Six" << endl; cout << "7 = Seven" << endl; cout << "8 = Eight" << endl; cout << "9 = Nine" << endl; cout << "10 = Ten" << endl; cout << "J = Jack" << endl; cout << "Q = Queen" << endl; cout << "K = King " << endl; } } }; class hand : public cardDB { protected: // the deck in each and bool cards[13][4] = {}; // when cards are lose vector lose; // the setter bool set(double card, bool state) { int rank, shape; rank = (int) card; shape = (int) (card * 10000); shape = (shape - (rank * 10000)) / 1000; // show values in debugging if (this->debug){ cout << __LINE__ << " set [" << card << "] R=" << rank << " S=" << shape << " state=" << state << endl; } // set the state return this->set(rank, shape, state); } bool set(int rank, int shape, bool state) { // now set the card state this->cards[rank][shape] = state; // show values in debugging if (this->debug){ cout << __LINE__ << " set R=" << rank << " S=" << shape << " state=" << state << endl; } // always true :) return true; } // remove the cards locally bool remove(double card, bool found = false) { // check if this card is in the deck if (found || this->searchDeck(card)) { // show values in debugging if (this->debug){ cout << __LINE__ << " removed=" << card << endl; } // was removed so true return this->set(card, false); } // show values in debugging if (this->debug){ cout << __LINE__ << " not removed=" << card << endl; } // was not removed return false; } // remove the card locally (may not be needed) bool remove(string card, bool found = false) { // check if this card is in the deck if (found || this->searchDeck(card)) { // get the double double d_card = this->get(card); // show values in debugging if (this->debug){ cout << __LINE__ << " removed=[" << d_card << "]=" << card << endl; } // was removed so true return this->set(d_card, false); } // show values in debugging if (this->debug){ cout << __LINE__ << " not removed=" << card << endl; } // was not removed return false; } // remove the cards locally (may not be needed) bool remove(int rank) { // show values in debugging if (this->debug){ cout << __LINE__ << " removed=" << rank << endl; } // there can only be four ranks for (int shape = 1; shape < 5; shape++) { this->set(rank, shape, false); } // aways true return true; } // the getter bool has(int rank, int shape) { // show values in debugging if (this->debug){ cout << __LINE__ << " has R=" << rank << " S=" << shape << " answer=" << this->cards[rank][shape] << endl; } // now add the card return this->cards[rank][shape]; } // the getter RANK bool has(int rank, bool give) { bool found = false; for (int s = 1; s < 5; s++) { if (this->cards[rank][s]) { double r = this->getDoubleKey(rank, s); // show values in debugging if (this->debug && give){ cout << __LINE__ << " has & give R=" << rank << " S=" << s << " answer=1" << " [" << r << "]" << endl; } else if (this->debug){ cout << __LINE__ << " has R=" << rank << " S=" << s << " answer=1" << " [" << r << "]" << endl; } // give value to another player if (give) { this->lose.push_back(r); } found = true; } } // now add the card return found; } public: // show players hand void showHand() { bool none = true; for (int r = 1; r < 14; r++) { for (int s = 1; s < 5; s++) { if (this->cards[r][s]) { // get the key double card = this->getDoubleKey(r, s); // show this card cout << this->deck_specifics_b[card] << ") " << this->deck_display[this->deck_specifics_b[card]] << endl; none = false; } } } // give empty hand message if no cards found if (none) { cout << "Your hand is empty :)" << endl; } } // set the cards locally bool add(int card) { // check if this card is in the deck if (this->searchDeck(card)) { // show values in debugging if (this->debug){ cout << __LINE__ << " add " << card << endl; } // was set so true return this->set(card, true); } // show values in debugging if (this->debug){ cout << __LINE__ << " did not add " << card << endl; } // was not set return false; } // set the cards locally bool add(double card) { // check if this card is in the deck if (this->searchDeck(card)) { // show values in debugging if (this->debug){ cout << __LINE__ << " add " << card << endl; } // was set so true return this->set(card, true); } // show values in debugging if (this->debug){ cout << __LINE__ << " did not add " << card << endl; } // was not set return false; } // set the cards locally (may not be needed) bool add(string card) { // check if this card is in the deck if (this->searchDeck(card)) { // get the double double d_card = this->get(card); // show values in debugging if (this->debug){ cout << __LINE__ << " add [" << d_card << "] " << card << endl; } // was set so true return this->set(d_card, true); } // show values in debugging if (this->debug){ cout << __LINE__ << " did not add " << card << endl; } // was not set return false; } // set the cards locally bool hasCard(double card, bool give) { // always rest the lose this->lose.clear(); // show values in debugging if (this->debug){ cout << __LINE__ << " we clear the lose vector" << endl; } // check if this card is in the deck if (this->searchDeck(card)) { int rank, shape; rank = (int) card; shape = (int) (card * 10000); shape = (shape - (rank * 10000)) / 1000; // show values in debugging if (this->debug){ cout << __LINE__ << " has card [" << card << "]" << " R=" << rank << " S=" << shape << endl; } // check if we must remove it at the same time if (give) { // get the card if (this->has(rank, shape)) { // remove since it is found return this->remove(card, true); } // not found return false; } // return if the card is found return this->has(rank, shape); } // not a card return false; } // set the card RANK locally bool hasCard(int card, bool give) { // always rest the lose this->lose.clear(); // check if this card is in the deck if (card > 0 && card < 14) { // show values in debugging if (this->debug){ cout << __LINE__ << " has card [" << card << "]" << endl; } // check if we must remove it at the same time if (give) { // get the card if (this->has(card, give)) { // remove since it is found for (double c : this->lose) { // show values in debugging if (this->debug) { cout << __LINE__ << " lose [" << c << "]" << endl; } this->remove(c, true); } return true; } // not found return false; } // return if the card is found return this->has(card, give); } // not a card return false; } // set the cards locally (may not be needed) bool hasCard(string card, bool give) { // always rest the lose this->lose.clear(); // check if this card is in the deck if (this->searchDeck(card)) { // get the double double d_card = this->get(card); int rank, shape; rank = (int) d_card; shape = (int) (d_card * 10000); shape = (shape - (rank * 10000)) / 1000; // show values in debugging if (this->debug){ cout << __LINE__ << " has card [" << card << "=" << d_card << "]" << " R=" << rank << " S=" << shape << endl; } // check if we must remove it at the same time if (give) { // get the card if (this->has(rank, shape)) { // remove since it is found return this->remove(d_card); } // not found return false; } // return if the card is found return this->has(rank, shape); } // not a card return false; } // get your loses to those asking RANK vector getWinnings() { return this->lose; } // ask for a card bool askCard(int card, hand &AHand) { // show values in debugging if (this->debug){ cout << __LINE__ << " ask [" << card << "]" << endl; } if (card > 0 && AHand.hasCard(card, true)) { vector winnings = AHand.getWinnings(); for (double c : winnings) { // show values in debugging if (this->debug) { cout << __LINE__ << " winning [" << c << "]" << endl; } if (!this->add(c)){ if (this->debug){ cout << __LINE__ << " winning ERROR->[" << c << "]" << endl; } // break on error return false; } } // cards were found return true; } // cards were not found return false; } // ask for a card bool askCard(double card, hand &AHand) { // show values in debugging if (this->debug){ cout << __LINE__ << " ask [" << card << "]" << endl; } if (AHand.hasCard(card, true)) { // show values in debugging if (this->debug) { cout << __LINE__ << " before add [" << card << "]" << endl; } // cards were found return this->add(card); } // cards were not found return false; } // ask for a card bool askCard(string card, hand &AHand) { return this->askCard(this->get(card), AHand); } }; class game : public deck { protected: // game status bool status; // number of payers int players; // deceit in mode = 2 (can ask for a card you already have in your hand, or not) bool deceit; // allow empty deck bool empty_deck; // player hands map hands; // opening setup void setupBoard() { // for quick testing //this->players = 2; //this->mode = 1; //this->empty_deck = false; //return; // string to get answers string tmp; // ask the opening questions while (true) { cout << "How many players will play?" << endl; cout << "[2-6]: "; cin >> this->players; if (this->players > 1 && this->players < 7) { break; } cin.clear(); cin.ignore(); cout << "Must be between 2 and 6 players." << endl; } // get the game mode while (true) { cout << "Will players be asking per [R]ank or for [S]pecific cards?" << endl; cout << "(r/s): "; cin >> tmp; if (tmp == "r" || tmp == "R" || tmp == "Rank" || tmp == "rank") { this->mode = 1; break; } else if (tmp == "s" || tmp == "S" || tmp == "Specific" || tmp == "specific") { this->mode = 2; break; } cin.clear(); cin.ignore(); cout << "Lets try again, please answer only r or s" << endl; } // only allow deceit when in specific this->mode if (this->mode == 2) { while (true) { cout << "Will players be allowed to ask for cards they have?" << endl; cout << "(y/n): "; cin >> tmp; if (tmp == "y" || tmp == "Y" || tmp == "yes" || tmp == "Yes") { this->deceit = true; break; } else if (tmp == "n" || tmp == "N" || tmp == "no" || tmp == "No") { this->deceit = false; break; } cin.clear(); cin.ignore(); cout << "Lets try again, please answer only y or n" << endl; } } // check if empty deck is allowed while (true) { cout << "Will the game continue if the deck is empty?" << endl; cout << "(y/n): "; cin >> tmp; if (tmp == "y" || tmp == "Y" || tmp == "yes" || tmp == "Yes") { this->empty_deck = true; break; } else if (tmp == "n" || tmp == "N" || tmp == "no" || tmp == "No") { this->empty_deck = false; break; } cin.clear(); cin.ignore(); cout << "Lets try again, please answer only y or n" << endl; } } // deal the cards void dealCards() { // deal cards int number = 6; if (this->players == 2) { number = 7; } int p = 1; while (p <= this->players) { // load only the number of cards allowed for (int card = 1; card <= number; ++card) { this->hands[p].add(this->mixed.top()); this->mixed.pop(); } // set player p++; } } // get a card (go fish) double getCard(int player) { // check if we still have cards if (!this->mixed.empty()) { // get the next card from the stack double card = this->mixed.top(); this->mixed.pop(); // add to player this->hands[player].add(card); // return the card return card; } return 0; } public: game() { // game has started status = true; // do opening setup this->setupBoard(); // deal the cards this->dealCards(); } // play the game void startGame() { // we start with a random player int p = this->getRandom(1, this->players, 0); // get new player bool get_new_player = false; // show whole key set string yes; cout << "Before we start, here is the list of all the keys of each card." << endl; this->showSelection(); while (true) { if (this->mode == 1) { cout << "So J is the key for all Jacks" << endl; } else { cout << "So H1 is the key for Ace of Hearts" << endl; } cout << "Player [" << p << "] are you ready to continue?" << endl; cout << "(y/n): "; cin >> yes; if (yes == "y" || yes == "Y" || yes == "yes" || yes == "Yes") { break; } cin.clear(); cin.ignore(); } // check if we still have cards while (status) { // check if we must get the next player if (get_new_player) { // get the next player p = p + 1; // if the player is beyond the list (start at player one) if (p > this->players) { p = 1; } // little pause to setup the new player while (true) { cout << "Player [" << p << "] are you ready to continue?" << endl; cout << "(y/n): "; cin >> yes; if (yes == "y" || yes == "Y" || yes == "yes" || yes == "Yes") { break; } cin.clear(); cin.ignore(); } // reset getting new player get_new_player = false; } // asking temp INT/string int tmp; // asking who is the next player int ask; // last player int l = this->players; // first player int f = 1; // ask for the next player bool ask_next = true; if (this->players > 2) { // if the player is the first, then move to 2 if (p == 1) { f = 2; } // if the last is the player, that a step back if (l == p) { l = this->players - 1; } } else { // do not ask for the next player ask_next = false; // just ask the next player ask = 1; if (p == 1) { ask = 2; } } // check if we should ask for next player if (ask_next) { cout << "We will show your hand in a moment." << endl; while (true) { cout << "Please select a player you would like to ask between:" << endl; cout << "[" << f << " - " << l << "] "; cin >> tmp; if (tmp >= f && tmp <= l && tmp != p) { ask = tmp; break; } cin.clear(); cin.ignore(); cout << "Lets try again, you are player [" << p << "]" << endl; } } // get the card to ask for string card; while (true) { cout << "This is your current hand:" << endl; this->hands[p].showHand(); cout << "What card do you want to ask for?" << endl; cin >> card; // make string uppercase transform(card.begin(), card.end(), card.begin(), ::toupper); if (this->searchDeck(card)) { break; } cin.clear(); cin.ignore(); cout << "Lets try again" << endl; } // make sure to get INT if RANK mode bool found_card = false; if (this->mode == 1) { found_card = this->hands[p].askCard(this->getRankKey(card), this->hands[ask]); } else { found_card = this->hands[p].askCard(card, this->hands[ask]); } // now lets ask if (found_card) { cout << endl; // load cards of RANK if (this->mode == 2) { cout << " Yes! Player [" << ask << "] had the card!" << endl; } else { cout << " Yes! Player [" << ask << "] had the card/s!" << endl; } cout << " YOU GET TO GO AGAIN :)" << endl; cout << endl; cout << endl; } else { cout << "Go fish................................" << endl; // load the card from the deck and add to player double c = this->getCard(p); // we must check if we found what we where looking for if (c > 0) { if (this->mode == 2 && c == this->get(card)) { cout << endl; cout << " Wow you got the card you were looking for!" << endl; cout << " OU GET TO GO AGAIN :)" << endl; cout << endl; cout << endl; } else { cout << "The new card was added to your hand...." << endl; // player questions cout << "Player [" << p << "] your turn is over." << endl; cout << endl << endl << endl << endl << endl << endl; cout << endl << endl << endl << endl << endl << endl; cout << endl << endl << endl << endl << endl << endl; get_new_player = true; } } else { // check if we allow empty decks if (!this->empty_deck) { // deck is empty so stop the game status = false; } } } } } }; int main() { // get the game game *Game = new game(); // start game Game->startGame(); // clear memory delete(Game); return 0; }