因为Loop没有完全完成

时间:2017-06-16 03:58:51

标签: c# unity3d

我有一个For循环,它处理从主牌组中取出牌,然后将它们随机排列到玩家牌组中。代码是:

for(int a = 0; a < deckManager.DeckAllCardsPlayer.Count; a++){
        int b = Random.Range(0, deckManager.DeckAllCardsPlayer.Count);
            if(!PlayerDeck.Contains(deckManager.DeckAllCardsPlayer[b])){
            PlayerDeck.Add(deckManager.DeckAllCardsPlayer[b]);
            deckManager.DeckAllCardsPlayer.RemoveAt(b);
        } 
    }

主甲板上有16张牌,但这个for循环只有8个。有人能找出原因吗?最初,它多次添加一些卡片,这就是我添加'!PlayerDeck.Contains'语句的原因。我不知道为什么它只做16个中的8个。

5 个答案:

答案 0 :(得分:4)

问题是deckManager.DeckAllCardsPlayer.Count在每次迭代时变得越来越小。试试这个:

while (deckManager.DeckAllCardsPlayer.Count > 0) {
    int b = Random.Range(0, deckManager.DeckAllCardsPlayer.Count);
    PlayerDeck.Add(deckManager.DeckAllCardsPlayer[b]);
    deckManager.DeckAllCardsPlayer.RemoveAt(b);
}

我删除了条件,因为它不应该是必要的。 (除非起始牌组有副本?如果是,请将其重新放入。)

答案 1 :(得分:3)

你从16张牌开始,但每次都要删除一张。

因此,虽然每次迭代减少一次,但deckManager.DeckAllCardsPlayer.Count的值向下

经过8次迭代后,a为7,但DeckAllCardsPlayer的大小已减少为8.因此循环在下一轮结束。

解决问题的一种方法是先计算并存储整数:

int totalCards = deckManager.DeckAllCardsPlayer.Count;
for(int a = 0; a < totalCards; a++){
    ... etc.

虽然还有很多其他方法,具体取决于您要公开的逻辑。

这个问题可能很有启发性:Is the condition in a for loop evaluated each iteration?

答案 2 :(得分:1)

当您从卡座中移除卡片时,循环的上限或上限会发生变化。 只需更改2行代码即可修复它 试试这个

int count = deckManager.DeckAllCardsPlayer.Count;
for(int a = 0; a < count; a++){
        int b = Random.Range(0, deckManager.DeckAllCardsPlayer.Count);
            if(!PlayerDeck.Contains(deckManager.DeckAllCardsPlayer[b])){
            PlayerDeck.Add(deckManager.DeckAllCardsPlayer[b]);
            deckManager.DeckAllCardsPlayer.RemoveAt(b);
        } 
    }

答案 3 :(得分:1)

假设PlayerDeck&amp; deckManager.DeckAllCardsPlayer都是列表,然后执行此操作:

PlayerDeck.AddRange(deckManager.DeckAllCardsPlayer.OrderBy(x => Random.value));
deckManager.DeckAllCardsPlayer.Clear();

然后你不必担心在迭代时删除元素(你永远不应该这样做)。

答案 4 :(得分:0)

int count = deckManager.DeckAllCardsPlayer.Count;
for(int a = 0; a < count; a++){
        int b = Random.Range(0, deckManager.DeckAllCardsPlayer.Count);
            if(!PlayerDeck.Contains(deckManager.DeckAllCardsPlayer[b])){
            PlayerDeck.Add(deckManager.DeckAllCardsPlayer[b]);
            deckManager.DeckAllCardsPlayer.RemoveAt(b);
        } 
    }

您必须使用计数变量。因为deckManager.DeckAllCardsPlayer.Count会在运行deckManager.DeckAllCardsPlayer.RemoveAt(b)后更改。我希望它对你有用。