我试图用Java构建一个简单的Rock-Paper-Scissors游戏。基本上,这个想法是玩家在做出错误行动时会被淘汰出局。剩下的最终球员是胜利者。 我相对缺乏经验,不太了解。我运行它时遇到了这个ConcurrentModification异常。我尝试了谷歌,但没有得到任何简单的解决方案。有关像迭代器这样的事情的讨论,我不太了解/理解。
我尝试过如下 -
GameStarter类:
public class GameStarter
{
public static void main(String[] args)
{
RPS g = new RPS();
g.play();
}
}
RPS课程:
import java.util.ArrayList;
public class RPS
{
Player p1 = new Player(" A ");
Player p2 = new Player(" B ");
Player p3 = new Player(" C ");
Player p4 = new Player(" D ");
Player p5 = new Player(" E ");
ArrayList<Integer> hold =new ArrayList<Integer>();
ArrayList<Player> active = new ArrayList<Player>();
{
active.add(p1);
active.add(p2);
active.add(p3);
active.add(p4);
active.add(p5);
}
public void play()
{
int i,j;
while(active.size()>1)
{
for(Player p:active)
{
System.out.print("\n Currently active players are: "+p.name+" , ");
}
System.out.println("\n\n");
for(Player p:active)
{
p.rpsThrow();
hold.add(p.cur);
}
if(hold.contains(1) && hold.contains(2) && !hold.contains(3))
{
for(Player p: active)
{
if(p.cur==1)
{
active.remove(p);
System.out.println("Player "+p.name+" eliminated ");
}
}
}
if(hold.contains(1) && !hold.contains(2) && hold.contains(3))
{
for(Player p: active)
{
if(p.cur==3)
{
active.remove(p);
System.out.println("Player "+p.name+" eliminated ");
}
}
}
if(!hold.contains(1) && hold.contains(2) && hold.contains(3))
{
for(Player p: active)
{
if(p.cur==2)
{
active.remove(p);
System.out.println("Player "+p.name+" eliminated ");
}
}
}
hold.clear();
try
{
Thread.sleep(3500);
}
catch(Exception ex)
{
}
}
if(active.size()==1)
{
for(Player p:active)
{
System.out.println("\n\n The winner is : \n"+p.name);
}
}
}
}
和玩家类:
public class Player
{
String name;
Integer cur;
public Player(String n)
{
name=n;
}
public int rpsThrow()
{
int t;
t=(int)((Math.random()*3)+1);
cur=t;
if(t==1)
{
System.out.println("\n"+name+" throws : rock");
}
else if(t==2)
{
System.out.println("\n"+name+" throws : paper");
}
else
{
System.out.println("\n"+name+" throws : scissors");
}
return t;
}
}
有没有简单的方法来解决这个CMException?请随意修改我的代码以解决它。
答案 0 :(得分:2)
基本上,一旦你开始在Collection上使用迭代器(并且这种类型的for循环使用迭代器),你就不能修改底层集合,直到完成迭代器,否则你将得到一个CME。如果要从集合中删除项,则需要使用显式迭代器并使用其remove()方法,如下所示:
public static void main(String[] args) throws Exception {
List<String> vals = new ArrayList<>();
vals.add("1"); vals.add("2"); vals.add("3");
// This throws a CME
for(String s: vals) {
if("1".equals(s)) {
vals.remove(s);
}
}
// This would work
for(Iterator i = vals.iterator(); i.hasNext(); ) {
if("1".equals(i.next())) {
i.remove();
}
}
}
答案 1 :(得分:1)
我将RPS类更改为此(正常):
package RockPaperScissors;
import java.util.ArrayList;
public class RPS
{
Player p1 = new Player(" A ");
Player p2 = new Player(" B ");
Player p3 = new Player(" C ");
Player p4 = new Player(" D ");
Player p5 = new Player(" E ");
ArrayList<Integer> hold =new ArrayList<Integer>();
ArrayList<Player> active = new ArrayList<Player>();
{
active.add(p1);
active.add(p2);
active.add(p3);
active.add(p4);
active.add(p5);
}
public void play()
{
int i,j;
Player p;
while(active.size()>1)
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
System.out.print("\n Currently active players are: "+p.name+" , ");
}
System.out.println("\n\n");
for(i=0;i<active.size();i++)
{
p= active.get(i);
p.rpsThrow();
hold.add(p.cur);
}
if(hold.contains(1) && hold.contains(2) && !hold.contains(3))
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
if(p.cur==1)
{
active.remove(p);
System.out.println("Player "+p.name+" eliminated ");
}
}
}
if(hold.contains(1) && !hold.contains(2) && hold.contains(3))
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
if(p.cur==3)
{
active.remove(p);
System.out.println("Player "+p.name+" eliminated ");
}
}
}
if(!hold.contains(1) && hold.contains(2) && hold.contains(3))
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
if(p.cur==2)
{
active.remove(p);
System.out.println("Player "+p.name+" eliminated ");
}
}
}
hold.clear();
try
{
Thread.sleep(3500);
}
catch(Exception ex)
{
}
}
if(active.size()==1)
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
System.out.println("\n\n The winner is : \n"+p.name);
}
}
}
}
RPE不再存在。虽然我必须说它的表现并不像我期望的那样。 我还将尝试研究和研究迭代器。感谢你的帮助。 编辑:改变指数与正常。现在它的工作方式就像我想要的那样。
package RockPaperScissors;
import java.util.ArrayList;
public class RPS
{
Player p1 = new Player(" A ");
Player p2 = new Player(" B ");
Player p3 = new Player(" C ");
Player p4 = new Player(" D ");
Player p5 = new Player(" E ");
ArrayList<Integer> hold =new ArrayList<Integer>();
ArrayList<Player> active = new ArrayList<Player>();
{
active.add(p1);
active.add(p2);
active.add(p3);
active.add(p4);
active.add(p5);
}
public void play()
{
int i,j;
Player p;
while(active.size()>1)
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
System.out.print("\n Currently active players are: "+p.name+" , ");
}
System.out.println("\n\n");
for(i=0;i<active.size();i++)
{
p= active.get(i);
p.rpsThrow();
hold.add(p.cur);
}
if(hold.contains(1) && hold.contains(2) && !hold.contains(3))
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
if(p.cur==1)
{
active.remove(p);
**i=i-1;**
System.out.println("Player "+p.name+" eliminated ");
}
}
}
if(hold.contains(1) && !hold.contains(2) && hold.contains(3))
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
if(p.cur==3)
{
active.remove(p);
i=i-1;
System.out.println("Player "+p.name+" eliminated ");
}
}
}
if(!hold.contains(1) && hold.contains(2) && hold.contains(3))
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
if(p.cur==2)
{
active.remove(p);
i=i-1;
System.out.println("Player "+p.name+" eliminated ");
}
}
}
hold.clear();
try
{
Thread.sleep(3500);
}
catch(Exception ex)
{
}
}
if(active.size()==1)
{
for(i=0;i<active.size();i++)
{
p= active.get(i);
System.out.println("\n\n The winner is : \n"+p.name);
}
}
}
}
答案 2 :(得分:0)
在循环中使用iterator
,您可以在其中修改当前迭代的集合
for(Iterator iter = active.iterator(); iter.hasNext();)
{
Player p = (Player)iter.next();
if(p.cur==1)
{
iter.remove();
System.out.println("Player "+p.name+" eliminated ");
}
}
答案 3 :(得分:0)
将活动播放器的循环更改为Iterator
答案 4 :(得分:0)
这段代码存在问题: -
for(Player p: active)
{
if(p.cur==2)
{
active.remove(p);
System.out.println("Player "+p.name+" eliminated ");
}
}
您正在迭代列表活动并从中删除元素。
您需要使用迭代器并从迭代器中删除数据,它将自动从实际列表中删除。
for(Iterator playerIterator = active.iterator(); playerIterator.hasNext();) {
Player p = (Player)playerIterator.next();
if(p.cur==2){
playerIterator.remove();
System.out.println("Player "+p.name+" eliminated ");
}
}