1

I made a blackjack game for my C++ course. I have a problem checking who won the game. During the game I check after each draw whether or not that person busted (exceeded 21 in total). If they did bust I store it in a variable. They are playerBust and dealerBust. They are initialized to 0.

The win-check is a standard if/else-if segment. It says that playerBust == 1 is always false, and that dealerBust == 0 is always true.

However, the last test of the game I logged both of these, and dealerBust = 1 by the end.

A few explanations of my code:

deck.newdeck gives me a new, shuffled deck.

initializeGame(); sets the player's and dealer's hand total to 0.

.toString() simply return a string naming a card, for instance "Ace of Spades".

getPlayerCardValue(...)and getDealerCardValue(...) just evaluates the numerical value of the card just drawn.

void Blackjack::playGame(){
deck.newDeck();
initializeGame();
drawInitialCards();
bool playerBust = 0;
bool dealerBust = 0;
Card newCard;

// PLAYERS TURN
if (playerHand > 21){
    playerBust = 1;
}
else if (playerHand < 21){
    bool stopDraw = 0;
    while (stopDraw == 0){
        bool playerDraw = askPlayerDrawCard();
        if (playerDraw == 1){
            newCard = deck.drawCard();
            cout << endl << "You drew: " << newCard.toString() << endl;
            playerHand += getPlayerCardValue(newCard);
            cout << "Player's total: " << playerHand << endl;
            if (playerHand > 21){
                playerBust = 1;
                stopDraw = 1;
            }
        }
        else if (playerDraw == 0){
            stopDraw = 1;
        }
    }
}

// DEALERS TURN
dealerHand += getDealerCardValue(dealerFaceDown, dealerHand);
cout << "Dealer's face down card is: " << dealerFaceDown.toString() << endl
<< "Dealer's total: " << dealerHand << endl;

if (dealerHand > 21){
    dealerBust = 1;
}
else if (dealerHand < 21){
    while (dealerHand < 17){
        newCard = deck.drawCard();
        cout << endl << newCard.toString() << endl;
        dealerHand += getDealerCardValue(newCard, dealerHand);
        cout << "Dealer's hand totals: " << dealerHand << endl;
        if (dealerHand > 21){
            dealerBust = 1;
        }
    }
}

// WINNING CONDITIONS
if (playerBust == 1 || dealerBust == 1){
    cout << "Tie" << endl;
}
else if (playerBust == 1 || dealerBust == 0){
    cout << "Dealer wins" << endl;
}
else if (playerBust == 0 || dealerBust == 1){
    cout << "Player wins" << endl;
}
else if (playerBust == 0 || dealerBust == 0){
    if (playerHand > dealerHand){
        cout << "Player wins" << endl;
    }
}
cout << endl << "Player's bust: " << playerBust << endl << "Dealer's bust: " << dealerBust << endl;
Cheezmeister
  • 4,895
  • 3
  • 31
  • 37
Auclair
  • 125
  • 1
  • 10
  • 3
    Have you tried just saying `dealerBust = true;` and checking with `if (dealerBust)`? – fuzzything44 Feb 22 '16 at 22:29
  • @fuzzything44 Huh, no I haven't. That never occurred to me. Is it bad practice to use `0`and `1` for boolean variables? – Auclair Feb 22 '16 at 22:31
  • 4
    @Auclair: `bool` is an actual data type in C++, and `true` and `false` are actual Boolean keywords. You should be using them in C++ code. It is not recommended to use integers for boolean values and comparisons. That is what people do in C instead, because C does not have a native boolean data type. Things like `if (playerDraw == 1) { ... } else if (playerDraw == 0) { ... }` should be `if (playerDraw) { ... } else { ... }` in C++. – Remy Lebeau Feb 22 '16 at 22:32
  • @RemyLebeau And even then it is a good idea to `#define true 1` to keep it constant. – Fantastic Mr Fox Feb 22 '16 at 22:33
  • Alright, thank you all. I'll immediately kill that habit. – Auclair Feb 22 '16 at 22:34
  • 3
    @Ben, you should **never** `#define true 1` in C. This is just terribly wrong, and can lead to much headache. Instead, `#define false 0 #define true !false`. – SergeyA Feb 22 '16 at 22:37
  • @Auclair I rolled back your edit. The question needs to contain the original error, so that future readers will understand what the problem was and how the answers solved it. – Barmar Feb 22 '16 at 22:47
  • @Barmar Yes of course, thank you. – Auclair Feb 22 '16 at 22:48
  • @SergeyA Why is this wrong? what does `!0` evaluate to? because after the pre-processor runs over this i suspect the result will be the same? http://ideone.com/r01AVS – Fantastic Mr Fox Feb 22 '16 at 22:49
  • 3
    @Ben _"Why is this wrong?"_ Because any value other than `0` will evaluate to `true`. – πάντα ῥεῖ Feb 22 '16 at 22:54
  • @πάνταῥεῖ Can you clarify that, in the online example i provided, i believe both interperations are exactly the same. It only matters once you cross into c++? – Fantastic Mr Fox Feb 22 '16 at 22:55
  • 2
    @SergeyA `1` and `!0` are identical, in C – M.M Feb 22 '16 at 22:58
  • Shouldn't `if (playerBust == 1 || dealerBust == 1)` be `if (playerBust == 1 && dealerBust == 1)`? It's a tie when *player AND dealer* bust. Your logic allows a tie if *either* player busts. – kfsone Feb 22 '16 at 22:58
  • @M.M A supporter! I dont see the difference! – Fantastic Mr Fox Feb 22 '16 at 22:58
  • 1
    @SergeyA Since C99 you should not define those tokens at all, since they are defined by a standard header. If you don't want to use the standard versions then perhaps use `TRUE` and `FALSE` to avoid conflicting definitions when someone who is not 25 years in the past does try and compile your code. (This is somewhat off-topic for a C++ question though!) – M.M Feb 22 '16 at 23:00
  • @kfsone Yes, that was the most embarrassing mistake. I fixed it though – Auclair Feb 22 '16 at 23:01
  • @M.M if you do not have them, than !0 doesn't ave to be 1. – SergeyA Feb 23 '16 at 01:42
  • @SergeyA actually `!0` it does have to be `1` in all versions of C. Look up the definition of the `!` operator. – M.M Feb 23 '16 at 01:52
  • @SergeyA I added a question to cover this here: http://stackoverflow.com/questions/35565740/define-true-false-vs-define-true-1 – Fantastic Mr Fox Feb 23 '16 at 02:32

2 Answers2

12

You are using logical or (||) where you actually want to use logical and (&&) instead.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Sebastian Hoffmann
  • 2,815
  • 1
  • 12
  • 22
2

Consider this:

if (playerBust == 1 || dealerBust == 1){
    cout << "Tie" << endl;
}
else if (playerBust == 1 || dealerBust == 0)

If the first branch is not taken then we know that playerBust is not true, and neither is dealerBust. So in the else if there's no point testing if playerBust is true (it can't be) or if dealerBust is false (it must be).

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64