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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/837951/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 13:58:37  来源:igfitidea点击:

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

javablackHyman

提问by John Munsch

My kiddo had a homework assignment to write BlackHyman in Java. I helped him a little but for the most part he did it all himself and it actually plays pretty well. He even caught an error I didn't see in how it was calculating hand values. However, there is a snag that he hasn't dealt with and every solution I can think of is really complicated and way beyond what he's going to be able to easily code up with his still rudimentary Java skills.

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

The Ace. In fact, not just one Ace, there's four of them and you could possibly get all four of them in a single hand. How do you elegantly deal with calculating the value of a hand of cards when there's one or more Aces, each of which might be valued at one or eleven. I feel like there should be a graceful algorithm for it, but I'm not seeing it. Of course, part of it could just be that I'm tired, but maybe you can help.

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

回答by Unknown

Just treat each ace as 11. Then while the value is over 21, subtract 10 from your total for each ace in your hand.

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

回答by Milhous

You will only ever use 1 ace for the 11 points. So calculate all but the last ace as 1 and if have 10 or less points, the last ace counts as 10.

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

回答by elundmark

Only 1 Ace ever counts as 11.

只有 1 Ace 算作 11。

So, an alternative method to treating each Ace as 11 would be to treat every Ace as 1. Then add 10 to the total value ( carried regardless of Ace on hand ) and keep that in a separate "high" variable ( value + 10 ). Also create a boolean of ~ ace:true if (any) ace comes up.

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

And so when checking the score against the dealer; check if the players' hand has (any) Ace, in which case you ( can ) use the "high" value, otherwise ( no Ace ) use the "low" value.

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

That way King + 9 + Ace ( bad example perhaps ) would be ~ low:20 & high:30 & ace:true - With that information you can check if 30 - 10 will "win the game". So, King + 5 + 5 ( low:20 high:30 ace:false ) will not use it's high value of 30.

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

I'm using this method so I know when to show an alt. Ace score onscreen; like 3/13 ( Ace + 2 ), using the same ace:true|false boolean I already have. This is surely the same answer as the first one given, but this makes more sense to me :)

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

回答by TStamper

No matter what every ace should be counted to sum value as 11, then when the total sum has reached over 21 subtract 10 from hand, but the thing is you must make sure you keep a count of how many times you subtract 10 and how many times you add 11( an ace),

不管每张 A 的总和值是 11,当总和超过 21 时,从手上减去 10,但问题是你必须确保你计算出你减去 10 的次数和多少你加11(一张A)的次数,

add 11 >= subtract 10 -must always be satisfied

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

alorithm example:

算法示例:

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

  }
}

回答by Cheese Daneish

Similar to elundmark's answer...

类似于 elundmark 的回答...

You've most likely got a method that evaluates a blackHyman hand value. Always value aces at one point. If a hand contains an ace, compute a hard value (all aces are ones, +10) and a soft value (all aces ones).

您很可能已经获得了一种评估 21 点牌值的方法。总是在一点上重视 A。如果手牌包含 A,则计算硬值(所有 A 都是 1,+10)和软值(所有 A 都是)。

If the hard value is not a bust, return the hard value. If the hard value is a bust, return the soft value.

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

example 1
2, A, A
hard value 2 + 1 + 1 + 10 = 14
soft value = 2 + 1 + 1 = 4

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

hard value < 21, so return hard value (hand value is 14)

硬值 < 21,所以返回硬值(手值为 14)

example 2
2, A, A, 8
hard value = 2 + 1 + 1 + 8 + 10 = 22 (bust)
soft value = 2 + 1 + 1 + 8 = 12

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

hard value > 21, so return soft value (hand value is 12)

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

Traditional thinking about the rules and the way the game is played, is that an Ace's value is conditional and can have two values, 1 or 11. This concept is difficult to implement. It's much easier on a programmer to count all Aces as a value of one and conditionally add 10 points to the hand value. That way your Card's Rank or Value implementation can remain rigid and straightforward. I've experimented with this before by returning a collection of values and a couple other methods. It's a pain, and not worth it for just the one Ace rank.

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

If you want to show an alt on the screen like 2/12, instead of returning an Integer, just return a "BlackHymanValue" object that contains an Integer and a String object that you create in the method that evaluates your hand value.

如果你想在屏幕上显示一个像 2/12 这样的 alt,而不是返回一个 Integer,只需返回一个“BlackHymanValue”对象,其中包含一个 Integer 和一个 String 对象,这些对象是你在评估你的手值的方法中创建的。

回答by Stoica Mircea

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;

回答by Charlie Martin

The problem is that it's not determined: you can count (as I understand the rules) an Ace as either 1 or 11. But you know you're not going to count it as 11 every time, because you'll bust.

问题是它没有确定:你可以(按照我的理解规则)把 A 算作 1 或 11。但你知道你不会每次都把它算作 11,因为你会破产。

The only solution I think is to compute the score for each possible value of the ace where the sum <= 21.

我认为唯一的解决方案是计算总和 <= 21 的 ace 的每个可能值的分数。