2013-04-25 2 views
0

Я хочу реализовать метод атаки, который работает следующим образом: каждый воин из моих войск атакует воина, выбранного случайным образом из другого отряда. Если атакуемый воин умирает, он должен быть удален из войска. С методом, который я пытался я получаю сообщение об ошибке для случайного числа:Удаление во время итерации проблем в java

java.lang.IllegalArgumentException: n must be positive 

Войск является списком <Creature> воинов; Я думаю, что я не делаю удаление правильно, потому что иначе я не должен иметь эту ошибку.

public void atac(Troop opponentTroop){ 
     for(Creature f : warriors){ 
      Creature c = getOpponent(opponentTroop); 
      f.atac(c); 
      ListIterator<Creature> iterator = opponentTroop.warriors.listIterator(); 
      while(iterator.hasNext()){ 
       c = iterator.next(); 
       if(c.isDead()){ 
        iterator.remove();     
       } 
      } 

     }  
    } 


private Creature getOpponent(Troop opponent){ 
     int x = rand.getRandomArrayIndex(opponent.warriors.size()); 
     return opponent.warriors.get(x); 
} 
+1

Можете ли вы дать нам сама строка, в которой выбрано исключение (см. Stacktrace)? – Fildor

+0

Где вызывается «IllegalArgumentException»? Я не признаю его стандартным сообщением об ошибке Java, поэтому его может бросить какая-то другая часть вашего приложения Проблема может быть не итерацией, а логикой вообще –

ответ

0

Удаление записи делает недействительным итератор. Вы должны сохранить его, вы могли бы сделать что-то вроде этого:.

while(iterator.hasNext()) { 
    c = iterator.next(); 
    if(c.isDead()) { 
     // Make a temporary iterator 
     ListIterator<Creature> toDelete= c; 
     // Step the regular one 
     c = iterator.next(); 
     // Remove 
     toDelete.remove();     
    } 
} 

Кроме того, убедитесь, что int x = rand.getRandomArrayIndex(opponent.warriors.size()); никогда не выходит за пределы последнего индекса (который является количество записей минус один

+2

Я думаю, что я бы предпочел добавить мертвого противника в новый список. В дополнительном цикле t его мертвые оппоненты будут удалены. Вполне вероятно, что нужно сделать больше для мертвых противников, таких как анимационный процесс или что-то для всех мертвых тел. – Raymond

+0

@ Раймонд ван Донгелен: На ​​самом деле нет необходимости в дополнительном цикле. Она могла просто называть 'enemyTroop.warriors.removeAll (toDelete)' –

Смежные вопросы