代码之家  ›  专栏  ›  技术社区  ›  John Munsch

有没有一种优雅的方法来对付21点游戏中的王牌?

  •  14
  • John Munsch  · 技术社区  · 17 年前

    我的孩子有一个家庭作业要用Java写21点。我帮了他一点忙,但在大部分情况下,他都是自己做的,而且打得很好。他甚至犯了一个我在计算手的价值时没有看到的错误。然而,有一个他还没有解决的问题,我能想到的每一个解决方案都非常复杂,远远超出了他将能够用他仍然基本的Java技能轻松编写代码的范围。

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

    7 回复  |  直到 17 年前
        1
  •  25
  •   Unknown    17 年前

        2
  •  9
  •   Milhous    17 年前

    你将只使用1张A获得11分。因此,将除最后一张ace外的所有ace计算为1,如果分数为10或更少,则最后一张ace计算为10。

        3
  •  5
  •   elundmark    16 年前

    只有1张A可以算作11张。

    因此,将每个Ace视为11的替代方法是将每个Ace视为1。 然后将总价值加上10(不管手头上有多少Ace),并将其保存在单独的“高”变量中(值+10)。如果出现(任何)ace,也要创建~ace:true的布尔值。

    因此,当检查经销商的分数时;检查玩家的手牌是否有王牌,在这种情况下,你可以使用“高”值,否则(没有王牌)使用“低”值。

    那样的话,King+9+Ace(也许是个糟糕的例子)将~低:20&高:30及;ace:是的-有了这些信息,你可以检查30-10是否会“赢得比赛”。 所以,国王+5+5(低:20高:30 ace:false)不会使用它的高值30。

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

        4
  •  3
  •   TStamper    17 年前

    不管每个a的总和是11,当总数超过21时,从手上减去10,但问题是你必须记下减去10的次数和加11的次数(a),

    我们必须始终感到满意

    alorithm示例:

    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
  •  2
  •   Cheese Daneish    13 年前

    与埃伦马克的答案相似。。。

    您很可能得到了一个计算21点手牌值的方法。始终在某一点上为A赋值。如果一只手包含一个ace,则计算一个硬值(所有ace都是1,+10)和一个软值(所有ace都是1)。

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

    例1
    2,A,A

    软值=2+1+1=4

    例2
    2,A,A,8

    软值=2+1+1+8=12

    硬价值>21,因此返回软值(手动值为12)

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

    如果希望在屏幕上显示alt(如2/12),而不是返回整数,只需返回一个“BlackjackValue”对象,该对象包含一个整数和一个字符串对象,该对象是您在计算手值的方法中创建的。

        6
  •  0
  •   Stoica Mircea    9 年前
    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
  •  -1
  •   TStamper    17 年前

    问题是它还没有确定:你可以将一张A(据我所知)算作1或11。但你知道你不会每次都把它算作11,因为你会破产的。