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

Java 有没有一种优雅的方法来对付21点游戏中的王牌?,java,blackjack,Java,Blackjack,我的孩子有一个家庭作业要用Java写21点。我帮了他一点忙,但在大部分情况下,他都是自己做的,而且打得很好。他甚至犯了一个我在计算手的价值时没有看到的错误。然而,有一个他还没有解决的问题,我能想到的每一个解决方案都非常复杂,远远超出了他将能够用他仍然基本的Java技能轻松编写代码的范围 王牌。事实上,不仅仅是一张王牌,还有四张王牌,你可以在一只手上拿到所有四张王牌。当有一张或多张a牌时,你如何优雅地计算一手牌的价值,每张a牌的价值可能是一张或十一张。我觉得应该有一个优雅的算法,但我没有看到。当然

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


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

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


我认为唯一的解决方案是计算ace每个可能值的分数,其中总和仅将每个ace视为11。然后,当数值超过21时,从你手中的每一张a的总数中减去10。

无论每一张a的总和应计为11,当总数超过21时,从手上减去10,但问题是你必须确保记下你减去10的次数和加11的次数(a),

加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

  }
}

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

只有1张A可以算作11张

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

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

这样,国王+9+王牌(可能是个坏例子)将~低:20&高:30&王牌:正确-根据这些信息,你可以检查30-10是否会“赢得比赛”。 所以,国王+5+5(低:20高:30 ace:false)不会使用它的高值30


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

类似于埃伦马克的答案

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

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

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

硬值<21,因此返回硬值(手动值为14)

例2
2,A,A,8
硬值=2+1+1+8+10=22(半身像)
软值=2+1+1+8=12

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

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

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

short aces\u count=0;
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;
短非A和=0; 短全局_和=0; 每一张卡在_卡中:{ 如果(card.value!=11){//假设ace值为11 如果(卡值>10) 非aces总和+=10; 其他的 非aces_总和+=卡值 }否则 aces_计数+=1; } 短A_和=0; 如果(aces_计数>0)aces_总和=11; 对于(inti=0;i21) aces_sum=aces_count;//不需要11值的ace,所以都是1 全局求和=非求和+求和;
漂亮、优雅,而不必多次查看卡片+1您不必多次查看。只要在你第一次看的时候记下a就行了。令人惊讶的是,错误的答案竟然被选上了榜首。正如随后的正确答案所指出的,只有一个ace被计算为11,因此简单地将每个ace计算为1要有效得多,然后,如果您发现一个ace,并且总数小于12,则添加10。不需要记录有多少个ACE,只需要额外添加一个。如果你加了10,你可以设置一个“软”标志,如果你需要跟踪总数是硬的还是软的。他们打了一个接一个,再打一个接一个,再打一个接一个。即使只有一个甲板,他们也有四个!如果是多层鞋,情况可能更糟。根据需要保持清点和折扣。。。