【问题标题】:Is there an elegant way to deal with the Ace in Blackjack?有没有一种优雅的方式来处理二十一点中的王牌?
【发布时间】:2010-10-24 16:32:38
【问题描述】:

我的孩子有一个家庭作业是用 Java 编写 Blackjack。我帮助了他一点,但大部分都是他自己做的,而且实际上打得很好。他甚至在计算手牌价值时发现了一个我没有看到的错误。然而,有一个他没有处理过的问题,而且我能想到的每一个解决方案都非常复杂,而且远远超出了他能够用他仍然初级的 Java 技能轻松编写代码的能力。

王牌。事实上,不仅仅是一张 A,还有四张 A,你可以在一手牌中拿到全部四张。当有一个或多个 A 时,你如何优雅地计算一手牌的价值,每个 A 的价值可能是 1 或 11。我觉得应该有一个优雅的算法,但我没有看到它。当然,部分原因可能是我累了,但也许你可以帮忙。

【问题讨论】:

    标签: java blackjack


    【解决方案1】:

    只需将每个 ace 视为 11。然后当值超过 21 时,从手中的每个 ace 中减去 10。

    【讨论】:

    • 漂亮而优雅,除了必须多次查看卡片。 +1
    • 您不必多次查看。只需在您第一次看时记下 A。
    • 令人惊讶的是,错误的答案如何被投票到顶部。正如随后的正确答案所指出的那样,只有一个 ace 被计为 11,因此将每个 ace 简单地计为 1 会更有效,然后,如果您找到一个 ace,并且总数
    【解决方案2】:

    您将只能使用 1 个 ace 来获得 11 分。因此,除最后一个 ace 以外的所有点都计算为 1,如果点数为 10 或更少,则最后一个 ace 计为 10。

    【讨论】:

    • 想象一个从 ace-2 开始的玩家。他们击中获得和王牌,再次击中获得和王牌,再次击中获得和王牌。即使只有一个甲板,他们也有四个!使用多层鞋可能会更糟。根据需要进行计数和折扣...
    【解决方案3】:

    只有 1 个 Ace 才算作 11。

    因此,将每个 Ace 视为 11 的另一种方法是将每个 Ace 视为 1。 然后将 10 加到总值中(无论手头有多少 Ace 都进行)并将其保存在一个单独的“高”变量中(值 + 10)。如果(任何)ace 出现,也创建一个布尔值 ~ ace:true。

    因此,在与庄家核对分数时;检查玩家的手牌是否有(任何)A,在这种情况下,您(可以)使用“高”值,否则(没有 A)使用“低”值。

    这样,King + 9 + Ace(可能是坏例子)将是 ~ 低:20 & 高:30 & ace:true - 有了这些信息,您可以检查 30 - 10 是否会“赢得比赛”。 所以,King + 5 + 5 ( low:20 high:30 ace:false ) 不会使用它的高值 30。

    我正在使用这种方法,所以我知道何时显示 alt。屏幕上的王牌分数;像 3/13 ( Ace + 2 ),使用我已经拥有的相同 ace:true|false 布尔值。这肯定与第一个给出的答案相同,但这对我来说更有意义:)

    【讨论】:

      【解决方案4】:

      不管每张 ace 应该算作 11 的总和值,然后当总和达到 21 时,从手上减去 10,但问题是你必须确保记下你减去 10 的次数以及你加了多少次 11(一个 ace),

      加 11 >= 减 10 -必须始终满足

      算法示例:

      int sum=0;
      int ace=0;
      int subtract=0;
      while(!busted or !stay)
      {
        Hitme(value);
        if(value=11)ace++;
        sum+=value;
        if(sum>21) 
        {
            if(ace>=1)
            {
               if(ace>=subtract)
               {
                 sum-=10
                 subtract++;
               }
               else
               {
                  busted;
               }
            }
            else
            {
                busted;
            }
        }
        else
        {
          hit or stay;
          //of course if sum== 21 then force stay
      
        }
      }
      

      【讨论】:

        【解决方案5】:

        类似于 elundmark 的回答...

        您很可能已经获得了一种评估二十一点手牌价值的方法。始终在某一时刻重视 A。如果一手牌中有一张 A,则计算一个硬值(所有 A 都是 1,+10)和一个软值(所有 A 都是)。

        如果硬值不是半身像,则返回硬值。如果硬值是半身像,则返回软值。

        示例 1
        2、A、A
        硬值 2 + 1 + 1 + 10 = 14
        软值 = 2 + 1 + 1 = 4

        hard value

        示例 2
        2、A、A、8
        硬值 = 2 + 1 + 1 + 8 + 10 = 22(胸围)
        软值 = 2 + 1 + 1 + 8 = 12

        硬值> 21,所以返回软值(手值是12)

        对规则和游戏方式的传统思考是,A 的值是有条件的,可以有两个值,1 或 11。这个概念很难实现。对于程序员来说,将所有 A 计为 1 并有条件地在手牌值上加 10 点要容易得多。这样,您的卡的等级或价值实施可以保持僵化和直接。我之前通过返回一组值和其他几种方法对此进行了试验。这是一种痛苦,不值得仅仅为了一个 Ace 等级。

        如果您想在屏幕上显示 2/12 之类的 alt,而不是返回 Integer,只需返回一个“BlackjackValue”对象,其中包含一个 Integer 和一个 String 对象,您在评估手牌值的方法中创建该对象.

        【讨论】:

          【解决方案6】:
          short aces_count = 0;
          short non_aces_sum = 0;
          short global_sum = 0;
          
          foreach card in _card:{
              if( card.value != 11 ){ // assuming ace value is 11
                  if( card.value > 10 ) 
                      non_aces_sum += 10;
                  else
                      non_aces_sum += card.value
              }else
                  aces_count += 1;
          }
          
          short aces_sum = 0;
          if( aces_count > 0) aces_sum = 11;
          
          for(int i=0 ; i < aces_count - 1; i++){ // - 1 cuz already asigned first ace
              aces_sum += 1; // 2x aces == 22 so max 1 ace has value 11
          }
          if(aces_sum + non_aces_sum > 21)
              aces_sum = aces_count; // no need for an 11 value ace, so all are 1
          
          global_sum = non_aces_sum + aces_sum;
          

          【讨论】:

            【解决方案7】:

            问题在于它不是确定的:您可以(根据我理解的规则)将一张 A 计为 1 或 11。但您知道您不会每次都将其计为 11,因为您会破产.

            我认为唯一的解决方案是计算总和

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-09-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多