/******************************* FILE HEADER ********************************** File: Fish.java Main Class: Aquarium.java Author: James D. Skrentny copyright 2000, all rights reserved Course: CS302: Lectures 1 & 2 Compiler: CodeWarrior IDE 4.0 (JDK 1.2) Platform: Windows NT 4.0 **************************** 80 columns wide *********************************/ import java.awt.Color; /** * Represents a Fish. * * Bugs: None known. **/ class Fish { private int foodPoints; // fish's energy, 0 to Tank.FISH_MAX_POINTS private Location location; // fish's Location in the tank private boolean direction; // fish's heading, Tank.RIGHT or Tank.LEFT /** * Constructs a new Fish at a random Location and randomly facing either * in the left or right direction. **/ public Fish ( ) { foodPoints = Tank.FISH_MAX_POINTS; location = new Location((int)(Math.random()*Tank.TANK_WIDTH + 1), (int)(Math.random()*Tank.WATER_HEIGHT + 1)); direction = (int) (Math.random()*2) == 0 ? Tank.RIGHT : Tank.LEFT; } /** * Returns the Location of this Fish. * * @return this fish's Location **/ public Location getLocation () { return location; } /** * Get the Color of this Fish. * A weak fish is white, otherwise it's pink. * * @return this fish's Color **/ public Color getColor () { if (isWeak()) return Color.white; else return Color.pink; } /** * Get the direction of this Fish * * @return this fish's direction **/ public boolean getDirection () { return direction; } /** * Get the number of food points of this Fish. * * @return this fish's food points **/ public int getFoodPoints () { return foodPoints; } /** * Determine is this Fish is alive. * * @return true if this fish is alive, false otherwise */ public boolean isAlive () { return foodPoints > 0; } /** * Determine if this Fish is dead. * * @return true if this fish is dead, false otherwise */ public boolean isDead () { return !isAlive(); } /** * Determine is this Fish is weak. * * @return true if this fish is weak, false otherwise */ public boolean isWeak () { return foodPoints < Tank.FISH_MAX_POINTS*Tank.STRENGTH_THRESHOLD; } /** * Move this fish, if living, one step from its current location, but it * can't move backwards. **/ public void move ( ) { if (isAlive()) { int x = location.getX(); // fish's current x-coord int y = location.getY(); // fish's current x-coord // change directions if at wall if ( ((x <= 0) && (direction == Tank.LEFT)) || ((x >= Tank.TANK_WIDTH) && (direction == Tank.RIGHT)) ) { direction = !direction; } else { // Simple Move Algorithm: // randomly choose a move until a valid move is found // This isn't a very efficient moving algorithm (we may have // to choose a lot of moves if the fish is in a corner), but // it is easy to code. boolean invalidMove = true; // true iff a valid move found int dx, dy; //change in x and y coordinates do { // randomly choose a change of location switch ((int)(Math.random()*5)) { // 5 ways to move case 0: dx = 0; dy = 1; break; // straight down case 1: dx = 1; dy = 1; break; // diagonal down case 2: dx = 1; dy = 0; break; // straight across case 3: dx = 1; dy = -1; break; // diagonal up default: dx = 0; dy = -1; break; // straight up } // if facing left, make dx negative if (direction == Tank.LEFT) { dx = -dx; } // compute new coordinates int newX = x + dx; int newY = y + dy; // check if new location is valid if ((newX >= 0) && (newX <= Tank.TANK_WIDTH) && (newY >= 0) && (newY <= Tank.WATER_HEIGHT)) { invalidMove = false; } } while (invalidMove); // move Fish location.move(dx, dy); } // decrement foodPoints foodPoints -= Tank.FISH_MOVE_COST; } } /** * This Fish attempts to eat at the specified FoodCenter. * * @param fc the specified food center **/ public void eat (FoodCenter fc) { if (isAlive()) { int amountEaten = fc.foodWanted(Tank.FISH_MAX_POINTS - foodPoints); foodPoints += amountEaten; } } /** * Kills the Fish because it was eaten by a piranha. **/ public void gotEatten () { foodPoints = 0; } /** * Get the information about this Fish. * * @return a String representation of this fish **/ public String toString () { String info = "Fish "; if (isAlive()) { info += " Direction: "; if (direction == Tank.RIGHT) info += "Right"; else info += "Left"; info += " Location: " + location; info += " Food points: " + foodPoints; } else { info += " is dead"; } return info; } }