程序代写代做代考 Java import java.util.*;

import java.util.*;

/**
* Creates and maintains a “field” for the rabbit and fox, and sets
* up a number of methods to be used by animals. This class, rather
* than the Animal class, is in charge of letting animals move and
* look around–this makes it harder for an animal to “cheat” by
* knowing things it shouldn’t know, or making moves it shouldn’t
* be allowed to make.
*
* @author David Matuszek
* @version October 26, 2001
*/
public class Model {

// define instance variables
private Object[][] field;
private int numberOfRows;
private int numberOfColumns;
private Rabbit rabbit;
private Fox fox;
private int foxRow;
private int foxColumn;
private int rabbitRow;
private int rabbitColumn;
private Bush bush; // all bushes are the same bush
private long oldRandomSeed;
private static Random randomNumberGenerator = new Random();
private boolean isUnderConstruction;

/** Flag used to end the game when the fox wins */
boolean rabbitIsAlive;
/** Flag to tell when the game ends */
boolean gameIsOver;
/** The number of turns taken so far in the game */
int stepsTaken;
/** The number of turns the rabbit has to survive in order to win */
final int MAX_NUMBER_OF_STEPS = 100;
/** The number of rows in the field */
static int NUMBER_OF_ROWS;
/** The number of columns in the field */
static int NUMBER_OF_COLUMNS;
/** Remember each time animal does look(direction) for later viewing */
static Vector looks = new Vector();
/** True if rabbit’s turn, false if fox’s turn */
static boolean isRabbitsTurn;

// define some class constants to represent directions
/** Represents the direction NORTH */
static final int N = 0;
/** Represents the direction NORTHEAST */
static final int NE = 1;
/** Represents the direction EAST */
static final int E = 2;
/** Represents the direction SOUTHEAST */
static final int SE = 3;
/** Represents the direction SOUTH */
static final int S = 4;
/** Represents the direction SOUTHWEST */
static final int SW = 5;
/** Represents the direction WEST */
static final int W = 6;
/** Represents the direction NORTHWEST */
static final int NW = 7;
/** Represents the direction “right here” */
static final int STAY = 8;
/** The smallest int representing a direction */
static final int MIN_DIRECTION = 0;
/** The largest int representing a direction */
static final int MAX_DIRECTION = 7;

// define some constants to represent objects
/** Indicates the edge of the playing field */
final static int EDGE = 0;
/** Indicates a bush */
final static int FOX = 1;
/** Indicates a rabbit */
final static int RABBIT = 2;
/** Indicates a fox */
final static int BUSH = 3;

/**
* Constructs a model that uses the given field.
*
* @param field the field to be used by the model
*/
Model(Object[][] field) {
this.field = field;
NUMBER_OF_ROWS = numberOfRows = field.length;
NUMBER_OF_COLUMNS = numberOfColumns = field[0].length;
reset();
}

/**
* Sets up a new hunt.
*/
void reset() {
gameIsOver = false;
rabbitIsAlive = true;
isRabbitsTurn = false; // will be changed before first move
stepsTaken = 0;
// populate using new random numbers
oldRandomSeed = randomNumberGenerator.nextLong();
randomNumberGenerator.setSeed(oldRandomSeed);
populate();
}

/**
* Sets up the same hunt all over again, using old random seed.
*/
void replay() {
gameIsOver = false;
rabbitIsAlive = true;
isRabbitsTurn = false; // will be changed before first move
stepsTaken = 0;
// populate using same random numbers as last time
randomNumberGenerator.setSeed(oldRandomSeed);
populate();
}

/**
* Puts a rabbit, a fox, and some bushes in the field.
*/
void populate () {

// protect against calls during creation of game
isUnderConstruction = true;

// create some abbreviations, just to save some typing
int numRows = numberOfRows;
int numCols = numberOfColumns;

// remove any previous contents of field
for (int i = 0; i < numRows; i++) for (int j = 0; j < numCols; j++) field[i][j] = null; // put the rabbit in a random location rabbitRow = random(0, numRows - 1); rabbitColumn = random(0, numCols - 1); isRabbitsTurn = true; // so error messages can place the blame rabbit = new Rabbit(this, rabbitRow, rabbitColumn); field[rabbitRow][rabbitColumn] = rabbit; // put the fox in a random location, not too close to the rabbit int distance; do { foxRow = random(0, numRows - 1); foxColumn = random(0, numCols - 1); distance = Math.max(Math.abs(foxRow - rabbitRow), Math.abs(foxColumn - rabbitColumn)); } while (distance < (numRows + numCols) / 4); isRabbitsTurn = false; // so error messages can place the blame fox = new Fox(this, foxRow, foxColumn); field[foxRow][foxColumn] = fox; // put in some random bushes // (since bushes don't do anything, we cheat and use the same bush) bush = new Bush(); int numberOfBushes = (numRows * numCols) / 20; for (int i = 0; i < numberOfBushes; i++) { int bushRow = random(0, numRows - 1); int bushColumn = random(0, numCols - 1); if (field[bushRow][bushColumn] == null) { field[bushRow][bushColumn] = bush; } else i--; } // finish isUnderConstruction = false; } /** * Gives one animal a chance to move. * */ void allowSingleMove() { Animal animal; int direction; int newRow; int newColumn; // make sure it's legal to allow moves if (gameIsOver) return; // prepare to save info about looks (for later use by view) looks.clear(); // decide whose turn it is now (change isRabbitsTurn) isRabbitsTurn = !isRabbitsTurn; if (isRabbitsTurn) { animal = rabbit; } else { // fox's turn animal = fox; } // ask the animal to decide a direction direction = animal.decideMove(); // if move is legal, do it if (direction != STAY) { newRow = animal.row + rowChange(direction); newColumn = animal.column + columnChange(direction); if (legalLocation(newRow, newColumn) && !(field[newRow][newColumn] instanceof Bush)) { moveAnimal(animal, newRow, newColumn); } } // check whether move was fatal for rabbit if (rabbit.row == fox.row && rabbit.column == fox.column) { rabbitIsAlive = false; gameIsOver = true; } // increment steps taken; check for end of game after fox's turn if (isRabbitsTurn) { stepsTaken++; } else if (stepsTaken >= MAX_NUMBER_OF_STEPS) {
gameIsOver = true;
}
}

