eMRe
eMRe

Reputation: 3247

How to calculate the score for Blackjack game? Where am I going wrong?

My calculation is not working properly. I can not see anything wrong with the code. Sometimes it does not calculate the score properly. Sometimes it does perfectly. I can not even understand when it does properly and when it does not do it properly.

Score calculation should be like this:

Ace can add to the total score either 1 or 11. If the score is higher than 21, then ace is calculated as 1; otherwise ace is 11.

Here is my code:

  // Updates the the value of the cards the player has in their hand
  int updateValueOfHand() {
    int result = 0;                             // it will be returned
    int ace = 0;                                // value of ace

    for (int i =0; i < playerHand.size(); i++)  // loop to see players hand
    {
      int cardValue;                            // card value of hand
      Card card=(Card)playerHand.get(i);        // check the card
      cardValue = card.getRank();
      if (cardValue == 1)                       // if card value is 1 (ace)
      {
        cardValue = 0;                         // assign to 0
        ace += 1;                              // ace is 1 (if there are 2 aces ace is 2 ...)
      }
      result = result + cardValue;             // result is card value (no ace)
    }
    //return result;
    println("Number of ace: " + ace);
    if (ace!=0)                                //if there is ace
    {
      for (int j=0; j<ace; j++)                // if there is more than 1 ace
      {
        if (result+11<=21) {                   // if result is <= 21 when you count ace as 11, then ace is 11
          result+=11;
        }        
        else {
          result+=1;                          // otherwise ace is 1
        }        
      }
    }
    return result;
  }

enter image description here

Upvotes: 1

Views: 6489

Answers (5)

Ghandhikus
Ghandhikus

Reputation: 841

Here's my attempt

public int handScore(Hand hand)
{
    int score = 0;
    int aceCount = 0;
    for (Card card : hand.getCards())
    {
        switch (Card.RANK_SYMBOLS[card.getRank()])
        {
            case "2": score += 2; break; 
            case "3": score += 3; break;
            case "4": score += 4; break;
            case "5": score += 5; break;
            case "6": score += 6; break;
            case "7": score += 7; break;
            case "8": score += 8; break;
            case "9": score += 9; break;
            case "10":
            case "j":
            case "q":
            case "k": score += 10; break;
            case "a": score += 11; aceCount++; break;
        }

        while(score>21 && (aceCount-->=0))
            score -= 10;

    }
    return score; 
}

Upvotes: 2

tgwaste
tgwaste

Reputation: 439

For me the best way to do this is to get 2 totals:

  • The total of the hand (considering 11 for ace)
  • The total number of aces in the hand.

Then if hand_total > 21 subtract 10 from the hand_total for every ace until <= 21
An ace should always be counted as 11 unless it NEEDS to be 1 to prevent a bust.

Upvotes: 2

CaptainJanuary
CaptainJanuary

Reputation: 61

Here's .NET code I'm using, where Hand is a specialized collection of my Cards... anyways, you still get the basic idea and should be able to easily convert syntax and naming-conventions to Java.

protected int EvaluateHand(Hand hand)
    {
        int score = 0;
        foreach (Card currentCard in hand)
        {
            switch (currentCard.Value)
            {
                case Value.Two:
                    score += 2;
                    break; 
                case Value.Three:
                    score += 3;
                    break;
                case Value.Four:
                    score += 4;
                    break;
                case Value.Five:
                    score += 5;
                    break;
                case Value.Six:
                    score += 6;
                    break;
                case Value.Seven:
                    score += 7;
                    break;
                case Value.Eight:
                    score += 8;
                    break;
                case Value.Nine:
                    score += 9;
                    break;
                case Value.Ten:
                case Value.Jack:
                case Value.Queen:
                case Value.King:
                    score += 10;
                    break;
                case Value.Ace:
                    score += 11;
                    break; 

            }

        }

        // after evaluating with 11 for each ace, if score has busted, then change each ace value from 11 to 1
        if (score > 21)
        {   // if our evaluated score is over 21, subtract 10 foreach ace in the hand. 
            foreach (Card currentAceCheckCard in hand)
            {
                if (score <= 21)
                {   // if we've subtracted enough until we're not busted, then break and return value
                    break;
                }
                if (currentAceCheckCard.Value == Value.Ace)
                {
                    score -= 10;
                }
            }
        }
        return score; 
    } 

Upvotes: 0

CaptainJanuary
CaptainJanuary

Reputation: 61

Is there an elegant way to deal with the Ace in Blackjack?

Just treat each ace as 11. If your value is over 21, go through and foreach ace in your hand, subtract 10 from your total until either your score is 21 or less or you've gone through each ace. This will be your final score.

Upvotes: 2

Joe Daley
Joe Daley

Reputation: 46476

Consider a hand with one King and two Aces. This should be calculated as 10 + 1 + 1, since otherwise it would be greater than 21.

However, the program loops through each Ace, and:

// if result is <= 21 when you count ace as 11, then ace is 11

Since the King plus the first Ace counted as 11 is <= 21, the program chooses to count the first Ace as 11, but this in incorrect.

Here is one idea to fix it: In your first for loop, increase result by 1 for every Ace, then in your second for loop, increase result by 10 for every Ace as long as it stays <= 21.

Upvotes: 6

Related Questions