/*
 * ManifestDestiny.java
 *
 * Created on July 22, 2001, 9:06 PM
 */

import java.util.*;
import java.io.*;

/**
 * This is the driver class which creates and runs the island simulator
 */
public class ManifestDestiny
{
    // Input stream delimiter
    public static final String DELIMITER = " ";
    public static final String START = "START";
    public static final String END = "END";

    // Vector of islands read in from the input stream
    private Vector islands;

    // Number of rounds to play, which is read in as input
    private int turns;

    /* Creates new ManifestDestiny */
    public ManifestDestiny()
    {
		// Call the super classe constructor
		super();

		// Initialize the simulator
		init();
    }

    // Initialize the island object and tribes vector
    protected void init()
    {
		// Fill the island object with the data from the input file
		islands = getIslands();
    }

    // This method reads in the data from the input file and fills the island's
    // matrix with the data.
    protected Vector getIslands()
    {
		int rows = 0;
		int columns = 0;
		int rounds;
		String line = null;
		BufferedReader input = null;
		StringBuffer data = null;
		Island island;
		Vector islands = new Vector();
		StringTokenizer st = null;
		String token = null;
		
		try
		{
	    	// Create the input reader
		    input = new BufferedReader( new InputStreamReader( System.in ) );
			
	    	// Read the first line of data which should be the start string
			line = input.readLine();
			st = new StringTokenizer( line );
			token = st.nextToken();
			
	    	while( ( token != null ) && ( token.equals( START ) ) )
	    	{	
				// Read the number of rounds 
				rounds = Integer.parseInt( st.nextToken() );				
						
				// Read the first line of data
				line = input.readLine();
						
				// Calculate the number of columns
				columns = ( new StringTokenizer( line, DELIMITER ).countTokens() / 2 );
			
				// Create the StringBuffer which is going to hold the data 
				data = new StringBuffer();
			
				// Loop through the data to count the number or rows and to build the
				// data string.
				rows = 0;
				while ( ( line != null ) && ( !line.equals( END ) ) )
				{
		    		rows++;
		    		data.append( line + DELIMITER );
		    		line = input.readLine();
				}
						
				if ( line.equals( END ) )
				{
		    		// Create the island object
		    		island = new Island( rounds, rows, columns );
		
		    		// Populate the island with the data
		    		island.populate( data );
				
		    		// Add the island to the islands vector
		    		islands.add( island );
				}
				else
				{
		    		throw new IOException( "Missing " + END );
				}
				
				// Read in the next line of input
				line = input.readLine();
				
				if ( ( line != null ) && ( !token.equals( "" ) ) )
				{
					st = new StringTokenizer( line );
					token = st.nextToken();
				}
				else
				{
					token = null;
				}
	    	}
		}
		catch ( NumberFormatException nfe )
		{
	    	// There was non-numeric data for the food/population column of input
	    	System.out.println( "Invalid data in the input.  Non-numeric perhaps" );
	    	System.out.println( nfe.getMessage() );
	    	System.exit( 0 );
		}
		catch ( NoSuchElementException nsee )
		{
	    	// There was some data missing.  Perhaps some of the rows of data
	    	// had less input than others.
	    	System.out.println( "Invalid data in the input.  Not enough data." );
	    	System.out.println( nsee.getMessage() );
	    	System.exit( 0 );
		}
		catch ( IOException ioe )
		{
	    	// There was some sort of i/o error reading the input.
		    System.out.println( "Error reading the input." );
	    	System.out.println( ioe.getMessage() );
	    	System.exit( 0 );
		}
		finally
		{
	    	// Make sure the inputstream is closed
	    	if ( input != null )
	    	{
				try
				{
		    		input.close();
				}
				catch( IOException ioe )
				{
		    		// Do nothing
				}
	    	}
		}
		
		return islands;
    }
	
    // This method starts the simulator.  It calls the nextRound method once for
    // each round.  The number of rounds was read in from the input file
    private void start()
    {
		Enumeration islandEnum = islands.elements();
		Island island;
	
		// Loop through each of the sets of island data that was read in.
		while( islandEnum.hasMoreElements() )
		{
	
	    	// Get the island
	    	island = (Island)islandEnum.nextElement();
			
	    	// Start that islands simulation
	    	island.start();
			
	    	// Print the results of that island
	    	island.printResults();
		}
    }
	
