小编典典

C#纸牌游戏中的最佳纸牌选择

algorithm

问题在于遵循以下规则在游戏的每个时刻选择最佳选项:

  • 您只能选择最左边或最右边的卡片。

  • 您的对手将始终优先选择,并且将始终从最左边或最右边的卡片中选择最高的卡片。如果是平局,它将选择最右边。考虑到这并不总是最佳选择。

有时候,这是不可能的,但是无论如何,您都必须显示出与该对手对抗时可以增加的最高金额(例如,可以说是策略)。

例:

Cards:    1 2 4 2 8 4 3
Opponent: 3 4 2 2 = 11
Me:       1 8 4 = 13

在这里,我在第二个回合中选择了1而不是4,所以以后可以选择8。这就是为什么选择最高的卡并不总是最好的原因。

我一直在尝试使用递归来实现此解决方案,但是我不确定这是最佳选择。关于如何设计此算法的任何想法?

[编辑]感谢@PengOne的慷慨帮助。这是我试图实现的代码,但不幸的是,它给了我错误。我应该修复什么?我在进行编辑。

static int cardGameValue(List<int> D, int myScore, int opponentScore)
{
    if (D.Count == 0) return myScore;
    else
    {
        if (D[0] <= D[D.Count - 1])
        {
            opponentScore += D[D.Count - 1];
            D.RemoveAt(D.Count - 1);
        }
        else
        {
            opponentScore += D[0];
            D.RemoveAt(0);
        }

        int left = cardGameValue(
                new List<int>(D.GetRange(1, D.Count - 1)),
                myScore + D[0],
                opponentScore);

        int right = cardGameValue(
                new List<int>(D.Take(D.Count - 2)),
                myScore + D[D.Count - 1],
                opponentScore);

        if (left >= right)
        { return left; }
        else
        { return right; }
    }
}

阅读 271

收藏
2020-07-28

共1个答案

小编典典

使用递归从最简单的情况构建解决方案。

假设D是纸牌阵列。设A您的牌B总数为对手的牌总数。设置S = A-B为游戏的价值。如果你赢了S>0,如果输S<0和领带如果S==0

最简单的方法是一次执行两个动作,然后是对手确定的动作。有两种基本情况需要考虑:

  • 如果length(D) == 0,请返回S。游戏结束了。

  • 如果length(D) == 1,请返回S + D[0]。您选择剩余的卡,游戏结束。

对于递归情况,当时length(D) > 1,评估两种可能性

  • L是比赛的结果,如果你选择了左侧的卡,随后被对手做他的确定性的举动,即

L = D[0] - max(D[1],D[N-1]) + cardGameValue(newD)

  • R是比赛的结果,如果你选择正确的卡,随后被对手做他的确定性的举动,即

R = D[N-1] - max(D[0],D[N-2]) + cardGameValue(newD)

选择与较大数字相对应的播放,即“ D[0]如果” L>=R,否则“” D[N-1]。在这里N = length(D)

2020-07-28