/* * Frogger.java * * Created on August 16, 2001, 7:29 AM */ import java.io.*; import java.util.*; /** * This class is a driver class for using the Frog and Street classes to simulate * a game of Frogger * @author Andrew McDowell * @version 1.0 */ public class Frogger { /** The number of lanes in the street */ public static final int NUM_LANES = 10; /** The number of columns in the street */ public static final int NUM_COLUMNS = 10; /** The string used as the starting point for the input */ public static final String START = "START"; /** The string used as the ending point for the input */ public static final String END = "END"; private Frog frog; private Vector streets; /** Creates a new Frogger Simulator */ public Frogger() { // Initialize Frogger simulator init(); } /** Initializes the frog and the streets */ protected void init() { // Create the Frog object frog = new Frog(); // Create the Vector of streets streets = readInputStreets(); } /** Reads the input streets */ protected Vector readInputStreets() { String line; Street street; Vector streets = new Vector(); BufferedReader input = null; try { // Create the input stream input = new BufferedReader( new InputStreamReader( System.in ) ); //input = new BufferedReader( new FileReader( "c:\\frogger.in" ) ); // Read the first line line = input.readLine(); // Check to see if it is null or the Start string while( ( line != null ) && ( line.equals( Frogger.START ) ) ) { // Create a new street object street = new Street( NUM_COLUMNS, NUM_LANES ); // Read in one line of lane data at a time and set that lane of the street for( int laneNum = 1; laneNum < NUM_LANES - 1; laneNum++ ) { line = input.readLine(); street.fillLane( line, laneNum ); } // Add the street to the streets Vector streets.add( street ); // Read in the next line line = input.readLine(); // Check to see if it the End string if ( !line.equals( Frogger.END ) ) { System.out.println( "Invalid Data. Missing \"END\". Exiting!" ); System.exit( 0 ); } // Read in the next line line = input.readLine(); } } catch( NumberFormatException nfe ) { System.out.println( "Error reading input. Non-numeric data in the input file." ); System.exit( 0 ); } catch( NoSuchElementException nsee ) { System.out.println( "Error reading input. Make sure every row has enough data." ); System.exit( 0 ); } catch( IOException ioe ) { System.out.println( "Error reading input. Frogger exiting." ); System.out.println( ioe.getMessage() ); System.exit( 0 ); } // Return the Vector of streets return streets; } /** Starts the simulator */ protected void start() { Street street; Enumeration roads = streets.elements(); // Loop through all the different streets that were read in from the input while( roads.hasMoreElements() ) { // Get the next street street = (Street)roads.nextElement(); // Start the simulation for this particular street street.start( frog ); } } /** Main method which is run by the java interpreter. */ public static void main( String args[] ) { // Create the Frogger simulator Frogger froggerSimulator = new Frogger(); // Start the simulation froggerSimulator.start(); } } /** * This class represents the frog object. It contains member variables and * methods to help simulate a frog moving across a street. * @author Andrew McDowell * @version 1.0 */ class Frog { /** Lane number that the frog is in */ private int laneNumber; /** Column number that the frog is in */ private int columnNumber; /** Boolean flag indicating whether or not the frog is alive */ private boolean alive; /** Public constructor which intializes the frog to alive, and in lane 0 * and column 0 */ public Frog() { alive = true; laneNumber = 0; columnNumber = 0; } /** Returns the column number of where the frog currently is * @return The column number the frog is in */ public int getColumnNumber() { return columnNumber; } /** Returns the lane number of where the frog currently is * @return The lane number the frog is in */ public int getLaneNumber() { return laneNumber; } /** Returns a boolean indicating whether or not the frog made it across the street * @param int Number of Lanes in the street * @return true if the frog made it across */ public boolean isAcross( int numLanes ) { return laneNumber == ( numLanes - 1 ); } /** Returns a boolean indicating if the frog is in a lane with cars * @param int Number of Lanes in the street * @return true if the frog is in a lane with traffic in it */ public boolean isInStreet( int numLanes ) { return ( ( laneNumber > 0 ) && ( laneNumber < ( numLanes - 1 ) ) ); } /** Returns a boolean indicating where or not the frog has been hit yet * @return truetrue if the frog is on the same square as a car. */ protected boolean isRoadKill( Frog frog ) { return ( simulatorMatrix[frog.getColumnNumber()][frog.getLaneNumber()] != 0 ); } /** Moves all the cars in the street by that particular car's velocity and direction. * @param Frog object */ protected void move( Frog frog ) { int[][] newMatrix = new int[NUM_COLUMNS][NUM_LANES]; int direction; int velocity; int newColumn; // Loop through every lane. for( int row = 1; row < NUM_LANES - 1; row++ ) { // Set the direction depending on the lane number direction = ( row >= 1 ) && ( row < ( NUM_LANES / 2 ) ) ? -1 : 1; // Loop through every column for ( int col = 0; col < NUM_COLUMNS; col++ ) { // Retrieve the velocity velocity = simulatorMatrix[col][row]; if ( velocity > 0 ) { // Calculate the new position of the car. newColumn = ( ( velocity * direction ) + col + 100 ) % 10; // Set the new position of the car in the matrix newMatrix[newColumn][row] = velocity; // If the car moved over the spot with the frog then mark // the spot with something besides 0 so that the isRoadKill // method will catch it. if ( ( frog.getLaneNumber() == row ) && ( ranOverFrog( frog, direction, col, newColumn ) ) ) { newMatrix[frog.getColumnNumber()][frog.getLaneNumber()] = -1; } } } } // Set the simulator matrix to the matrix with the new positions of the cars simulatorMatrix = newMatrix; } /** * Checks to see if the car moved over the square that the frog was in. * @param frog Frog object * @param direction The direction the car was going * @param col previous column of the car * @param newCol new column of the car * @return boolean Returns true if the frog was run over */ protected boolean ranOverFrog( Frog frog, int direction, int col, int newCol ) { boolean ranOver = false; // Get the column number of the frog int frogX = frog.getColumnNumber(); // If the direction is to the right if ( direction == 1 ) { // If the car didn't wrap around to the other side if ( newCol > col ) { // If the frog was between the new column and the old column if ( ( frogX > col ) && ( frogX < newCol ) ) { ranOver = true; } } // Else the car wrapped around to the other side else { if ( ( frogX > col ) || ( frogX < newCol ) ) { ranOver = true; } } } // If the direction is to the left else { // If the car didn't wrap around to the other side if ( newCol < col ) { // If the frog was between the new column and the old column if ( ( frogX < col ) && ( frogX > newCol ) ) { ranOver = true; } } // Else the car wrapped around to the other side else { if ( ( frogX < col ) || ( frogX > newCol ) ) { ranOver = true; } } } return ranOver; } /** Resets the the simulator matrix back to the starting positions. */ protected void reset() { simulatorMatrix = (int[][])startingMatrix.clone(); } /** Starts this streets simulation * @param frog A Frog Object */ public void start( Frog frog ) { // Reset the frog back to column 0 and lane 0. frog.reset(); // Reset the cars back to their starting position this.reset(); // Try every column while( frog.getColumnNumber() < NUM_COLUMNS ) { // Move the frog frog.move(); // While the frog is alive and still in the street while( ( frog.isStillAlive() ) && ( frog.isInStreet( NUM_LANES ) ) ) { // Check to see if the frog moved onto a car if ( isRoadKill( frog ) ) { // If so, kill the frog and continue to the next column frog.squish(); continue; } // Move the cars this.move( frog ); // Check to see if the frog got hit by a car if ( isRoadKill( frog ) ) { // If so, kill the frog and continue to the next column frog.squish(); continue; } // Move the frog frog.move(); } // Check to see if the frog made it across if ( frog.isAcross( NUM_LANES ) ) { // If so, print the success message and return System.out.println( "LEFTOVER POSSUM" ); return; } // Move the frog to the next column frog.nextColumn(); } // If it gets this far, then the frog ran out of columns to try System.out.println( "FROGGER" ); } }