    /**
    * This is the main method which is the starting point for the driver class.
    */
    public static void main (String args[])
    {
		// Create the manifest destiny simulator
		ManifestDestiny simulator = new ManifestDestiny();
		
		// Start the simulator
		simulator.start();
    }
}

/****************************************************************************
 * Interface for which the Tribe class implements
 * Defines constants and methods for which the Tribe class must implement
 ****************************************************************************/
interface TribeInterface
{
    float ATTACK_PERCENTAGE = .1F;
    float DEFEND_PERCENTAGE = .5F;
    float TRAVEL_PERCENTAGE = .1F;
    float STARVE_PERCENTAGE = .05F;
    float PROCREATION_PERCENTAGE = .33F;

    public void attack( Island island );
	
    public void defend( Island island, int casualties );
	
    public void eat( Island island );
	
    public boolean isAlive();
	
    public boolean isFightingTime( Island island, Position position );
	
    public boolean isNearFood( Island island );
	
    public void move( Island island );
}

/*********************************************************************
 * This class represents a tribe.  A instance is created for each
 * tribe on the island.
 ********************************************************************/
class Tribe implements TribeInterface
{
    private int ID;
    private int population;
    private Position position;
    private Position lastPosition;
    private Vector traveledTo;
    private String timeOfDeath;
	
    // public constructor which initializes the tribes member variables
    public Tribe( int id, int size, Position startPoint )
    {
	ID = id;
		population = size;
		position = startPoint;
		traveledTo = new Vector();
		lastPosition = startPoint;
		timeOfDeath = "";
    }
	
    // Create a new Tribe object
    public Tribe( String ID, int size, int row, int column )
    {
		this( Integer.parseInt( ID ), size, row, column );
    }
	
    // Create a new Tribe object
    public Tribe( int ID, int size, int row, int column )
    {
		this( ID, size, new Position( row, column ) );
    }
	
    // This method is called when attacking another tribe to reduce the number
    // of peoplein by some percentage due to not eating while attacking
    public void attack( Island island )
    {
		// Reduce the population by the number of people who die in the attack
		die( island, population * TribeInterface.ATTACK_PERCENTAGE ); 
    }
	
    // This method is called when defending against an attack.	The tribes 
    // population is reduced by some percentage of the population of the other 
    // tribe which is passed in as an int.
    public void defend( Island island, int numAttackers )
    {
		// Kill some percentage of the size of the attacking tribe
		die( island, numAttackers * TribeInterface.DEFEND_PERCENTAGE );
    }
	
    // This method rounds the number of casualties up to the nearest whole number
    // and then calls the other die method.
    public void die( Island island, float casualties )
    {
		die( island, (int)Math.ceil( casualties ) );
    }
	
    // This method reduces the population by the number of casualties entered
    public void die( Island island, int casualties )
    {	
		// Reduce the population
		population -= casualties;
		
		// If the population is less than one
		if ( population < 1 )
		{
	    	// Set the population to zero
	    	setPopulation( 0 );
			
	    	// Set the time of death to the current round number
	    	setTimeOfDeath( island.getRound() );
					
	    	// Get the island entry where the tribe died
	    	IslandEntry entry = island.getEntry( getPosition() );
		
	    	// Set the descriptor to a field without wheat
	    	entry.setDescriptor( IslandInterface.FIELD_WO_WHEAT );
			
	    	// Set the hasTribe flag to false
	    	entry.setHasTribe( false ); 			
		}
    }
	
