二十一点游戏,'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()
(在 DealerCardValue
或 PlayerCardValue
中),因为 Where()
return value 是一个空序列,因此没有最大值。这个写在Max()
函数的documentation in MSDN.
在DealerCardValue
和PlayerCardValue
中的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;
}
我为编码学校创建了一个 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()
(在 DealerCardValue
或 PlayerCardValue
中),因为 Where()
return value 是一个空序列,因此没有最大值。这个写在Max()
函数的documentation in MSDN.
在DealerCardValue
和PlayerCardValue
中的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;
}