2015-01-18 2 views
1

Я пытаюсь играть в войну, и всякий раз, когда вы сравниваете две карты if(c.getValue() > Player2.get(x).getValue()){... Я нахожу победителя и перераспределяю карту игрока и карту двух игроков на стопку, ArrayList<Card> Pile = new ArrayList<Card>();, а затем распространять эту кучу на победителя, основываясь на булевом, но консоль бросает «concurrentModificationException». Я не знаю другого способа подойти к этому. Как добавить к arraylist постоянно меняющегося размера после сравнения двух аррайалистов объектов?Изменение размера arraylist при использовании улучшенного цикла для цикла

import java.util.ArrayList; 

public class Deck { 
    ArrayList<Card> deck = new ArrayList<Card>(); 
    ArrayList<Card> player1 = new ArrayList<Card>(); 
    ArrayList<Card> player2 = new ArrayList<Card>(); 
    ArrayList<Card> pile = new ArrayList<Card>(); 
    boolean winner; 

    public Deck(){ 

    } 
    public void createDeck(){ 
     for(int i =0; i<4; i++){   
      for(int j =1; j<15;j++){    
       if(i==0) deck.add(new Card("Spades", j));     
       if(i==1) deck.add(new Card("Hearts", j)); 
       if(i==2) deck.add(new Card("Clubs", j)); 
       if(i==3) deck.add(new Card("Diamonds",j)); 

      } 
     } 
    } 
    public void splitDeck(){ 
     for(int i = 0; i< 52;i++){ 
      int r = (int) (Math.random()*(51-i)); 
      if(i%2==0){ 
       player1.add(deck.get(r)); 
      } 
      else{ 
       player2.add(deck.get(r)); 
      } 
      deck.remove(r); 
     } 

    } 
    public int [] war(){ 

     int[]score = {0,0}; 

     for(Card c : player1){ 
      int x = player1.indexOf(c); 
      if(c.getValue() > player2.get(x).getValue()){ 
       winner = true; 
       score[0]++; 
       pile.add(player1.get(x)); 
       pile.add(player2.get(x)); 
       distributeCards(); 
      } 
      else if(c.getValue() <player2.get(x).getValue()) score[1]++; 
      distributeCards(); 
     } 

     return score; 
    } 

    public void distributeCards(){ 

      if(winner==true){ 
       for(int i = 0; i<pile.size(); i++){ 
        player1.add(pile.get(i)); 
       } 
      } 
      else{ 
       for(int i = 0; i<pile.size(); i++){ 
        player2.add(pile.get(i)); 
       } 
      } 
     } 


    public String warGame(){ 
     String print= ""; 
     for(Card c : player1){ 
      int x = player1.indexOf(c); 
      if(c.getValue() > player2.get(x).getValue()){ 

       print+= "\n"+"Player1 won"; 
      } 
      else if(c.getValue() <player2.get(x).getValue()) 
       print+="\n"+"Player2 won"; 

      else if(c.getValue() ==player2.get(x).getValue()) 
       print+= "\n"+"Its a tie"; 
     } 

     return print; 

    } 

} 

ошибка в консоли

Exception in thread "main" java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source) 
    at java.util.ArrayList$Itr.next(Unknown Source) 
    at Deck.war(Deck.java:69) 
    at War.main(War.java:6) 
+0

Можете ли вы опубликовать полное сообщение об ошибке с линией, на которую он указывает в коде –

+0

Линия 69 указывает на 'distributeCards()' внутри блока 'if' или снаружи. –

+1

В стороне, вы захотите изучить и использовать [Соглашения об именах Java] (http://en.wikipedia.org/wiki/Naming_convention_ (программирование) #Java). Имена переменных должны начинаться с нижней буквы, а имена классов - с буквой верхнего регистра. Следуя этим рекомендациям, а также следуя хорошим методам форматирования кода, вы сможете лучше понять ваш код и, что более важно, позволить вашему будущему «я» лучше понять, что вы думали 6 месяцев назад, когда вы написали код. –

ответ

1

Что вам нужно, это CopyOnWriteArrayList см http://docs.oracle.com/javase/tutorial/collections/implementations/list.html. Суть его заключается в том, что CopyOnWriteArrayList не бросает исключения одновременной модификации (поэтому вы можете добавлять к ним, итерации по ним), однако это происходит за счет копирования базовых данных каждый раз, когда есть запись. Так как ваш вариант использования - это военная игра, эта работа, но, вероятно, не будет такой заметной.

+0

После прочтения генерала почти кажется, что мне придется почти реструктурировать остальные мои методы, это правда? Я буду читать дальше по глубине завтра, но это кажется многообещающим. – Adamc23

+0

Вы должны просто отключить свой ArrayList с помощью CopyOnWriteArrayList. Обратите внимание, что в это время я бы изменил ваши объявления на что-то подобное. Список pile = new CopyOnArrayList () ;. Это известно как программирование интерфейса, то, что он покупает, - если вы прошли свои списки вокруг вас, вам придется менять каждое место, в котором принимал ArrayList, а все последующие коды зависят от данной реализации. Используя интерфейс вместо этого, вы можете изменить тип реализации списка, не затрагивая другой код. –

+0

Скорректированный мой ответ из-за вашей обратной связи. –

1

Вы также можете попробовать ListIterator, который поддерживает метод удаления/добавления во время самой итерации.

0

Если вы хотите изменить ArrayList вы итерация, решение довольно просто:

private List<YourObject> list = new ArrayList<>(); 
public void removeFromList(){ 
    List<YourObject> tempList = new ArrayList<>(); 
    for (Object o: list) { 
     o.doSomething(); 
     if (yourCondition){ 
      tempList.add(o); 
     } 
    } 
    list = tempList; 
} 

Это для удаления объектов, но реализация для добавления их также очень просто.

+0

Что именно будет o.doSomething(); относятся к этому проекту? также list = tempList; как это поможет мне добавить руку 1 и руку 2 победителю? Разве это не сделает список A равным списку B без карты B? – Adamc23

+0

То, что я пытаюсь вам сказать, состоит в том, чтобы избежать параллельных изменений в списке, вы можете создать новый список с необходимыми объектами и затем скопировать его. –

+0

Я пробовал это с помощью «кучи» карты, которую раздавал каждый игрок, клал в кучу, а затем раздавал победителю – Adamc23

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