    /*************************************************************************
     * This method is called when it is time for a tribe to eat.  The tribe 
     * consumes 1 unit of wheat for every person in the tribe.	It starts by
     * eating food to the north and going clockwise until everyone has eaten.
     * If there isn't enough food for everyone, then some percentage of the 
     * people who don't eat will die.  The tribe will produce offspring equal 
     * to some percentage of the people who do eat.
     ************************************************************************/
    public void eat( Island island )
    {
		int population = getPopulation();
		int peopleToFeed = population;
		int food;
		String[] directions = { IslandInterface.NORTH, IslandInterface.EAST,
								IslandInterface.SOUTH, IslandInterface.WEST };
		
		// Loop through the directions, starting with north
		for ( int i = 0; i < directions.length; i++ )
		{
			if ( island.isValidEntry( getPosition(), directions[i] ) )
			{
				// Get the island entry
				IslandEntry position = island.getEntry( getPosition(), directions[i] );
			
	    		if ( position.getFood() > 0 )
	    		{		
					// Get the amount of wheat
					food = position.getFood();
		
					// If there is enough food for everyone
					if ( food >= peopleToFeed )
					{
		    			// Reduce the amount of food by the number of people to eat
		    			position.reduceFood( peopleToFeed );
				
		    			// Set the number of people left to feed to zero
		    			peopleToFeed = 0;
				
		    			// Exit the loop
		    			break;
					}
					// If there isn't enough food
					else
					{
		    			// Reduce the number of people to feed by the amount of food
		    			peopleToFeed = peopleToFeed - food;
				
		    			// Set the amount of wheat to zero for this island entry
		    			position.zeroOutFood();
					}
	    		}
			}
		}
		
		// Some of the people left to feed will starve
		starve( island, peopleToFeed );
		
		// Some of the people who did eat will multiply
		procreate( population - peopleToFeed );
    }
	
    // Returns the id of the tribe
    public int getID()
    {
		return ID;
    }
		
    /*************************************************************************
     * This methoc returns the Position object representing the next position 
     * that the tribe should travel to.  It takes an Island object as input
     ************************************************************************/
    private Position getNextPosition( Island island )
    {
		final int xcoord = getPosition().getXCoord();
		final int ycoord = getPosition().getYCoord();
		int lowestPoints = Integer.MAX_VALUE;
		int points = 0;
		Position nextPosition = new Position( xcoord, ycoord );
		
		// These arrays are used for the coordinates of the 4 different cardinal directions.
		int[] xcoords = { xcoord, xcoord + 1, xcoord, xcoord - 1 };
		int[] ycoords = { ycoord - 1, ycoord, ycoord + 1, ycoord };
		
		for	( int i = 0; i < xcoords.length; i++ )
		{
	    	if ( ( island.isValidEntry( xcoords[i], ycoords[i] ) ) &&
		 		( island.getEntry( xcoords[i], ycoords[i] ).isNavigable() ) )
	    	{
				// Get the points for the current location
				points = getPoints( xcoords[i], ycoords[i], lastPosition );
				
				// Compare it to the lowest point number found so far
				if ( points < lowestPoints )
				{
		    		lowestPoints = points;
		    		nextPosition.setCoordinates( xcoords[i], ycoords[i] );
				}
	    	}
		}
				
		return nextPosition;
    }
	
    // Returns the number of points for the island entry represented by the x and y
    // coordinates passed in.  1 point is added every time the island entry represented
    // by the x and y coordinates has already been traveled to.  The points
    // are doubled if the coordinates match that of the last position.
    private int getPoints( int xcoord, int ycoord, Position lastPosition )
    {
		int visits = 0;
		Position position;
		Enumeration iterator = traveledTo.elements();
		
		// Loop through all of the entries in the traveled to enumeration
		while ( iterator.hasMoreElements() )
		{
	    	// Get the next position in the enumeration
	    	position = (Position)iterator.nextElement();
			
	    	// Check to see if the coordinates match the coordinates passed in
	    	if ( ( position.getXCoord() == xcoord ) && ( position.getYCoord() == ycoord ) )
	    	{
				visits++;
	    	}
		}
		
		// Double the points if these coordinates match those of the last position
		if ( ( lastPosition.getXCoord() == xcoord ) && ( lastPosition.getYCoord() == ycoord ) )
		{
	    	visits *= 2;
		}
		
		return visits;
    }
	
    // Returns the current position of the tribe.
    public Position getPosition()
    {
		return position;
    }
	
    // Returns the population of the tribe.
    public int getPopulation()
    {
		return population;
    }
	
