Search code examples
c++infinite-loopvisual-studio-debuggingvisual-studio-2013playing-cards

No output in program?


I am making a program to shuffle a deck of cards and deal out two hands, but right now, there is no output! I combed through the code for infinite loops, but I can't find anything! Can someone please help me?

// (Description in Word File)
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;

unsigned seed = time(0); // for use of rand()

const int SUIT = 4;
const int FACE = 13;
const int HAND = 5;

// A couple of reference arrays.
const string SUITS[SUIT] = {" Hearts", " Diamonds", " Clubs", " Spades"};
const string FACES[FACE] = {"Ace of", "Two of", "Three of",
                            "Four of", "Five of", "Six of", "Seven of",
                            "Eight of", "Nine of", "Ten of",
                            "Jack of", "Queen of", "King of"};

// The reason that these functions are in Main is because
// it gives me error 2065: undeclared identifier otherwise.
void shuffle(string[][FACE]);
void deal(string[][FACE], string[HAND]);
void displayDeck(string[][FACE]);
void displayHand(string[HAND]);

int main()
{
    string deck[SUIT][FACE];
    string hand1[HAND];
    string hand2[HAND];

    srand(seed); // for use of rand()

    // Shuffle the deck.
    shuffle(deck);

        // Now display the deck
    displayDeck(deck);

    // Deal for each hand.
    deal(deck, hand1);
    deal(deck, hand2);

    // Now display each hand.
    displayHand(hand1);
    displayHand(hand2);

    return 0;
}

// This function will keep track of face values
// for the shuffle function
bool duplCheck(string cards[][FACE], int suit, int face)
{
    bool status = true;
    for (int count1 = 0; count1 != SUIT; count1++)
        for (int count2 = 0; count2 != FACE; count2++)
            if (cards[count1][count2] == cards[suit][face]
                && suit != count1 && face != count2)
                return false;
    return status;
}

// This function will shuffle the deck.
void shuffle(string cards[][FACE])
{
    int randFace, randSuit;
    // These loops will assign random face values
    // and suits to each place in cards[][].
    for (int count1 = 0; count1 != SUIT; count1++)
        for (int count2 = 0; count2 != FACE; count2++)  
        {
            do
            {
                randFace = rand() % FACE;
                randSuit = rand() % SUIT;
                if (duplCheck(cards, randSuit, randFace) == true)
                    cards[count1][count2] = 
                        FACES[randFace] + SUITS[randSuit];
            } while(duplCheck(cards, randSuit, randFace) == false);
        }
}

// This function deals out a hand of five random cards.
void deal(string cards[][FACE], string hand[HAND])
{
    for (int count = 0; count != HAND; count++)
    {
        // make random suit and face numbers
        int randSuit = rand() % SUIT;
        int randFace = rand() % FACE;

        // If random card is not obsolete...
        if (cards[randSuit][randFace] != "null")
            // ...assign that card to hand.
            hand[count] = cards[randSuit][randFace];

        // obsolete that card
        cards[randSuit][randFace] = "null";
    }
}

void displayDeck(string cards[][FACE])
{
    std::cout << "\t\tThe Deck:\n\n";
    for (int count1 = 0; count1 != SUIT; count1++)
        for (int count2 = 0; count2 != FACE; count2++)
        {
            std::cout << ((count1 * FACE) + count2 + 1) << " "
                << cards[count1][count2] << endl;
        }
}

void displayHand(string hand[HAND])
{

}

Solution

  • Your problem is in shuffle, specifically in the use of duplCheck.

    void shuffle(string cards[][FACE])
    {
        int randFace, randSuit;
        // These loops will assign random face values
        // and suits to each place in cards[][].
        for (int count1 = 0; count1 != SUIT; count1++)
            for (int count2 = 0; count2 != FACE; count2++)  
            {
                do
                {
                    randFace = rand() % FACE;
                    randSuit = rand() % SUIT;
                    std::cout << count1 << "," << count2 << " trying " << randFace << "/" << randSuit << std::endl;
                    if (duplCheck(cards, randSuit, randFace) == true) {
                        std::cout << "duplCheck returned true" << std::endl;
                        cards[count1][count2] = 
                            FACES[randFace] + SUITS[randSuit];
                    }
                } while(duplCheck(cards, randSuit, randFace) == false);
            }
    }
    

    I've added some extra output. This demonstrates (http://ideone.com/BkZKD9) that duplCheck isn't returning false the first time you run it.

    do
    {
        randFace = rand() % FACE;
        randSuit = rand() % SUIT;
        if (duplCheck(cards, randSuit, randFace) == true) {
                   ... this doesn't happen
        }
    } while(duplCheck(cards, randSuit, randFace) == false);
    

    Because duplCheck returns false, you stay permanently in this loop.

    bool duplCheck(string cards[][FACE], int suit, int face)
    {
        bool status = true;
        for (int count1 = 0; count1 != SUIT; count1++)
            for (int count2 = 0; count2 != FACE; count2++)
                if (cards[count1][count2] == cards[suit][face]
                    && suit != count1 && face != count2)
                    return false;
        return status;
    }
    

    It appears that duplCheck returns "false" if there is a duplicate and "true" if there isn't, but your use of it expects the opposite: your while loop stops when duplCheck returns true, it expects duplCheck to return true if there IS a duplicate.