【问题标题】:How to decide when Ace should count as 1 or 11 in BlackJack game?在二十一点游戏中,如何决定 Ace 何时应计为 1 或 11?
【发布时间】:2012-11-11 05:01:14
【问题描述】:

我正在尝试计算简单的 BlackJack 游戏的分数。我希望计算机能够根据牌的情况选择何时将 Ace 牌计为 1 或 11,但我不想硬编码这种情况。

我应该怎么做?

这是我在庄家/玩家手牌类别中计算得分的方式:

public int calcScore()
{
    int score = 0;
    Link current = first;

    while(current != null)
    {
        score = score + current.card.getValue();
        current = current.next;
    }

    return score;
}

这是我在 Card 类中指定卡片值的方式:

public int getValue()
{
    int value = 0;

    if (rank == 1)
        value = 11;
    else if (rank == 11 || rank == 12 || rank == 13)
        value = 10;
    else
        value = rank;

    return value;
}

【问题讨论】:

  • 您应该使用Enum 来存储您的卡片。
  • 我只是尝试演示数据结构的使用。恐怕我需要坚持我的解决方案。
  • 那么你将不得不对其进行硬编码。没有出路。
  • 您可以创建一个Map 用于将值映射到rank

标签: java logic blackjack


【解决方案1】:

问题是计算需要知道当前总数是多少,所以这样编码:

public int getValue(int currentTotal) {
    int value = 0;

    if (rank == 1 && currentTotal < 11)
        value = 11;
    else if (rank == 1)
        value = 1;
    else if (rank == 11 || rank == 12 || rank == 13)
        value = 10;
    else
        value = rank;

    return value;
}

我还没有彻底理解它那个,但我很确定你不需要检查多个后续的 A,因为唯一的失败方法就是如果你击中21,没有人会这样做。如果这不起作用,您可能必须传递已计数 A 的累积总数,并使用更复杂的逻辑。

【讨论】:

  • 我在考虑这个,但这是一种硬编码,结果可能会因我认为的情况而异。我的意思是,在最坏的情况下,我知道它就足够了。
【解决方案2】:

我不认为你可以将确定牌值的所有逻辑都放在 card 对象中,因为在计算完所有牌的值之前,你不知道 ace=11 是否会导致手牌破产 - 在这种情况下,王牌会神奇地变成 1。

我会修改设计,使卡片具有getMinValue()getMaxValue()。它们的工作原理与您的getValue() 完全相同,只是如果卡片是 ace,则 getMinValue 返回 1,而 getMaxValue 返回 11。

现在您重新设计 calcScore 以首先使用 getMaxValue 计算分数。如果牌出局,您需要对 getMaxValue 和 getMinValue 进行更复杂的计算。

这样,您的卡片类不必封装二十一点的business logic,但它仍然提供了足够的信息,您可以在游戏级别处理规则。

【讨论】:

    【解决方案3】:

    我知道已经有了答案,但问题是一个通用的方法,一切都在 java 中。这是答案的伪代码逻辑。

    计算ace等于1的分数

    1. 设置可变分数
    2. 用手循环
    3. 设置一个等于卡值的变量数
    4. 如果数字大于 10 设置等于 10
    5. 在总分中添加新数字

    检查 ace

    1. 将 isThereAnAce 的变量设置为 false
    2. 遍历牌组并检查是否有任何牌是 A,如果至少有一组 isThereAnAce 为 true

    执行逻辑

    1. 如果 isThereAnAce 等于 true 并且当前分数小于 12,则分数加 10

    【讨论】:

      【解决方案4】:

      我牢记你们给我的提示,以及其他 post 的一些提示,正如 fgb 建议的那样,我想出了这个。

      当我需要时,我宁愿计算卡片,而不是计算卡片,因为它们属于我的 Hand 类的插入方法。

      这让我算牌并决定是用 1 还是 11 作为 A。

      public void insert(Card card)
      {
          Link newLink = new Link(card);
          newLink.next = first;
      
          if (card.rank == 1 && cardTotal + card.getValue() > 21)
              cardTotal = cardTotal + (card.getValue() - 10);
          else
              cardTotal = cardTotal + card.getValue();
      
          first = newLink;
      }
      

      问题是我是否应该让玩家决定何时使用 1 或 11,但我稍后会担心。

      感谢您的帮助。

      【讨论】:

      • 一种更简单、更稳健的解决方法是为手牌价值创建一个总方法。方法中:最初ace可以是11。如果total > 21,找到任何ace并将值降为1,然后返回最终的总数。
      • @Ben Sewards,我想你是对的。我只是这样做了,但我认为这是“足够好”的解决方案:)
      【解决方案5】:

      您还可以做的一件事是在您的卡片对象或您所称的任何内容中,您可以根据您当前拥有的总数返回值。因此,您只需将您拥有的总数输入卡中的 get 值,如果您有一张 A,它将决定是否给您 1 或 11

      另一种可能也是最简单的方法就是在你的 get value 函数中检查总数。

      public int getValue(int currentVal)
      {
          int value = 0;
      
          if (rank == 1 && currentVal < 11)
              value = 11;
          else if(rank == 1)
              value = 1;
          else if (rank == 11 || rank == 12 || rank == 13)
              value = 10;
          else
              value = rank;
      
          return value;
      }
      

      两者都行得通,取决于你想怎么做。

      【讨论】:

        猜你喜欢
        • 2019-09-09
        • 2018-04-02
        • 1970-01-01
        • 2023-03-21
        • 2020-05-18
        • 1970-01-01
        • 2017-12-01
        • 2021-04-25
        • 1970-01-01
        相关资源
        最近更新 更多