    // Returns the round number in which this tribe died
    public String getTimeOfDeath()
    {
		return timeOfDeath;
    }
		
    // Returns a boolean indicating whether or not this tribe still has any 
    // surviving members
    public boolean isAlive()
    {
		return ( population > 0 );
    }
	
    /***********************************************************************
     * This method is called whenever the tribe is looking for someone to fight.
     * It starts by looking north and then keeps looking clockwise.
     * It takes an Island object and Position object as input and returns true if
     * there is a nearby tribe to fight.  The Position object passed in is set
     * to the coordinates of the tribe to attack if a tribe is found.  
     ***********************************************************************/
    public boolean isFightingTime( Island island, Position opponent )
    {
		boolean fightingTime = false;
		int xcoord = position.getXCoord();
		int ycoord = position.getYCoord();
		
		// These arrays are used for the coordinates of the 4 different cardinal directions.
		int[] xcoords = { xcoord, xcoord + 1, xcoord, xcoord - 1 };
		int[] ycoords = { ycoord - 1, ycoord, ycoord + 1, ycoord };
		
		for ( int x = 0; x < xcoords.length; x++ )
		{
	    	if ( ( island.isValidEntry( xcoords[x], ycoords[x] ) ) && 
				 ( island.getEntry( xcoords[x], ycoords[x] ).hasTribe() ) )
	    	{
				opponent.setCoordinates( xcoords[x], ycoords[x] );
				fightingTime = true;
				break;
	    	}
		}
		
		return fightingTime;
    }	
	
    /************************************************************************
     * This method is called to check the surrounding squares and look for a 
     * field with wheat.  Returns a boolean indicating whether or not food
     * was found.
     ***********************************************************************/
    public boolean isNearFood( Island island )
    {
		boolean isNearFood = false;
		int xcoord = position.getXCoord();
		int ycoord = position.getYCoord();
		
		// These arrays are used for the coordinates of the 4 different cardinal directions.
		int[] xcoords = { xcoord, xcoord + 1, xcoord, xcoord - 1 };
		int[] ycoords = { ycoord - 1, ycoord, ycoord + 1, ycoord };
		
		for ( int x = 0; x < xcoords.length; x++ )
		{
	    	if ( ( island.isValidEntry( xcoords[x], ycoords[x] ) ) && 
				 ( island.getEntry( xcoords[x], ycoords[x] ).hasFood() ) )
	    {
			isNearFood = true;
			break;
	    }
		}

		return isNearFood;
    }
	
    /**********************************************************************
     * This method is called whenever it is time for a tribe to move on.
     * It retrieves the next position and then sets all the proper variables 
     * to indicate the new position
     * It takes an Island object as input
     **********************************************************************/
    public void move( Island island )
    {
		// Retrieve the new location
		Position nextPosition = getNextPosition( island );
		
		// Add the current location to the traveledTo Vector
		traveledTo.add( getPosition() );
		
		// Set the lastPosition to the current position
		lastPosition = getPosition();
		
		// Set the current location to a be a field with no wheat
		island.getEntry( getPosition() ).setDescriptor( IslandInterface.FIELD_WO_WHEAT );
		
		// Set the hasTribe flag on the current position to false
		island.getEntry( getPosition() ).setHasTribe( false );
		
		// Set the hasTribe flag on the new position to true
		island.getEntry( nextPosition ).setHasTribe( true );
		
		// Set the tribe number variable on the new position
		island.getEntry( nextPosition ).setTribeNumber( getID() );
		
		// Set the position to the new position
		setPosition( nextPosition );
		
		// kill some percentage due to traveling
		die( island, population * TribeInterface.TRAVEL_PERCENTAGE );
    }
	
    // Increases the population of the tribe by the integer amount passed in.
    public void procreate( int peopleWhoAte )
    {
		population += (int)Math.ceil( peopleWhoAte * TribeInterface.PROCREATION_PERCENTAGE );
    }

    // Sets the population to the integer passed in.
    public void setPopulation( int pop )
    {
		population = pop;
    }
	
    // Sets the position to the position passed in.
    public void setPosition( Position newPosition )
    {
		position = newPosition;
    }
	