/**
* Gives the rabbit a chance to move, then gives the fox
* a chance to move.
*/
void allowMoves() {
allowSingleMove();
allowSingleMove();
}

/**
* Utility method to absolutely move an animal from
* one location to another. Any error checking must
* be done before this method is invoked.
*
* @param animal the animal to be relocated
* @param newRow the new row number for the animal
* @param newColumn the new column number for the animal
*/
private void moveAnimal(Animal animal, int row, int column) {

// perform move
field[animal.row][animal.column] = null;
field[row][column] = animal;
animal.row = row;
animal.column = column;

if (animal instanceof Rabbit) {
rabbitRow = row;
rabbitColumn = column;
}
else { // animal must be a fox
foxRow = row;
foxColumn = column;
}
}

/**
* Utility method to choose a random integer from min
* to max, inclusive.
*
* @param min the smallest number to be returned
* @param max the largest number to be returned
* @return a random number N, where min <= N <= max
*/
static int random(int min, int max) {
return randomNumberGenerator.nextInt(max – min + 1) + min;
}

/**
* Determines how moving in the given direction affects the
* row number.
*
* @param direction the direction in which to move
* @return the amount by which the row number will change
*/
static int rowChange(int direction) {
int change = 0;
switch (direction) {
case N:
case NE:
case NW:
change = -1;
break;
case S:
case SE:
case SW:
change = +1;
break;
}
return change;
}

