0

我正在尝试计算简单的二十一点游戏的分数。我希望计算机能够根据牌的情况选择何时将 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;
}
4

5 回答 5

3

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

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 的累积总数,并使用更复杂的逻辑。

于 2012-11-22T19:16:41.947 回答
2

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

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

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

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

于 2012-11-22T19:25:55.843 回答
1

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

计算 ace 等于 1 的分数

  1. 设置可变分数
  2. 穿过手
  3. 设置一个等于卡值的变量数
  4. 如果数字大于 10 设置等于 10
  5. 将新数字添加到总分

检查一个王牌

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

执行逻辑

  1. 如果 isThereAnAce 等于 true 并且当前分数小于 12,则分数加 10
于 2013-08-23T17:34:07.183 回答
0

您还可以做的一件事是在您的卡片对象或您所称的对象中,您可以根据您当前的总数返回值。因此,您只需将您拥有的总数输入卡中的获取值,如果您有一张王牌,它将决定是否给您 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;
}

两者都会起作用,这取决于你想用什么方式来做。

于 2012-11-22T19:47:43.920 回答
0

正如我记得你们给我的提示以及 fgb 建议的另一篇关于SO 的帖子中的一些提示,我想出了这个。

与其在需要时算牌一次,不如算牌,因为它们属于我的 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,但我稍后会担心。

感谢帮助。

于 2012-11-22T21:05:02.440 回答