    // Sets the round number that this tribe died in
    public void setTimeOfDeath( int round )
    {
		timeOfDeath = new Integer( round ).toString();
    }
	
    // Kills 5% of the people who didn't eat
    public void starve( Island island, int peopleWhoDidntEat )
    {
		die( island, peopleWhoDidntEat * TribeInterface.STARVE_PERCENTAGE );
    }
}

/****************************************************************************
 * Interface which the Island Class implements.
 * It defines constants and methods which the Island class must implement.
 ****************************************************************************/
interface IslandInterface
{
    String FIELD_W_WHEAT = "w";
    String FIELD_WO_WHEAT = ".";
    String NORTH = "north";
    String SOUTH = "south";
    String EAST = "east";
    String WEST = "west";
		
    public void populate( StringBuffer data );
}

/*****************************************************************************
 * This class represents the island.  It contains a matrix of IslandEntry objects
 * and methods for accessing and analyzing the different island entries.
 *****************************************************************************/
class Island implements IslandInterface
{
    private int width;
    private int height;
    private int numRounds;
    private IslandEntry[][] matrix;
    public int round;
    private Vector tribes;
	
    // public constructor which sets the size of the matrix
    public Island( int rounds, int numRows, int numCols )
    {
		width = numCols;
		height = numRows;
		matrix = new IslandEntry[width][height];
		round = 0;
		numRounds = rounds;
		tribes = new Vector();
    }
	
    // Returns the IslandEntry with the given position
    public IslandEntry getEntry( int xcoord, int ycoord )
    {
		return matrix[xcoord][ycoord];
    }
	
    // Returns the IslandEntry with the given position
    public IslandEntry getEntry( Position position )
    {
		return getEntry( position.getXCoord(), position.getYCoord() );
    }
	
    // Returns the IslandEntry object which is one square away from the position
    // passed in the direction that was passed in.
    public IslandEntry getEntry( Position position, String direction )
    {
		if ( direction.equals( IslandInterface.NORTH ) )
		{
	    	return getEntry( position.getXCoord(), position.getYCoord() - 1 );
		}
		else if ( direction.equals( IslandInterface.EAST ) )
		{
	    	return getEntry( position.getXCoord() + 1, position.getYCoord() );
		}
		else if ( direction.equals( IslandInterface.SOUTH ) )
		{
	    	return getEntry( position.getXCoord(), position.getYCoord() + 1 );
		}
		else
		{
	    	return getEntry( position.getXCoord() - 1, position.getYCoord() );
		}
    }
	
    // Returns the current round number
    public int getRound()
    {
		return round;
    }
	
    // This method searches through the matrix and finds all the
    // positions of the island that has a tribe on it and returns a Vector with
    // all of these tribes
    public void extractTribes()
    {
		IslandEntry islandEntry = null;
		Tribe tribe = null;
		
		// Loop through every entry on the island looking for tribes
		for ( int x = 0; x < getWidth(); x++ )
		{
	    	for ( int y = 0; y < getHeight(); y++ )
	    	{
				// Get the island entry at coordinates (x,y)
				islandEntry = getEntry( x, y );
				
				// Check to see if there is a tribe at that position
				if ( islandEntry.hasTribe() )
				{
		    		// Create a new tribe
		    		tribe = new Tribe( islandEntry.getDescriptor(),
					islandEntry.getNumber(), x, y );
					
		    		// Put the new tribe in the vector
		    		// Make sure the vector is big enough first
		    		if ( tribes.size() <= tribe.getID() )
		    		{
						tribes.setSize( tribe.getID() + 1 );
		    		}
		    		tribes.set( tribe.getID(), tribe );
				}
	    	}
		}
    }
		
    // Returns the width of the island, which is the number of columns in the matrix
    public int getWidth()
    {
		return width;
    }
	
    // Returns the height of the island, which is the number of rows in the matrix
    public int getHeight()
    {
		return height;
    }
		
    // Returns boolean indicating whether or not the position entered is a valid
    // set of coordinates for the island.
    public boolean isValidEntry( int xcoord, int ycoord )
    {
		return ( ( xcoord >= 0 ) && ( xcoord < getWidth() ) &&
				 ( ycoord >= 0 ) && ( ycoord < getHeight() ) );
    }
	
