/* Ocean.java */

/* DO NOT CHANGE THIS FILE. */
/* YOUR SUBMISSION MUST WORK CORRECTLY WITH _OUR_ COPY OF THIS FILE. */

import java.util.*;

/**
 *  The Ocean class is an abstract class that specifies the methods that
 *  should be present in any implementation of an Ocean.  In addition to
 *  the methods listed below, there should also be a constructor of the form
 *
 *      public DenseOcean(int i, int j);
 *
 *  or
 *
 *      public SparseOcean(int i, int j);
 *
 *  that creates an ocean having width i and height j.
 *
 *  In this assignment, you are required to implement two subclasses of Ocean,
 *  named DenseOcean and SparseOcean.  Descriptions of the methods you must
 *  implement appear below.  See the README file accompanying this project for
 *  additional details on DenseOcean and SparseOcean.
 *
 *  @author Jonathan Shewchuk
 */

public abstract class Ocean {

  /**
   *  width() returns the width of an Ocean object.
   *  @return the width of the ocean.
   */

  public abstract int width();

  /**
   *  height() returns the height of an Ocean object.
   *  @return the height of the ocean.
   */

  public abstract int height();

  /**
   *  addFish() places a fish in cell (x, y) if the cell is empty.  If the
   *  cell is already occupied, leave the cell as it is.
   *  @param x is the x-coordinate of the cell to place a fish in.
   *  @param y is the y-coordinate of the cell to place a fish in.
   */

  public abstract void addFish(int x, int y);

  /**
   *  addShark() places a shark in cell (x, y) if the cell is empty.  The
   *  shark is considered to be a well-fed newborn.  If the cell is already
   *  occupied, leave the cell as it is.
   *  @param x is the x-coordinate of the cell to place a shark in.
   *  @param y is the y-coordinate of the cell to place a shark in.
   */

  public abstract void addShark(int x, int y);

  /**
   *  timeStep() performs a simulation timestep as described in README.
   *  @param starveTime is the number of timesteps a shark can survive without
   *         eating.
   *  @return an ocean representing the elapse of one timestep.
   */

  public abstract Ocean timeStep(int starveTime);

  /**
   *  restartCritters() and nextCritter() are two methods that work together
   *  to return all the animals in the ocean, one by one.  Each time
   *  nextCritter() is invoked, it returns a different animal (represented
   *  as a Critter object), until every animal has been returned.  After every
   *  fish and shark has been returned, nextCritter() returns null, which
   *  lets the animation routine know that there are no more fish or sharks
   *  left to draw, so the simulation can proceed.
   *
   *  The restartCritters() method resets the enumeration, so that
   *  nextCritter() will once again enumerate all the animals as if
   *  nextCritter() were being invoked for the first time.
   *
   *  (Note:  Don't worry about what might happen if nextCritter() is
   *  interleaved with addFish() or addShark(); it won't happen.)
   */

  /**
   *  restartCritters() resets the enumeration as described above, so that
   *  nextCritter() will enumerate all the fish and sharks from the beginning.
   */

  public abstract void restartCritters();

  /**
   *  nextCritter() returns the next fish or shark in the enumeration, as
   *  described above.  If the animals have been exhausted, it returns null.
   *  It doesn't matter what order the animals are returned in, as long as
   *  each is returned only once.
   *  @return the next fish or shark in the enumeration.
   */

  public abstract Critter nextCritter();

  /**
   *  check() tests the integrity of the data structure used to represent
   *  an ocean, and prints warning messages if there are inconsistencies.
   *  In the DenseOcean class, this routine needn't do anything.  In the
   *  SparseOcean class, this routine should check for inconsistencies in
   *  the run-length encoding, as described in the accompanying README file.
   */

  public abstract void check();

}