1

我的计算不能正常工作。我看不出代码有什么问题。有时它不能正确计算分数。有时它做得很完美。我什至无法理解它什么时候做得好,什么时候做得不好。

分数计算应该是这样的:

Ace 可以在总分上加 1 或 11。如果得分高于 21,则 ace 计算为 1;否则 ace 是 11。

这是我的代码:

  // 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;
  }

在此处输入图像描述

4

5 回答 5

6

考虑一手牌,一张K,两张A。这应该计算为 10 + 1 + 1,否则它将大于 21。

但是,程序会循环遍历每个 Ace,并且:

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

由于国王加上算作 11 的第一个 A 是 <= 21,因此程序选择将第一个 A 算作 11,但这是不正确的。

这里有一个解决方法:在你的第一个for循环中,result每个 Ace 增加 1,然后在第二个for循环中,result只要它保持 <= 21,每个 Ace 增加 10。

于 2012-12-24T05:20:59.553 回答
2

有没有一种优雅的方式来处理二十一点中的王牌?

只需将每个 ace 视为 11。如果您的值超过 21,则遍历并获得手中的 ace,从总分中减去 10,直到您的得分为 21 或更少,或者您已经通过了每个 ace。这将是你的最终分数。

于 2013-11-24T21:48:27.980 回答
2

对我来说,最好的方法是获得 2 个总数:

  • 手牌总数(考虑 11 为 A)
  • 手中的 A 总数。

然后,如果 hand_total > 21 从 hand_total 中减去 10,直到 <= 21 为止
,除非它需要为 1 以防止爆牌,否则应始终将 ace 计为 11。

于 2014-02-16T20:00:20.070 回答
2

这是我的尝试

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; 
}
于 2017-08-30T22:55:21.660 回答
0

这是我正在使用的 .NET 代码,其中 Hand 是我的卡片的专门集合...无论如何,您仍然了解基本概念,并且应该能够轻松地将语法和命名约定转换为 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; 
    } 
于 2013-11-24T22:00:26.840 回答