    // Returns boolean indicating whether or not the position entered is a valid
    // set of coordinates for the island.	
    public boolean isValidEntry( Position position, String direction )
    {
		if ( direction.equals( IslandInterface.NORTH ) )
		{
	    	return isValidEntry( position.getXCoord(), position.getYCoord() - 1 );
		}
		else if ( direction.equals( IslandInterface.EAST ) )
		{
	    	return isValidEntry( position.getXCoord() + 1, position.getYCoord() );
		}
		else if ( direction.equals( IslandInterface.SOUTH ) )
		{
	    	return isValidEntry( position.getXCoord(), position.getYCoord() + 1 );
		}
		else if ( direction.equals( IslandInterface.WEST ) )
		{
	    	return isValidEntry( position.getXCoord() - 1, position.getYCoord() );
		}	
		else
		{
	    	return false;
		}
    }
	
    // This is the method that runs exactly one round of the island simulation
    protected void nextRound()
    {
		Tribe tribe = null;
		Position position = new Position();
		
		// Loop through all of the tribes in the tribes Vector
		for ( int x = 0; x < tribes.size(); x++ )
		{		
	    	// Get the tribe at position x in the Vector
	    	tribe = (Tribe)tribes.get( x );

	    	// Check to see if the tribe has any surviving members
	    	if ( tribe.isAlive() )
	    	{
				// Check for a neighboring tribe to fight
				if ( tribe.isFightingTime( this, position ) )
				{
					// Extract the tribe that is being attacked from the tribes Vector
					Tribe defendingTribe = 
						(Tribe)tribes.elementAt( getEntry( position ).getTribeNumber() );
					
					// Call the defend method of the tribe which is being attacked,
					// passing in the population of the attacking tribe.
		    		defendingTribe.defend( this, tribe.getPopulation() );
				
		    		// Call the attack method of the attacking tribe
		    		tribe.attack( this );		
				}
				// Else look for something to eat
				else if ( tribe.isNearFood( this ) )
				{
		    		// Eat the food
		    		tribe.eat( this );
				}
				// If there is no fighting or eating then it is time to move
				else
				{
		    		// Move to a new position
		    		tribe.move( this );
				}
	    	}
		}
    }	
	
    // Fills the island with the data that is passed in
    public void populate( StringBuffer data ) 
		throws NoSuchElementException, NumberFormatException
    {
		int number = 0;
		String descriptor = null;
		
		// Tokenize the input string
		StringTokenizer st = new StringTokenizer( data.toString() );
		
		// For every row in the island
		for ( int row = 0; row < getHeight(); row++ )
		{
	    	// For every pair of tokens in the line of data
	    	for ( int col = 0; col < getWidth(); col++ )
	    	{
				// Set the descriptor to the first token
				descriptor = st.nextToken();
			
				// Set the number to the second token
				number = Integer.parseInt( st.nextToken() );
			
				// Set that spot in the island matrix to a new IslandEntry object
				matrix[col][row] = new IslandEntry( descriptor, number ); 
	    	}
		}
		
		extractTribes();
    }	
	
    // This method prints the results of the simulator
    public void printResults()
    {
		Enumeration tribeEnum = tribes.elements();
		Tribe tribe;
		
		// Loop through all of the tribes
		while ( tribeEnum.hasMoreElements() )
		{
	    	tribe = (Tribe)tribeEnum.nextElement();
			
	    	// Add 1 to the coordinates since java arrays are zero based.
	    	System.out.println( tribe.getID() + " " + tribe.getPopulation() + " (" +
								tribe.getPosition().getXCoord() + "," + 
								tribe.getPosition().getYCoord() + ") " +
								tribe.getTimeOfDeath() );
		}
		System.out.println();
    }	
	
    // This method starts the simulation for this island.  It calls the nextRound
    // method once for each round.
    public void start()
    {
		// while the round number is less than the number of rounds
		while( round < numRounds )
		{
	    	// Increment the round number
	    	round++;
			
	    	// Start the next round
	    	nextRound();
		}
    }
}

