二十一点游戏,'Sequence contains no elements'

Blackjack game, 'Sequence contains no elements'

我为编码学校创建了一个 Blackjack 游戏,我正在对其进行修改以显示游戏的其他方面,例如庄家的牌面总价值以及我在游戏结束时的牌面总价值。一切正常,直到 Dealer Busted 出现此错误:

System.InvalidOperationException: 'Sequence contains no elements'

我用谷歌搜索并搜索了 Whosebug,但我不理解任何回复。这是我的 github 代码。 https://github.com/CrystalReimche/TwentyOneGame

在 TwentyOneGame.cs 中,第 143 行是我试图让它显示的地方。

            foreach (KeyValuePair<Player, int> entry in Bets)
            {
                Players.Where(x => x.Name == entry.Key.Name).First().Balance += (entry.Value * 2);
                Console.WriteLine($"{entry.Key.Name} won {entry.Value} and now has a balance of {entry.Key.Balance}!");
                Console.WriteLine($"Dealer had {TwentyOneRules.DealerCardValue(Dealer.Hand)} and {entry.Key.Name} had {TwentyOneRules.PlayerCardValue(entry.Key.Hand)}");
            }

在TwentyOneRules.cs中包含它的方法。

  public static Dictionary<Face, int> _cardValues = new Dictionary<Face, int>()
    {
        [Face.Two] = 2,
        [Face.Three] = 3,
        [Face.Four] = 4,
        [Face.Five] = 5,
        [Face.Six] = 6,
        [Face.Seven] = 7,
        [Face.Eight] = 8,
        [Face.Nine] = 9,
        [Face.Ten] = 10,
        [Face.Jack] = 10,
        [Face.Queen] = 10,
        [Face.King] = 10,
        [Face.Ace] = 1
    };

    public static int[] GetAllPossibleHandValues(List<Card> Hand)
    {
        int aceCount = Hand.Count(x => x.Face == Face.Ace); // Find out how many Ace's there are
        int[] result = new int[aceCount + 1]; // Plus 1 means if there's 2 Aces, there's 3 possible results ((1,1)||(1,11)||(11,11))
        int value = Hand.Sum(x => _cardValues[x.Face]); // Value is the lowest possible value with all Ace's == 1
        result[0] = value;
        if (result.Length == 1) return result;
        for (int i = 1; i < result.Length; i++)
        {
            value += (i * 10);
            result[i] = value;
        }
        return result;
    }

    public static bool CheckForBlackJack(List<Card> Hand)
    {
        int[] possibleValues = GetAllPossibleHandValues(Hand);
        int value = possibleValues.Max();
        if (value == 2) return true;
        else return false;
    }

    public static bool IsBusted(List<Card> Hand)
    {
        int value = GetAllPossibleHandValues(Hand).Min();
        if (value > 21) return true;
        else return false;
    }

    public static bool ShouldDealerStay(List<Card> Hand)
    {
        int[] possibleHandvalues = GetAllPossibleHandValues(Hand);
        foreach (int value in possibleHandvalues)
        {
            if (value > 16 && value < 22)
            {
                return true;
            }
        }
        return false;
    }

    public static bool? CompareHands(List<Card> PlayerHand, List<Card> DealerHand)
    {
        int[] playerResults = GetAllPossibleHandValues(PlayerHand);
        int[] dealerResults = GetAllPossibleHandValues(DealerHand);

        int playerScore = playerResults.Where(x => x < 22).Max(); // Filter the values that's < 22 and bring me the max of the values
        int dealerScore = dealerResults.Where(x => x < 22).Max();

        if (playerScore > dealerScore) return true;
        else if (playerScore < dealerScore) return false;
        else return null; // this is a tie
    }

    public static int PlayerCardValue(List<Card> PlayerHand)
    {
        int[] playerResults = GetAllPossibleHandValues(PlayerHand);
        int playerScore = playerResults.Where(x => x < 50).Max();
        return playerScore;
    }

    public static int DealerCardValue(List<Card> DealerHand)
    {
        int[] dealerResults = GetAllPossibleHandValues(DealerHand);
        int dealerScore = dealerResults.Where(x => x < 22).Max();
        return dealerScore; 
    }

我认为它与字典有关,因为这些方法适用于游戏中不使用字典的其他部分。例如,如果我爆牌,它会显示我的牌总值和庄家牌的总值。

if (busted)
                {
                    Console.WriteLine($"{player.Name} Busted!  You lose your bet of {Bets[player]}.  Your balance is now {player.Balance}");
                    Console.WriteLine($"Dealer had {TwentyOneRules.DealerCardValue(Dealer.Hand)} and {player.Name} had {TwentyOneRules.PlayerCardValue(player.Hand)}");

                }

我只是还没有很好地掌握如何正确使用词典。

问题是您在不包含任何元素的序列上调用 Max()(在 DealerCardValuePlayerCardValue 中),因为 Where() return value 是一个空序列,因此没有最大值。这个写在Max()函数的documentation in MSDN.

DealerCardValuePlayerCardValue中的Max()前添加DefaultIfEmpty(),防止InvalidOperationException被抛出,如图here,像这样:

public static int DealerCardValue(List<Card> DealerHand)
{
    int[] dealerResults = GetAllPossibleHandValues(DealerHand);
    int dealerScore = dealerResults.Where(x => x < 22).DefaultIfEmpty().Max();
    return dealerScore;
}