我在C#中创建一个小的BlackJack应用程序。我可以向经销商和玩家交易一个初始牌,然后击中玩家。然而,一旦我这样做,经销商应该在经销商手值低于17时从牌组中抽出一张牌。
这是从甲板上的牌组中获得一张牌:
public Card GetCard()
{
int r0 = rndCard.Next(0, cardsInDeck_.Count - 1);
cardsInDeck_.RemoveAt(r0);
return cardsInDeck_[r0];
}
当我点击“停留”且经销商激活时,我在最后一行收到此错误
Index was out of range. Must be non-negative and less than the size of the collection
这是我在表格上的“停留”方法
private void buttonStay_Click(object sender, EventArgs e)
{
while (dealer.GetValue() < 17)
{
dealer.CardsInDealerHand.Add(deck.GetCard());
}
dealerHandValue_ = dealer.GetValue();
if (dealerHandValue_ > 21)
{
Win();
}
else
{
WinCondition();
}
}
我对编程很新,但我认为我的套牌或经销商都有问题。
我将不胜感激。
答案 0 :(得分:1)
我注意到的第一件事是:你在访问它之前从卡片中取出卡片以使其退回,导致你的指数摆脱困境。在某些情况下,这可能“起作用”,因为它不会抛出,但你不会得到正确的牌。在其他情况下,您最终可能会超出列表的范围。
考虑一下:你的“套牌”中有6个项目,你选择最后一个。你现在的逻辑是:
cardsInDeck_.RemoveAt(r0); # Remove the item at index 5; now we have 5 items (0-based indexing)
return cardsInDeck_[r0]; # Try to get the item at index 5, but it's no longer there!
即使你没有选择最后一个索引,你实际上也会得到错误的卡片。例如,如果你有:
{ A, J, 5, 10, 2 }
...在你的套牌中,你选择了索引2,你应该得到5回。由于你首先删除卡 然后访问列表索引,你实际上会回到10。
您需要首先获得对卡片的引用,然后将其从卡片中移除并返回参考:
public Card GetCard()
{
int r0 = rndCard.Next(0, cardsInDeck_.Count - 1);
var chosenCard = cardsInDeck_[r0];
cardsInDeck_.RemoveAt(r0);
return chosenCard;
}
在尝试获取另一张卡之前,可能最好先检查cardsInDeck_.Count
是否为零值,或许是在GetCard()
或在while循环中。如果你只交出两只手(一只给玩家,一只给经销商),那么这在数学上不是你会遇到的情况。否则,对于多个玩家,您需要以某种方式处理这种情况(例如,您可以通过重新填充cardsInDeck
来添加第二个牌组。
答案 1 :(得分:0)
r0被设置为负值或大于cardsInDeck_的值,由函数rndCard.Next
int r0 = rndCard.Next(0, cardsInDeck_.Count - 1);
答案 2 :(得分:0)
问题:您试图从cardsInDeck_
移除项目而不检查其Count
。如果你继续在cardsInDeck_
删除项目,Count
成为cardsInDeck_
零如果计数为零,则无法删除任何项目。
解决方案:在从Count
移除项目之前,您需要检查其cardsInDeck_.RemoveAt(r0);
,只有在其计数大于零时才应删除项目。
替换它:
if(cardsInDeck_.Count>0)
{
cardsInDeck_.RemoveAt(r0);
}
有了这个:
{{1}}
答案 3 :(得分:0)
异常消息: “指数超出范围。必须是非负数且小于集合的大小” 这是问题,因为如果牌组是空的那么
int r0 = rndCard.Next(0,cardsInDeck_.Count - 1);
Next的第二个参数是一个独占上限。
因此,如果Count为0,那么你要求int> = 0&amp;&amp; &LT; -1
如果count为1,则要求输入int&gt; = 0&amp;&amp; &LT; 0
另外,我建议您遵循标准的C#命名约定。微软的建议是一个很好的起点