Search code examples
c++objectvectorinfinite-loop

Why is my output freezing when it gets to this section of the code?


I'm trying to compare two decks of cards, yet every time I try another method of doing it, I get the same result... Everything before the code outputs, and it just freezes as soon as it hits the comparison code, as if it's stuck in an infinite loop.

I've tried for loops, static variables, do-while loops, etc. This is my first time leaving the loop at the client code.

The code that supposedly throws the program into an infinite loop.

    while (repeatLoop == false)
    {
        deck1.shuffleDeck();
        counter++;
        repeatLoop = deck1.compareDecks();
    }

compareDecks function.

bool deck::compareDecks()
{
    int deckCount = 0;

    suitType tempOriginalSuit;
    suitType tempShuffleSuit;

    rankType tempOriginalRank;
    rankType tempShuffleRank;

    while (index < 52)
    {
        tempOriginalSuit = originalCardDeck[index].getSuit();
        tempShuffleSuit = shuffledCardDeck[index].getSuit();

        if (int(tempOriginalSuit) == int(tempShuffleSuit))
        {
            tempOriginalRank = originalCardDeck[index].getRank();
            tempShuffleRank = shuffledCardDeck[index].getRank();

            if (int(tempOriginalRank) == int(tempShuffleRank))
            {
                deckCount++;

                if (deckCount == 52)
                    return true;
            }
        }
        else
        {
            return false;
            index++;
        }
    }
}

The shuffleDeck function (This function pushes back the first card from the first half of the deck and the first card from the second half of the deck towards the end until all 52 cards have been pushed in this pattern. This makes the deck have 52 x 2 cards (with the second half of the deck being the perfect shuffle), so I delete the first half of the cards using .erase as it is not needed)

void deck::shuffleDeck()
{
    for (int a = 0, b = 2; a < 2 && b < 4; a++, b++)
    {
        for (int i = 2; i < 15; i++)
        {
            shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(a),
                                             static_cast<cardSpace::rankType>(i) });

            shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(b),
                                             static_cast<cardSpace::rankType>(i) });
        }
    }

    shuffledCardDeck.erase(shuffledCardDeck.begin(), 
                           shuffledCardDeck.begin() + (shuffledCardDeck.size() / 2));
}

The two decks initialized by this constructor.

deck::deck()
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 2; j < 15; j++)
        {
            originalCardDeck.push_back(card{ static_cast<cardSpace::suitType>(i),
                                            static_cast<cardSpace::rankType>(j) });
            shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(i),
                                            static_cast<cardSpace::rankType>(j) });
        }
    }

}

Also note that I've done a perfect shuffle on the shuffledCardDeck vector in another function. I'm trying to repeat the perfectShuffle function until it reaches it's original state and output how many times it took to do this.

I get an infinite loop.

EDIT: I've decided to add the return false; statement in the compareDecks function into the if-else. Also, I think what's causing the problem is that my index i is reset to zero everytime it is called again. Are there any solutions you guys could propose to this? I've tried using static variables, but they just would not increment in the for loop.

EDIT 2: I enclosed my if statements within the curly braces, per users' request, as it's a flaw in my code.

EDIT 3: After commenting out

deck1.shuffleDeck()

The compareDecks function returned true, stating that the decks are equal, which isn't supposed to happen... This caused the loop to end after only one loop.


Solution

  • I was expecting you to actually shuffle the deck.

    Your code was pushing a specific, newly synthesized card onto the end of the deck:

               shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(a),
                                                static_cast<cardSpace::rankType>(i) });
    

    For example, the first card it will push is always the 2 of 0's (Whatever the 0th suit is). That's not what you want. You actually want to push a copy of the card that is at a specific position index in the deck. For example, loop index from 0 to 25 and then push shuffledCardDeck[index] and shuffledCardDeck[26 + index].

    Then you can still wrap up by using your technique of erasing the first half of the deck.

    void deck::shuffleDeck()
    {
        for (int index = 0; index < 26; ++index) {
            shuffledCardDeck.push_back(shuffledCardDeck[index]);
            shuffledCardDeck.push_back(shuffledCardDeck[26 + index]);
        }
    
        shuffledCardDeck.erase(shuffledCardDeck.begin(), 
                               shuffledCardDeck.begin() + 52);
    }