最好的卡中选择卡牌游戏在C#最好的、卡牌、游戏

2023-09-11 02:27:23 作者:放不下、忘不ㄋ

问题在于在游戏中遵守这些规则,每一个时刻选择最佳的选择:

您只能挑选最左边或最右边的卡。

你的对手总是先挑,而且总是选择最大牌无论从最左边或最右边的卡。如果它是一个平局,就挑最右边。考虑到这一点并不总是最好的选择。

有时候这是不可能赢,但你必须反正显示你可以打对这样的对手加上大写金额最高(或战略,让我们说)。

例如:

 卡片:1 2 4 2 8 4 3
对手:3 4 2 2 = 11
我:1 8 4 = 13
 
十款非常好玩的卡牌游戏 一起来体验卡牌游戏的魅力吧

下面,我chosed 1而不是4在第二回合,所以我可以挑8晚。这就是为什么选择最大的牌并不总是最好的。

我一直试图实现使用递归这一解决方案,但我不知道这是最好的选择。如何设计这个算法任何想法?

感谢@PengOne为它的慷慨帮助。这是code我尝试推行,但不幸的是它给我的错误。我应该在它修复?我编辑这是我进步。

 静态INT cardGameValue(名单< INT> D,INT myScore中,诠释opponentScore)
{
    如果(D.Count == 0)返回myScore的;
    其他
    {
        如果(D [0]&其中= D [D.Count  -  1])
        {
            opponentScore + = D [D.Count  -  1];
            D.RemoveAt(D.Count  -  1);
        }
        其他
        {
            opponentScore + = D [0];
            D.RemoveAt(0);
        }

        INT左= cardGameValue(
                新的List< INT>(D.GetRange(1,D.Count  -  1)),
                myScore的+ D [0],
                opponentScore);

        INT右= cardGameValue(
                新的List< INT>(D.Take(D.Count  -  2)),
                myScore的+ D [D.Count  -  1]
                opponentScore);

        如果(左> =右)
        {返回左; }
        其他
        {返回的权利; }
    }
}
 

解决方案

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

D 是卡的阵列。让 A 是你的卡的总和 B 是对手的卡的总。设置 S = AB 是本场比赛的价值。你赢了,如果 S> 0 ,输如果 S< 0 和领带,如果取值== 0

最简单的就是让两个动作一次,你的移动跟着对手的决心的举动。有两个基地情况来考虑:

如果的长度(D)== 0 ,返回取值。比赛已经结束了。

如果的长度(D)== 1 ,返回 S + D [0] 。您可以选择剩余的卡,游戏结束。

有关递归的情况下,当的长度(D)> 1 ,评价两种可能性

是本场比赛的结果,如果你选择了留卡,随后被对手做他的确定性的举动,即

L = D [0] - 马克斯(D [1],D [N-1)+ cardGameValue(NEWD)

研究是本场比赛的结果,如果你选择合适的卡,随后被对手做他的确定性的举动,即

R = D [N-1] - 最大(D [0],D [N-2)+ cardGameValue(NEWD)

选择相应数量较多的发挥,即采取 D [0] 如果 L> = R ,否则采取 D [N-1] 。在这里, N =长度(D)

The problem consists in choosing the best option at every moment of the game following these rules:

You can only pick the leftmost or the rightmost card.

Your opponent will ALWAYS pick first, and will ALWAYS choose the highest card from either the leftmost or the rightmost card. If it's a tie, it will pick the rightmost. Take into consideration this is not always the best choice.

Sometimes it's impossible to win, but you must anyway display the highest amout you can add by playing against this opponent (or strategy, let's say).

Example:

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

Here, I chosed 1 instead of 4 on the second turn, so I could pick the 8 later. That's why choosing the highest card is not always best.

I've been trying to implement this solution using recursion but I'm not sure it's the best option. Any ideas on how to design this algorithm?

[EDIT] Thanks to @PengOne for it's generous help. This is the code im trying to implement, but unfortunately it's giving me errors. What should I fix in it? I'm editing this as I progress.

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; }
    }
}

解决方案

Build the solution out from the simplest cases using recursion.

Let D be the array of cards. Let A be the total of your cards and B be the total of your opponent's cards. Set S = A-B to be the value of the game. You win if S>0, lose if S<0 and tie if S==0.

The easiest is to make two moves at once, your move followed by the opponent's determined move. There are two base cases to consider:

If length(D) == 0, return S. The game has ended.

If length(D) == 1, return S + D[0]. You choose the remaining card, and the game ends.

For the recursive case, when length(D) > 1, evaluate the two possibilities

Let L be the result of the game if you choose the left card followed by the opponent doing his deterministic move, i.e.

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

Let R be the result of the game if you choose the right card followed by the opponent doing his deterministic move, i.e.

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

Choose the play corresponding to the larger number, i.e. take D[0] if L>=R, otherwise take D[N-1]. Here N = length(D).