gpt4 book ai didi

java.lang.reflect.InitationTargetException 错误

转载 作者:行者123 更新时间:2023-12-01 18:22:27 25 4
gpt4 key购买 nike

我正在开发一个机器人迷宫,机器人可以在不撞墙的情况下找到目标。作为一种“原路返回”方法,我需要机器人沿着与第一次遇到交叉路口时相反的方向行驶。这是我的代码:

import uk.ac.warwick.dcs.maze.logic.IRobot;
import java.util.ArrayList;
import java.util.*;
import java.util.Iterator;

public class Explorer {

private int pollRun = 0; // Incremented after each pass.
private RobotData robotData; // Data store for junctions.
private ArrayList<Integer> nonWallDirections;
private ArrayList<Integer> passageDirections;
private ArrayList<Integer> beenbeforeDirections;
private Random random = new Random();
int [] directions = {IRobot.AHEAD, IRobot.LEFT, IRobot.RIGHT, IRobot.BEHIND};

public void controlRobot (IRobot robot) {

// On the first move of the first run of a new maze.
if ((robot.getRuns() == 0) && (pollRun ==0))
robotData = new RobotData();
pollRun++; /* Increment poll run so that the data is not reset
each time the robot moves. */

int exits = nonwallExits(robot);
int direction;

nonWallDirections = new ArrayList<Integer>();
passageDirections = new ArrayList<Integer>();
beenbeforeDirections = new ArrayList<Integer>();

// Adding each direction to the appropriate state ArrayList.
for(int item : directions) {
if(robot.look(item) != IRobot.WALL) {
nonWallDirections.add(item);
}
}

for(int item : directions) {
if(robot.look(item) == IRobot.PASSAGE) {
passageDirections.add(item);
}
}

for(int item : directions) {
if(robot.look(item) == IRobot.BEENBEFORE) {
beenbeforeDirections.add(item);
}
}

// Calling the appropriate method depending on the number of exits.
if (exits < 2) {
direction = deadEnd(robot);
} else if (exits == 2) {
direction = corridor(robot);
} else {
direction = junction(robot);
robotData.addJunction(robot);
robotData.printJunction(robot);
}

robot.face(direction);
}


/* The specification advised to have to seperate controls: Explorer and Backtrack
and a variable explorerMode to switch between them.
Instead, whenever needed I shall call this backtrack method.
If at a junction, the robot will head back the junction as to when it first approached it.
When at a deadend or corridor, it will follow the beenbefore squares until it
reaches an unexplored path. */
public int backtrack (IRobot robot) {

if (nonwallExits(robot) > 2) {
return robotData.reverseHeading(robot);
} else {
do {
return nonWallDirections.get(0);
} while (nonwallExits(robot) == 1);
}

}


// Deadend method makes the robot follow the only nonwall exit.
public int deadEnd (IRobot robot) {

return backtrack(robot);

}


/* Corridor method will make the robot follow the one and only passage.
The exception is at the start. Sometimes, the robot will start with
two passages available to it in which case it will choose one randomly.
If there is no passage, it will follow the beenbefore squares
until it reaches an unexplored path.*/
public int corridor (IRobot robot) {

if (passageExits(robot) == 1) {
return passageDirections.get(0);
} else if (passageExits(robot) == 2) {
int randomPassage = random.nextInt(passageDirections.size());
return passageDirections.get(randomPassage);
} else {
return backtrack(robot);
}
}


/* Junction method states if there is more than one passage, it will randomly select one.
This applies to crossroads as well as essentially they are the same.
If there is no passage, it will follow the beenbefore squares until it reaches an unexplored
path. */
public int junction(IRobot robot) {

if (passageExits(robot) == 1) {
return passageDirections.get(0);
} else if (passageExits(robot) > 1) {
int randomPassage = random.nextInt(passageDirections.size());
return passageDirections.get(randomPassage);
} else {
return backtrack(robot);
}

}


// Calculates number of exits.
private int nonwallExits (IRobot robot) {

int nonwallExits = 0;

for(int item : directions) {
if(robot.look(item) != IRobot.WALL) {
nonwallExits++;
}
}

return nonwallExits;
}


// Calculates number of passages.
private int passageExits (IRobot robot) {

int passageExits = 0;

for(int item : directions) {
if(robot.look(item) == IRobot.PASSAGE) {
passageExits++;
}
}

return passageExits;
}


// Calculates number of beenbefores.
private int beenbeforeExits (IRobot robot) {

int beenbeforeExits = 0;

for(int item : directions) {
if(robot.look(item) == IRobot.PASSAGE) {
beenbeforeExits++;
}
}

return beenbeforeExits;
}

// Resets Junction Counter in RobotData class.
public int reset() {

return robotData.resetJunctionCounter();

}
}

