This problem is caused in your Pin
class in your getCurrentField()
method which is called when you call getNextFieldByDie(Die die)
from your loop. The problem is that you are removing items from the iterator that are not equivalent to the current pin. This action doesn't just produce an ArrayList
with the elements you are interested in, it actually modifies the backing store which in your code is in the GameManager
class.
public Field getCurrentField()
{
ArrayList<Position> positions = this.getManager().getPinPositions();
for (Iterator<Position> it=positions.iterator(); it.hasNext();) {
if (!it.next().getPin().equals(this))
it.remove();
}
if(positions.size() > 0)
return positions.get(0).getField();
else
return null;
}
After calling it.remove()
on the Position
objects that meet your criteria, your pos
list (which is drawn from the same instance of the GameManager
class) will no longer have anything but the original item left in it. Hence the change of size.
Rather than removing items from the iterator, it would be better to create a new ArrayList
that contained the elements of interest.
public Field getCurrentField()
{
ArrayList<Position> positions = this.getManager().getPinPositions();
//Just create a new list
ArrayList<Position> matchedPositions = new ArrayList<Position>();
//Use the for-each syntax to iterate over the iterator
for (Position position : positions) {
//switch the logic and add to the new list
if (position.getPin().equals(this))
matchedPositions.add(position);
}
if(matchedPositions.size() > 0)
return matchedPositions.get(0).getField();
else
return null;
}
I also want to point out that you have this same pattern occurring in multiple places in the code base you posted, and all of them could cause similar problems and should likely be switched.
It also just happens that you were using the only method for modifying a list while iterating over that list that will not throw the ConcurrentModificationException
making it harder to detect that a change had been made in your original list.