/*****************************************************************************
 * Abstract class which contains member variables and methods which a generic
 * IslandEntry should have.
 *****************************************************************************/
abstract class BasicIslandEntry
{
    protected String descriptor;
    protected int number;
		
    // Returns the value of the descriptor field
    public String getDescriptor()
    {
		return descriptor;
	}
	
    // Returns the number field which is initially used as the population of the
    // tribe occupying this island entry.
    public int getNumber()
    {
		return number;
    }
	
    // Returns whether or not this particulary island entry is navigable by a tribe
    abstract public boolean isNavigable();
	
    // Utility method used to determine if the String passed in represents an integer
    public boolean isNumeric( String string )
    {
		try
		{
	    	Integer number = new Integer( string );
		}
		catch( NumberFormatException nfe )
		{
	    	return false;
		}
		
		return true;
    }	
	
    // Set the descriptor field
    public void setDescriptor( String desc )
    {
		descriptor = desc;
    }
}

/****************************************************************************
 * This class is used to represent an individual island square.  The island
 * object contains a matrix of IslandEntry objects
 ****************************************************************************/ 
class IslandEntry extends BasicIslandEntry
{	
    private int tribeNo;
    private int food;
    private boolean hasTribe;
	
    // public constructor which sets the member variables
    public IslandEntry( String desc, int num )
    {
		// If the description is numeric, then this IslandEntry must have a tribe.
		if ( isNumeric( desc ) )
		{
	    	hasTribe = true;
	    	tribeNo = Integer.parseInt( desc );
	    	number = num;
		}
		else
		{
	    	food = num;
		}
		descriptor = desc;
    }
	
    // Returns the amount of food that this island entry has
    public int getFood()
    {
		return food;
    }
	
    // Returns the tribe number that is currently occupying this island entry
    public int getTribeNumber()
    {
		return tribeNo;
	}
	
    // Returns a boolean indicating whether or not this island entry has any wheat
    public boolean hasFood()
    {
		return ( descriptor.equals( IslandInterface.FIELD_W_WHEAT ) && ( food > 0 ) );
    }
	
    // Returns whether or not this island entry currently as a tribe on it		
    public boolean hasTribe()
    {
		return hasTribe;
    }
	
    // Returns whether or not this island entry is navigable by a tribe
    public boolean isNavigable()
    {
		return ( descriptor.equals( IslandInterface.FIELD_WO_WHEAT ) || 
				( descriptor.equals( IslandInterface.FIELD_W_WHEAT ) ) );
    }	
	
    // Reduces the food by the integer amount passed in
    public void reduceFood( int amountEaten )
    {
		food -= amountEaten;
    }
		
    // Sets the hasTribe flag to the boolean value passed in
    public void setHasTribe( boolean flag )
    {
		hasTribe = flag;
    }
	
    // Sets the tribe number to the integer passed in
    public void setTribeNumber( int number )
    {
		tribeNo = number;
    }
	
    // Sets the food to zero and sets the descriptor to a field without wheat
    public void zeroOutFood()
    {
		food = 0;
		descriptor = IslandInterface.FIELD_WO_WHEAT;
    }	
}

/******************************************************************************
 * This class is used to keep track of positions on the island.  It contains 2
 * member variables, an x coordinate and a y coordinate.
 ******************************************************************************/
class Position
{
    int xcoord;
    int ycoord;
	
    // Create a new Position object
    public Position()
    {
		this( 0, 0 );
    }
	
    // Create a new Position object
    public Position( int x, int y )
    {
		xcoord = x;
		ycoord = y;
    }
	
    // get the x coordinate
    public int getXCoord()
    {
		return xcoord;
    }
	
    // get the y coordinate
    public int getYCoord()
    {
		return ycoord;
    }
	
    // set both coordinates
    public void setCoordinates( int x, int y )
    {
		xcoord = x;
		ycoord = y;
    }
	
    // Set the x coordinate
    public void setXCoord( int x )
    {
		xcoord = x;
    }
	
    // Set the y coordinate
    public void setYCoord( int y )
    {
		ycoord = y;
    }
}