class RobotData {

/* It was advised in the specification to include the variable:
private static int maxJunctions = 10000;
However, as I am not using arrays, but ArrayLists, I do not
need this. */
private static int junctionCounter = 0;
private ArrayList<Junction> junctionList = new ArrayList<Junction>();
private Iterator<Junction> junctionIterator = junctionList.iterator();

// Resets the Junction counter.
public int resetJunctionCounter() {

return junctionCounter = 0;

}


// Adds the current junction to the list of arrays.
public void addJunction(IRobot robot) {

Junction newJunction = new Junction(robot.getLocation().x, robot.getLocation().y, robot.getHeading());
junctionList.add(newJunction);
junctionCounter++;

}


// Gets the junction counter for Junction info method in Junction class.
public int getJunctionCounter (IRobot robot) {

return junctionCounter;
}


// Prints Junction info.
public void printJunction(IRobot robot) {

String course = "";
switch (robot.getHeading()) {
case IRobot.NORTH:
course = "NORTH";
break;
case IRobot.EAST:
course = "EAST";
break;
case IRobot.SOUTH:
course = "SOUTH";
break;
case IRobot.WEST:
course = "WEST";
break;
}

System.out.println("Junction " + junctionCounter + " (x=" + robot.getLocation().x + ", y=" + robot.getLocation().y +") heading " + course);

}

/* Iterates through the junction arrayList to find the
heading of the robot when it first approached the junction. */
public int searchJunction(IRobot robot) {

Junction currentJunction = junctionIterator.next();
while (junctionIterator.hasNext()) {
if ((((currentJunction.x)==(robot.getLocation().x))) && ((currentJunction.y)==(robot.getLocation().y)))
break;
}

return currentJunction.arrived;
}


// Returns the reverse of the heading the robot had when first approaching the junction.
public int reverseHeading(IRobot robot) {

int firstHeading = searchJunction(robot);
int reverseHeading = 1; // Random integer to Iniitalise variable.

switch (firstHeading) {
case IRobot.NORTH:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.BEHIND;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.RIGHT;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.AHEAD;
else
reverseHeading = IRobot.LEFT;
break;

case IRobot.EAST:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.LEFT;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.BEHIND;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.RIGHT;
else
reverseHeading = IRobot.AHEAD;
break;

case IRobot.SOUTH:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.AHEAD;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.LEFT;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.BEHIND;
else
reverseHeading = IRobot.RIGHT;
break;

case IRobot.WEST:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.RIGHT;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.AHEAD;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.LEFT;
else
reverseHeading = IRobot.BEHIND;
break;
}

return reverseHeading;

}

}


class Junction {

int x;
int y;
int arrived;

public Junction(int xcoord, int ycoord, int course) {

x = xcoord;
y = ycoord;
arrived = course;

}

}

每当它回溯并到达它已经访问过的路口时,它就会卡住并出现此情况。

`java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor41.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at uk.ac.warwick.dcs.maze.controllers.PolledControllerWrapper.start(PolledControllerWrapper.java:70)
at uk.ac.warwick.dcs.maze.logic.ControllerThread.run(ControllerThread.java:46)
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at RobotData.searchJunction(Explorer.java:242)
at RobotData.reverseHeading(Explorer.java:255)
at Explorer.backtrack(Explorer.java:74)
at Explorer.junction(Explorer.java:122)
at Explorer.controlRobot(Explorer.java:56)
... 5 more`

最佳答案

我不认为你的searchJunction()正确或安全,由于 junctionList 的迭代器不正确,可能会引发 ConcurrentModificationException。 。问题应该更多地与迭代器有关,而不是与反射有关。

你可以尝试:

  1. private Iterator<Junction> junctionIterator = junctionList.iterator();没有多大意义,因为初始化 RobotData 对象时列表为空。尝试将其移至 searchJunction()
  2. 检查hasNext()首先然后调用next()

    public int searchJunction(IRobot robot) {
    Iterator<Junction> junctionIterator = junctionList.iterator();
    while (junctionIterator.hasNext()) {
    Junction currentJunction = junctionIterator.next();
    if ((((currentJunction.x)==(robot.getLocation().x))) && ((currentJunction.y)==(robot.getLocation().y)))
    break;
    }

    return currentJunction.arrived;
    }

关于java.lang.reflect.InitationTargetException 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27308032/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com