Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1.  import java.util.List;  
  2.  import java.util.Iterator;  
  3.  import java.util.Random;  
  4.  /**  
  5.   * A simple model of a fox.  
  6.   * Foxes age, move, eat rabbits, and die.  
  7.   *  
  8.   * @author Gede
  9.   * @version (22/11/2018)
  10.   */  
  11.  public class Fox  
  12.  {  
  13.    // Characteristics shared by all foxes (static fields).  
  14.    // The age at which a fox can start to breed.  
  15.    private static final int BREEDING_AGE = 10;  
  16.    // The age to which a fox can live.  
  17.    private static final int MAX_AGE = 150;  
  18.    // The likelihood of a fox breeding.  
  19.    private static final double BREEDING_PROBABILITY = 0.35;  
  20.    // The maximum number of births.  
  21.    private static final int MAX_LITTER_SIZE = 5;  
  22.    // The food value of a single rabbit. In effect, this is the  
  23.    // number of steps a fox can go before it has to eat again.  
  24.    private static final int RABBIT_FOOD_VALUE = 7;  
  25.    // A shared random number generator to control breeding.  
  26.    private static final Random rand = Randomizer.getRandom();  
  27.    // Individual characteristics (instance fields).  
  28.    // The fox's age.  
  29.    private int age;  
  30.    // Whether the fox is alive or not.  
  31.    private boolean alive;  
  32.    // The fox's position.  
  33.    private Location location;  
  34.    // The field occupied.  
  35.    private Field field;  
  36.    // The fox's food level, which is increased by eating rabbits.  
  37.    private int foodLevel;  
  38.    /**  
  39.     * Create a fox. A fox can be created as a new born (age zero  
  40.     * and not hungry) or with a random age and food level.  
  41.     *  
  42.     * @param randomAge If true, the fox will have random age and hunger level.  
  43.     * @param field The field currently occupied.  
  44.     * @param location The location within the field.  
  45.     */  
  46.    public Fox(boolean randomAge, Field field, Location location)  
  47.    {  
  48.      age = 0;  
  49.      alive = true;  
  50.      this.field = field;  
  51.      setLocation(location);  
  52.      if(randomAge) {  
  53.        age = rand.nextInt(MAX_AGE);  
  54.        foodLevel = rand.nextInt(RABBIT_FOOD_VALUE);  
  55.      }  
  56.      else {  
  57.        // leave age at 0  
  58.        foodLevel = RABBIT_FOOD_VALUE;  
  59.      }  
  60.    }  
  61.    /**  
  62.     * This is what the fox does most of the time: it hunts for  
  63.     * rabbits. In the process, it might breed, die of hunger,  
  64.     * or die of old age.  
  65.     * @param field The field currently occupied.  
  66.     * @param newFoxes A list to add newly born foxes to.  
  67.     */  
  68.    public void hunt(List<Fox> newFoxes)  
  69.    {  
  70.      incrementAge();  
  71.      incrementHunger();  
  72.      if(alive) {  
  73.        giveBirth(newFoxes);        
  74.        // Move towards a source of food if found.  
  75.        Location newLocation = findFood(location);  
  76.        if(newLocation == null) {  
  77.          // No food found - try to move to a free location.  
  78.          newLocation = field.freeAdjacentLocation(location);  
  79.        }  
  80.        // See if it was possible to move.  
  81.        if(newLocation != null) {  
  82.          setLocation(newLocation);  
  83.        }  
  84.        else {  
  85.          // Overcrowding.  
  86.          setDead();  
  87.        }  
  88.      }  
  89.    }  
  90.    /**  
  91.     * Check whether the fox is alive or not.  
  92.     * @return True if the fox is still alive.  
  93.     */  
  94.    public boolean isAlive()  
  95.    {  
  96.      return alive;  
  97.    }  
  98.    /**  
  99.     * Return the fox's location.  
  100.     * @return The fox's location.  
  101.     */  
  102.    public Location getLocation()  
  103.    {  
  104.      return location;  
  105.    }  
  106.    /**  
  107.     * Place the fox at the new location in the given field.  
  108.     * @param newLocation The fox's new location.  
  109.     */  
  110.    private void setLocation(Location newLocation)  
  111.    {  
  112.      if(location != null) {  
  113.        field.clear(location);  
  114.      }  
  115.      location = newLocation;  
  116.      field.place(this, newLocation);  
  117.    }  
  118.    /**  
  119.     * Increase the age. This could result in the fox's death.  
  120.     */  
  121.    private void incrementAge()  
  122.    {  
  123.      age++;  
  124.      if(age > MAX_AGE) {  
  125.        setDead();  
  126.      }  
  127.    }  
  128.    /**  
  129.     * Make this fox more hungry. This could result in the fox's death.  
  130.     */  
  131.    private void incrementHunger()  
  132.    {  
  133.      foodLevel--;  
  134.      if(foodLevel <= 0) {  
  135.        setDead();  
  136.      }  
  137.    }  
  138.    /**  
  139.     * Tell the fox to look for rabbits adjacent to its current location.  
  140.     * Only the first live rabbit is eaten.  
  141.     * @param location Where in the field it is located.  
  142.     * @return Where food was found, or null if it wasn't.  
  143.     */  
  144.    private Location findFood(Location location)  
  145.    {  
  146.      List<Location> adjacent = field.adjacentLocations(location);  
  147.      Iterator<Location> it = adjacent.iterator();  
  148.      while(it.hasNext()) {  
  149.        Location where = it.next();  
  150.        Object animal = field.getObjectAt(where);  
  151.        if(animal instanceof Rabbit) {  
  152.          Rabbit rabbit = (Rabbit) animal;  
  153.          if(rabbit.isAlive()) {  
  154.            rabbit.setDead();  
  155.            foodLevel = RABBIT_FOOD_VALUE;  
  156.            // Remove the dead rabbit from the field.  
  157.            return where;  
  158.          }  
  159.        }  
  160.      }  
  161.      return null;  
  162.    }  
  163.    /**  
  164.     * Check whether or not this fox is to give birth at this step.  
  165.     * New births will be made into free adjacent locations.  
  166.     * @param newFoxes A list to add newly born foxes to.  
  167.     */  
  168.    private void giveBirth(List<Fox> newFoxes)  
  169.    {  
  170.      // New foxes are born into adjacent locations.  
  171.      // Get a list of adjacent free locations.  
  172.      List<Location> free = field.getFreeAdjacentLocations(location);  
  173.      int births = breed();  
  174.      for(int b = 0; b < births && free.size() > 0; b++) {  
  175.        Location loc = free.remove(0);  
  176.        Fox young = new Fox(false, field, loc);  
  177.        newFoxes.add(young);  
  178.      }  
  179.    }  
  180.    /**  
  181.     * Generate a number representing the number of births,  
  182.     * if it can breed.  
  183.     * @return The number of births (may be zero).  
  184.     */  
  185.    private int breed()  
  186.    {  
  187.      int births = 0;  
  188.      if(canBreed() && rand.nextDouble() <= BREEDING_PROBABILITY) {  
  189.        births = rand.nextInt(MAX_LITTER_SIZE) + 1;  
  190.      }  
  191.      return births;  
  192.    }  
  193.    /**  
  194.     * A fox can breed if it has reached the breeding age.  
  195.     */  
  196.    private boolean canBreed()  
  197.    {  
  198.      return age >= BREEDING_AGE;  
  199.    }  
  200.    /**  
  201.     * Indicate that the fox is no longer alive.  
  202.     * It is removed from the field.  
  203.     */  
  204.    private void setDead()  
  205.    {  
  206.      alive = false;  
  207.      if(location != null) {  
  208.        field.clear(location);  
  209.        location = null;  
  210.        field = null;  
  211.      }  
  212.    }  
  213.  }