Catfish.java
上传用户:taztks
上传日期:2022-04-09
资源大小:37k
文件大小:14k
- import java.util.Vector;
- /*
- * Created at 11.00 on 26 november 2009
- *
- */
- /**
- * Catfish - simulates a catfish - can swim, eat, and consume
- * energy in the process.
- *
- * @author Adilbek Khalikhov
- *
- */
- public class Catfish extends LivingBeing {
- /**
- * The catfish is born "alive".
- * Then it dies, becoming a corpse.
- */
- private static final String ALIVE = "alive";
- /**
- * The catfish is born "alive".
- * Then it dies, becoming a "dead" corpse.
- */
- private static final String DEAD = "dead";
- /**
- * Energy needed to swim in a block of time.
- */
- private static final int ENERGY_TO_SWIM = 2;
- /**
- * debugging level.
- */
- private static final int DEBUG = 0;
-
- /**
- * Energy needed to look for food once.
- */
- private static final int ENERGY_TO_LOOK_FOR_FOOD = 1;
-
- /**
- * Energy expended to eat once.
- */
- private static final int ENERGY_TO_EAT = 1;
-
- /**
- * Energy gained when a full meal is eaten.
- */
- private static final int ENERGY_IN_A_FULL_MEAL = 10;
- /**
- * Energy needed to look for food once.
- */
- private static final int ENERGY_TO_LOOK_FOR_PREDATORS = 5;
-
- /**
- * Lowest possible energy needed for a baby to survive.
- */
- private static final int BABY_MIN_ENERGY = 15;
-
- /**
- * Maximum energy that a baby can store.
- */
- private static final int BABY_MAX_ENERGY = 100;
- /**
- * For each block of time, the min energy grows by a certain amount
- */
- private static final int MIN_ENERGY_GROWTH_INCREMENT = 5;
-
- /**
- * For each block of time, the max energy grows by a certain amount
- */
- private static final int MAX_ENERGY_GROWTH_INCREMENT = 10;
- /**
- * String constant - used to indicate the direction catfish is facing.
- */
- private static final String RIGHT = "right";
- /**
- * String constant - used to indicate the direction catfish is facing.
- */
- private static final String LEFT = "left";
- /**
- * String constant - used to indicate the direction catfish is facing.
- */
- private static final String UP = "up";
- /**
- * String constant - used to indicate the direction catfish is facing.
- */
- private static final String DOWN = "down";
- /**
- * Name of species
- */
- private static final String SPECIES = "Catfish";
- /**
- * Row-wise location of the catfish
- */
- private int row;
- /**
- * Column-wise location of the catfish
- */
- private int column;
- /**
- * Is the catfish dead or alive?
- */
- private String deadOrAlive;
- /**
- * If a predator is nearby, the catfish will be alarmed
- */
- private boolean alarmed = false;
-
- /**
- * Amount of energy the catfish has.
- */
- private int energy;
- /**
- * Age expressed as blocks of time lived
- */
- private int age = 0;
- /**
- * Name of this catfish.
- */
- private final String name;
- /**
- * The simulation to which this catfish belongs.
- * This is needed so the catfish can send a message
- * to simulation and ask
- * for prey (or predator) in the neighboring locations.
- * Prey is food. Food is good!
- */
- private Simulation simulation;
- /**
- * Minimum energy level needed to survive.
- * The minimum could increase as the individual grows.
- */
- private int minEnergy;
-
- /**
- * Maximum energy level that the catfish could carry.
- * The maximum could change as the individual grows.
- */
- private int maxEnergy;
-
- /**
- * Which direction am I facing.
- */
- private String direction;
- /**
- *
- * Number of Catfish created
- */
- private static int nCatfishCreated = 0;
- /**
- * Constructor. Initialize a catfish to start life at a specified
- * location with a specified energy. If location is out of bounds,
- * locate the catfish at the nearest edge.
- *
- * @param initialRow - the row at which the catfish is located
- * @param initialColumn - the column at which the catfish is located
- * @param initialSimulation - the simulation that the catfish belongs to
- */
- public Catfish(
- int initialRow,
- int initialColumn,
- Simulation initialSimulation) {
- simulation = initialSimulation;
- deadOrAlive = ALIVE;
- // Set the Row within bounds
- if (initialRow > initialSimulation.getLastRow()) {
- row = initialSimulation.getLastRow();
- } else if (initialRow < initialSimulation.getFirstRow()) {
- row = initialSimulation.getFirstRow();
- } else {
- row = initialRow;
- }
- // Set the Column within bounds
- if (initialColumn > initialSimulation.getLastColumn()) {
- column = initialSimulation.getLastColumn();
- } else if (initialColumn < initialSimulation.getFirstColumn()) {
- column = initialSimulation.getFirstColumn();
- } else {
- column = initialColumn;
- }
- // Set the minEnergy and maxEnergy
- minEnergy = BABY_MIN_ENERGY;
- maxEnergy = BABY_MAX_ENERGY;
- energy =
- simulation.getRand().nextInt(maxEnergy - minEnergy) + minEnergy;
- age = 0;
- name = SPECIES + nCatfishCreated;
-
- direction = RIGHT; // Start by facing east.
- ++nCatfishCreated;
- }
-
- /**
- * Get the row at which the catfish is located
- *
- * @return - the row of the catfish's location.
- */
- public int getRow() {
- return row;
- }
- /**
- * Get the column at which the catfish is located
- *
- * @return - the column of the catfish's location.
- */
- public int getColumn() {
- return column;
- }
- /**
- * Get the catfish's age
- *
- * @return the age of the catfish expressed in blocks of time
- */
- public int getAge() {
- return age;
- }
- /**
- * Color of the catfish expressed in hex notation.
- * For example, the "green-est" color is "#00FF00",
- * "blue-est" is "#0000FF", the "red-est" is "#FF0000".
- *
- * @return the rgb color in hex notation. preceded by a pound character '#'
- */
- public String getColor() {
- return "#FFFFFF"; // default is white.
- }
- /**
- * Get the name of this catfish
- *
- * @return the name of the catfish.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Get the minimum energy needed to live.
- *
- * @return the minimum energy needed for the catfish to live.
- */
- private int getMinEnergy() {
- return minEnergy;
- }
-
- /**
- * get the maximum energy that the catfish can carry.
- *
- * @return the maximum energy the catfish can carry.
- */
- private int getMaxEnergy() {
- return maxEnergy;
- }
-
- /**
- * Get the energy currently carried by the catfish.
- *
- * @return current energy level of the organism
- */
- public int getEnergy() {
- return energy;
- }
- /**
- * Sets energy level.
- * If new energy level is less than minimum energy level, the organism dies.
- * New energy level is capped at maximum energy level.
- */
- private void setEnergy(int newEnergy) {
-
- if (newEnergy < getMinEnergy()) {
- energy = newEnergy;
- die();
- } else if (newEnergy > getMaxEnergy()) {
- energy = getMaxEnergy();
- } else {
- energy = newEnergy;
- }
- }
- /**
- * Die: Change the deadOrAlive to DEAD.
- */
- public void die() {
- deadOrAlive = DEAD;
- }
- /**
- * Is the catfish dead?
- *
- * @return <code>true</code> if dead. <code>false</code>, otherwise.
- */
- public boolean isDead() {
- return (deadOrAlive == DEAD);
- }
- /**
- * Get the direction faced by the catfish.
- *
- * @return the facing direction.
- */
- private String getDirection() {
- return direction;
- }
- /**
- * Is the catfish hungry?
- *
- * @return True, if hungry. False, otherwise.
- */
- private boolean isHungry() {
-
- // Hungry, if current energy level is less than twice the
- // amount needed for survival.
- return (getEnergy() < (2 * getMinEnergy()));
- }
- /**
- * Move the catfish to a new row, if new row is within lake bounds.
- *
- * @param newRow - the row to move to.
- * @return the row moved to. Lake boundary limits movement. -1, if dead.
- */
- private int moveToRow(int newRow) {
-
- if (isDead()) {
- return -1;
- }
- // Keep the new value within lake boundary.
- if (newRow > simulation.getLastRow()) {
- newRow = simulation.getLastRow();
- } else if (newRow < simulation.getFirstRow()) {
- newRow = simulation.getFirstRow();
- }
- // I might face a new direction.
- if (newRow < row) {
- direction = UP;
- } else if (newRow > row) {
- direction = DOWN;
- }
- row = newRow;
- return row;
- }
- /**
- * Move the catfish to a new column, if new column is within lake bounds.
- *
- * @param newColumn - the column to move to.
- * @return the column moved to. Lake boundary limits movement.
- */
- private int moveToColumn(int newColumn) {
- if (isDead()) {
- return -1;
- }
- // System.out.println("column = " + column + ", newCOlumn = " + newColumn);
- // System.out.flush();
- // Keep the new value within lake boundary.
- if (newColumn > simulation.getLastColumn()) {
- newColumn = simulation.getLastColumn();
- } else if (newColumn < simulation.getFirstColumn()) {
- newColumn = simulation.getFirstColumn();
- }
- // I might face a new direction.
- if (newColumn < column) {
- direction = LEFT;
- } else if (newColumn > column) {
- direction = RIGHT;
- }
- column = newColumn;
- return column;
- }
- /**
- * Is the catfish alarmed?
- *
- * @return Is the catfish alarmed?
- **/
- public boolean getAlarmed() {
- return alarmed;
- }
- /**
- * Set the catfish's alarmed state
- *
- **/
- public void setAlarmed(boolean alarm) {
- alarmed = alarm;
- }
- /**
- * This individual belongs to the Catfish species.
- *
- * @return The string indicating the species
- */
- public String getSpecies() {
- return SPECIES;
- }
- /**
- * Catfish should be displayed as an image.
- *
- * @return a constant defined in {@link Simulation#IMAGE Simulation} class
- */
- public String getDisplayMechanism() {
- return Simulation.IMAGE;
- }
- /**
- * Get the image of the catfish
- *
- * @return filename of Catfish image
- */
- public String getImage() {
-
- if (getDirection() == RIGHT) {
- if(getAlarmed()) {
- return "/Catfish-red-right.gif";
- }
- return "/Catfish-right.gif";
- }
- if (getDirection() == LEFT) {
- if(getAlarmed()) {
- return "/Catfish-red-left.gif";
- }
- return "/Catfish-left.gif";
- }
- if (getDirection() == UP) {
- if(getAlarmed()) {
- return "/Catfish-red-up.gif";
- }
- return "/Catfish-up.gif";
- }
- if (getDirection() == DOWN) {
- if(getAlarmed()) {
- return "/Catfish-red-down.gif";
- }
- return "/Catfish-down.gif";
- }
-
- return "Catfish-right.gif";
- }
- /**
- * Look for food in the neighborhood. Consume some energy in the process.
- *
- * @return a neighboring algae that is food.
- */
- private AlgaeColony lookForFoodInNeighborhood() {
-
- int neighborIndex;
- // Looking for food consumes energy.
- setEnergy(getEnergy() - ENERGY_TO_LOOK_FOR_FOOD);
- if (isDead()) {
- return null;
- }
- Vector neighbors =
- simulation.getNeighbors(getRow(), getColumn(), 1);
- for (neighborIndex = 0;
- neighborIndex < neighbors.size();
- ++neighborIndex) {
- if (neighbors.get(neighborIndex) instanceof AlgaeColony) {
- return (AlgaeColony) neighbors.get(neighborIndex);
- }
- }
- return null;
- }
-
- /**
- * Swim to a new location if possible.
- * Consumes some energy.
- */
- private void swimIfPossible() {
- AlgaeColony food;
- if (isDead()) {
- return;
- }
- // If hungry, swim to a location where there is food.
- if (isHungry()) {
- // Naive swimming - We are not checking if a predator is in the destination.
- food = lookForFoodInNeighborhood();
- if (food != null) {
- // Consume energy to swim.
- setEnergy(getEnergy() - ENERGY_TO_SWIM);
- if (isDead()) {
- return;
- }
- if (DEBUG > 50) {
- System.out.println(
- "moving from (row, col) = ("
- + getRow()
- + ", "
- + getColumn()
- + ") to ("
- + food.getRow()
- + ", "
- + food.getColumn()
- + ")");
- }
- moveToRow(food.getRow());
- moveToColumn(food.getColumn());
- } else {
- // Do not swim. Need to conserve energy.
- }
- return;
- } else {
- // Consume energy to swim.
- setEnergy(getEnergy() - ENERGY_TO_SWIM);
- if (isDead()) {
- return;
- }
- // Swim at random in one of four directions.
- // Naive swimming - We are not checking if a predator is in the destination.
- int direction = simulation.getRand().nextInt(4);
- // Swim up.
- if (direction == 0) {
- moveToRow(getRow() - 1);
- }
- // Swim down.
- if (direction == 1) {
- moveToRow(getRow() + 1);
- }
- // Swim left.
- if (direction == 2) {
- moveToColumn(getColumn() - 1);
- }
- // Swim right.
- if (direction == 3) {
- moveToColumn(getColumn() + 1);
- }
- }
- }
- /**
- * Eat food if available.
- *
- */
- private void eatIfPossible() {
- Vector foodMaybe;
- int neighborIndex;
- if (isDead()) {
- return;
- }
- foodMaybe = simulation.getNeighbors(getRow(), getColumn(), 0);
- for (neighborIndex = 0;
- neighborIndex < foodMaybe.size();
- ++neighborIndex) {
- if (foodMaybe.get(neighborIndex) instanceof AlgaeColony) {
- AlgaeColony alg = (AlgaeColony) foodMaybe.get(neighborIndex);
- int energyGained = alg.giveUpEnergy(ENERGY_IN_A_FULL_MEAL);
- // Spend ENERGY_TO_EAT, irrespective of amount gained.
- setEnergy(getEnergy() + energyGained - ENERGY_TO_EAT);
- return;
- }
- }
- }
- /**
- * Catfish lives its life. It may lose or gain energy.
- */
- public void liveALittle() {
- if (isDead()) {
- return;
- }
- age = age + 1;
- swimIfPossible();
- eatIfPossible();
- // As I am growing bigger, I need to increase my minEnergy
- // and maxEnergy.
- minEnergy = getMinEnergy() + MIN_ENERGY_GROWTH_INCREMENT;
- maxEnergy = getMaxEnergy() + MAX_ENERGY_GROWTH_INCREMENT;
-
- alarmedIfNecessary();
- }
-
- /**
- * become alarmed if necessary.
- *
- */
- private void alarmedIfNecessary() {
- setAlarmed(findPredator());
- }
-
-
- private boolean findPredator() {
-
- /* Student To Do: Add code to find any predators within 1 block.
- * If a prdator is found, return true, else return false
- */
-
-
- setEnergy(getEnergy()-ENERGY_TO_LOOK_FOR_PREDATORS);
-
- if (isDead()) {
- return false;
- }
- Vector localVector = simulation.getNeighbors(getRow(), getColumn(), 1);
- int index=0;
- if (index<localVector.size())
- {
- return localVector.get(index) instanceof Crocodile;
- }
- return false;
- }
-
- }