/**
* Determines how moving in the given direction affects the
* column number.
*
* @param direction the direction in which to move
* @return the amount by which the column number will change
*/
static int columnChange(int direction) {
int change = 0;
switch (direction) {
case W:
case NW:
case SW:
change = -1;
break;
case E:
case NE:
case SE:
change = +1;
}
return change;
}

/** Determines whether the given row and column numbers represent
* a legal location in the field.
*
* @param row the row number
* @param column the column number
*/
boolean legalLocation(int row, int column) {
return row >= 0 && row < numberOfRows && column >= 0 && column < numberOfColumns; } /** * Determines what can be seen from a given location, looking * in a given direction. * * @param row the row of the object doing the looking * @param column the column of the object doing the looking * @param direction the direction of the look * @return the object seen */ int look(int row, int column, int direction) { // check for illegal request if (!verifyLocation("look", row, column)) { return Model.EDGE; } // save the fact that this look was performed--this is // only here for purposes of later viewing looks.add(new Integer(direction)); // decode direction into its x-y components int rowDelta = rowChange(direction); int columnDelta = columnChange(direction); // check in that direction until you see something // (if nothing else, you will eventually see the edge of the // array, thus the loop will terminate)
while (true) {
row = row + rowDelta;
column = column + columnDelta;
if (!legalLocation(row, column))
return EDGE;
if (field[row][column] instanceof Rabbit)
return RABBIT;
if (field[row][column] instanceof Fox)
return FOX;
if (field[row][column] instanceof Bush)
return BUSH;
}
}

/**
* Determines the distance to the nearest thing, or to the
* edge of the field, looking in a given direction.
*
* @param row the row of the object doing the looking
* @param column the column of the object doing the looking
* @param direction the direction of the look
* @return the distance
*/
int distance(int row, int column, int direction) {

// check for illegal request
// check for illegal request
if (!verifyLocation(“distance”, row, column)) {
return 1000;
}

// decode direction into its x-y components
int rowDelta = rowChange(direction);
int columnDelta = columnChange(direction);

// check in that direction until you see something
// (if nothing else, you will eventually see the edge of the
// array, thus the loop will terminate)
int steps = 0;
while (true) {
row = row + rowDelta;
column = column + columnDelta;
steps++;
if (!legalLocation(row, column) || field[row][column] != null) {
return steps;
}
}
}

/**
* Given a direction and a number of times to make 1/8 turn clockwise,
* return the resultant direction.
*
* @param direction the initial direction
* @param number of 45 degree turns clockwise
* @return the resultant direction
*/
static int turn(int direction, int number) {
int mod = (direction + number) % (MAX_DIRECTION – MIN_DIRECTION + 1);
if (mod >= MIN_DIRECTION) return mod;
else return 8 + mod;
}

/**
* Ensures that the rabbit or fox is at the location it claims
* to be.
*
* @param methodName the name of the method being used
* @param row the row that the caller claims the animal is in
* @param column the column that the caller claims the animal is in
* @return true if the location is valid
*/
private boolean verifyLocation(String methodName, int row, int column) {
if (isUnderConstruction) {
System.out.println(“Error! Call to ” + methodName +
” while the hunt is still under construction!”);
return false;
}

if (isRabbitsTurn) {
if (field[row][column] == rabbit) {
return true;
}
else {
System.out.println(“Illegal call by rabbit: ” + methodName +
“(direction, ” + row + “, ” + column + “)”);
System.out.println(“The rabbit is actually at row ” +
rabbitRow + “, column ” + rabbitColumn);
return false;
}
}
else { // fox’s turn
if (field[row][column] == fox) {
return true;
}
else {
System.out.println(“Illegal call by fox: ” + methodName +
“(direction, ” + row + “, ” + column + “)”);
System.out.println(“The fox is actually at row ” +
foxRow + “, column ” + foxColumn);
return false;
}
}
}
}