我构建了这个数组:有机细胞[] [];我用蚂蚁和doodlebugs填充阵列(两个类都继承了生物体),并将大部分斑点留空以表示空白点。然后我试图移动所有的蚂蚁和doodlebugs。为了移动它们,我首先为目标找到一个空的空间,然后将目标细胞更改为需要移动的生物体。在那之后,我在移动的生物 的x / y处杀死(设置为null)生物体。因此,如果我移动单元格[1] [1]并且单元格[2] [2]是我的目标,我会:设置单元格[2] [2] =单元格[1] [1]然后设置单元格[1] [1] = null。
我的问题是,在第二次执行此过程后,代码不再移动生物体。虽然所有生物都是第一次移动,但我需要这个过程是可重复的。
我该如何解决这个问题?谢谢你的帮助。
有很多代码,但我被要求发布重要部分。对不起,如果它很长,我试着简化它。
世界级:
public class World {
private final int HEIGHT = 20;
private final int WIDTH = 20;
private Organism cells[][]; // (0,0) is considered the upper left corner
public static Random generator = new Random(1000L); // Use of a Random generator lets us provide same
// sequence of "random" numbers. Consequently, the
// simulation will be identical each run, aiding debugging.
//public static Random generator = new Random(); // Once your program works properly, comment out the statement
// above, and uncomment this one. This will make your program run differently
// every time you run it.
/**
* @param x horizontal grid coordinate
* @param y vertical grid coordinate.
*
* @return If (x,y) are not legal coords, returns null. Else returns value of the that cell.
* This will eiher be an Organism or null.
*/
public Organism getCell(int y, int x){
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT){
return null;
}
return cells[y][x];
}
/**
* @param x horizontal grid coordinate
* @param y vertical grid coordinate.
* @param org Organism to place in the world
*/
public void setCell(int x, int y, Organism org){
cells[y][x]=org;
}
/**
* @param x horizontal grid coordinate
* @param y vertical grid coordinate.
* @return Return false if cell at given coords is not empty, or if coordinates are
* "off the grid." Else return true.
*/
public boolean isEmptyCell(int y, int x){
// YOUR CODE HERE...
if(getCell(y,x) != null){
return false;
}
return true;
}
/**
* Construct a World.
* If you don't want repeatable simulations (i.e., you want each to be unique),
* remove the "seed" value from the Random() constructor.
* @param numAnts The number of Ants to place randomly in the grid.
* @param numDoodles The number of Doodlebuggs to place randomly in the grid.
*/
public World(int numAnts, int numDoodles){
int x=0, y=0, count1=0, count2=0;
cells = new Organism[getHEIGHT()][getWIDTH()];
// YOUR CODE HERE to randomly place ants and doodlebugs.
while(count1<numAnts){
y = myRand(getHEIGHT());
x = myRand(WIDTH);
if(isEmptyCell(y,x)){
cells[y][x] = new Ant(y,x,this);
count1++;
//System.out.println("MAKING ANT at x=" + x +" and y= " + y);
}
}
while(count2<numDoodles){
y = myRand(getHEIGHT());
x = myRand(WIDTH);
if(isEmptyCell(y,x)){
cells[y][x] = new Doodlebug(y,x,this);
count2++;
}
}
}
/**
* @param x
* @param y
* @param org
* @return Return true if a new organism was added to the World, else return false.
* If at least one of the adjacent cells to [x,y] is empty, randomly select one of the
* empty ones and place org there.
* [You might do this by first checking if there's at least one empty adjacent cell.
* If so, use a loop to successively randomly select an adjacent cell until you find
* an empty one, then place org there.]
*
* [Oh, and this might be a good place to use a "switch" statement to deal with the
* four possible directions N,S,E,W.]
*/
public boolean addAdjacent(int x, int y, Organism org) {
// YOUR CODE HERE....
System.out.println("World.addAdjacent() not yet implemented.\n");
return true; // MODIFY SO RETURNS TRUE ONLY WHEN APPROPRIATE
}
/**
* Move all the ants.
*/
public void moveAllAnts() {
clearAntFlags();
for(int y=0; y<cells.length; y++){
for(int x=0; x<cells[y].length;x++){
if (getCell(x,y) instanceof Ant){
//System.out.println("Ant found at: y=" + x + " and x="+ y +"\t\tmoved? " + getCell(x,y).hasMoved);
getCell(x,y).move();
}
}
}
}
/**
* Move all the doodlebugs.
*/
public void moveAllDoodles() {
clearDoodleFlags();
for(int y=0; y<cells.length; y++){
for(int x=0; x<cells[y].length;x++){
if (getCell(x,y) instanceof Doodlebug){
//System.out.println("Doodle found at: y=" + x + " and x="+ y);
getCell(x,y).move();
}
}
}
}
public static void main(String[] args) {
World w;
w= new World(10,10);
System.out.println("A thinly populated world:\n"+w);
w.moveAllAnts();
w.moveAllDoodles();
System.out.println("A thinly populated world:\n"+w);
}
public int getHEIGHT() {
return HEIGHT;
}
public int getWIDTH() {
return WIDTH;
}
/**
* @param x,y takes the location of the ant and attempts to find an adjacent empty cell.
* @return Return a point if an adjacent cell is empty, otherwise return null.
*/
public Point getAdjaEmpty(int y, int x){
Point p = new Point(0,0);
boolean up = false, down = false, left = false, right = false;
int numTrue = 0;
if(isEmptyCell(y-1,x) && y-1>=0){ // can go left
left = true;
numTrue++;
}
if(isEmptyCell(y+1,x) && y+1<cells.length){ // can go right
right = true;
numTrue++;
}
if(isEmptyCell(y,x-1) && x-1>=0){ // can go up
up = true;
numTrue++;
}
if(isEmptyCell(y,x+1) && x+1<cells[0].length){ // can go down
down = true;
numTrue++;
}
if(numTrue >0){
if(numTrue==1){
if(left){
p.x = x;
p.y= y-1;
}else if(right){
p.x = x;
p.y= y+1;
}else if(up){
p.x = x-1;
p.y= y-1;
}else if(down){
p.x = x+1;
p.y= y;
}else{
System.err.println("Error in adjacEmpty function!");
}
}else if(numTrue>=2){
//make direction random
int dir = 0;
while(true){ //looks for a random spot that is empty and accessible
dir = generator.nextInt(4);
if(left && dir == 0){
p.x = x;
p.y= y-1;
//System.out.println("left");
break;
}else if(right && dir == 1){
p.x = x;
p.y= y+1;
//System.out.println("right");
break;
}else if(up && dir == 2){
p.x = x-1;
p.y= y;
//System.out.println("up");
break;
}else if(down && dir == 3){
p.x = x+1;
p.y= y;
//System.out.println("down");
break;
}
}
}
}else{
return null;
}
return p;
}
/* Moves the Organism to the random location given by getAdjaEmpty
* Also kills the old organism.
*
*/
public void killAndMove(int y, int x) {
Point p = getAdjaEmpty(y,x);
if(cells[y][x] != null){
setCell(p.x,p.y, getCell(y,x));
cells[y][x].kill();
}
}
}
有机体类:
abstract public class Organism {
protected int locX, locY; // Coords of organism in its World.
protected boolean hasMoved; // Movement flag: true if has already moved this turn [Can you see why this is needed?]
abstract public void move(); // Move the critter to an adjacent space
protected World myMap; // Need this so each organism has access to its World.
/**
* As this is an abstract class, this constructor is invoked via super() by its
* subclasses. Takes care of initializing the fields they inherit from this class.
* @param x
* @param y
* @param m
*/
public Organism(int x, int y, World m) {
// Initialize instance variables, including
myMap = m;
locX = x;
locY = y;
// YOUR CODE HERE! What other instance variables?
}
/**
* Clear the move flag.
*/
public void clearMoveFlag() {
hasMoved = false;
}
/**
* Remove the organism from the world.
*/
public void kill() {
myMap.setCell(locY, locX, null);
}
/**
* Choose a random direction. If that cell is empty, move there.
* Make sure to set the movement flag so there is no possibility of moving the
* same organism again this turn.
* @see clearMoveFlag
*/
public void moveToEmpty() {
// Remember to avoid moving a critter that has already moved this turn....
// If you want a random number to choose a direction, try
// int dir = World.myRand(4);
// to generate an integer 0-3.
// YOUR CODE HERE!
if(!hasMoved){
myMap.killAndMove(locX, locY);
//System.out.println("LocX = " +locX + " and locY = " + locY);
hasMoved = true;
}
}
/**
* Set the location of the organism to the given coordinates.
* @param x
* @param y
*/
public void setLoc(int x, int y){
locX = x;
locY = y;
}
/**
* @return Return a single character representing the organism. To be
* used in constructing the printed representation of a World.
*/
public abstract String singleCharRepresenting();
}