/** * CS151 Fall 2007 Lab #5 solution.
* Models a simple version of an automobile with fuel amount, fuel efficiency, * and mileage attributes. Fuel measured in gallons and efficiency in * miles/gallon. * * @author Scott Russell * @version 10/02/2007 */ public class Automobile { //* Constants * public static final String CIVIC = "Civic"; public static final String TAURUS = "Taurus"; public static final String PRIUS = "Prius"; public static final double CIVIC_EFFICIENCY = 40.0; public static final double TAURUS_EFFICIENCY = 30.0; public static final double PRIUS_EFFICIENCY = 40.0; public static final double PRIUS_BATTERY_EFFICIENCY = 50.0; //the fraction of the efficiency when driving in city or at begin and end of trip public static final double CITY_EFFICIENCY_MULT = 0.75; public static final double START_LOW_EFFIC_MILES = 5.0; public static final double END_LOW_EFFIC_MILES = 5.0; public static final double DEFAULT_FUEL_EFFICIENCY = 25.0; //in practice get current_year from a GregorianCalendar object public static final int CURRENT_YEAR = 2007; public static final int DEFAULT_YEAR = CURRENT_YEAR; public static final int AGE_CUTOFF = 5; public static final int HIGH_MILE_LIMIT =100000; public static final double HIGH_MILE_MULT = 0.9; public static final double HIGH_MILE_MULT2 = 2.0; public static final int MILEAGE_DIVISOR = 50000; public static final int LOW_MILE_LIMIT = 60000; public static final double LOW_MILE_MULT = 0.95; //Instance Fields/Variables //We need not intialize theses since we will do so in constructors //amount of fuel in the vehicle in gallons private double fuelLevel; //amount of distance the car can travel per gallon of fuel private double fuelEfficiency; //total distance in miles the car has traveled private double mileage; //the model of the car private String model; //the year the car was manufactured private int year; //Constructors /** * Creates a new automobile with the specified efficiency. Fuel level and * mileage are initialize to 0. * @param efficiency number of miles/gallon of fuel the car can travel. */ public Automobile(double efficiency) { //initialize the model to blank model = new String(); //initialize the efficiency to specified value fuelEfficiency = efficiency; //initialize fuel level to 0 fuelLevel = 0; //initialize mileage to 0 mileage = 0; //initialize year to this default year = DEFAULT_YEAR; } /** * Creates a new automobile with the specified efficiency and fuel level. * Mileage is initialized to 0. * @param efficiency number of miles/gallon of fuel the car can travel. * @param fuelAmount amount of fuel in gallons. */ public Automobile(double efficiency, double fuelAmount) { //initialize the model to blank model = new String(); //initialize the efficiency to specified value fuelEfficiency = efficiency; //initialize fuel level to specified value fuelLevel = fuelAmount; //initialize mileage to 0 mileage = 0; //initialize year to this default year = DEFAULT_YEAR; } /** * Creates a new automobile with the specified efficiency and fuel level. * Mileage is initialized to 0. * @param model the model of the car, e.g. Taurus, Civic, etc. * @param amount the initial amount of fuel in gallons. */ public Automobile(String theModel, double fuelAmount, double miles) { //initialize the efficiency to specified value base on the model model = theModel; setFuelEfficiency(model); //initialize fuel level 0 fuelLevel = fuelAmount; //initialize mileage to specified amount mileage = miles; //initialize year to this default year = DEFAULT_YEAR; } /** * Creates a new automobile with the specified efficiency, fuel level, and mileage. * @param efficiency number of miles/gallon of fuel the car can travel. * @param fuelAmount amount of fuel in gallons. * @param miles initial mileage reading in miles. */ public Automobile(double efficiency, double fuelAmount, double miles) { //initialize the model to blank model = new String(); //initialize the efficiency to specified value fuelEfficiency = efficiency; //initialize fuel level to specified value fuelLevel = fuelAmount; //initialize mileage to specified value mileage = miles; //initialize year to this default year = DEFAULT_YEAR; } //Methods /** * Add the specified amount of fuel to the auto's fuel level. * @param fuelAmount number of gallons of fuel to add. */ public void addFuel(double fuelAmount) { fuelLevel = fuelLevel + fuelAmount; } /** * Simulate driving the auto the specified number of miles. * @param distance number of miles to drive. */ public void drive(double distance) { //calculate fuel needed to travel distance and range given fuel level double range = fuelLevel*fuelEfficiency; double fuelNeeded = distance/fuelEfficiency; //alterntatively you can test (fuelLevel >= fuelNeeded) if (range >= distance) { fuelLevel = fuelLevel - fuelNeeded; mileage = mileage + distance; } else { fuelLevel = 0; mileage = mileage + range; } //using max and min is another way to to deal with the two possible outcomes /* * fuelLevel = Math.max(0, fuelLevel - fuelNeeded); * mileage = mileage + Math.min(range, distance) */ } /** * Simulate driving and take into account variable efficiency by Prius and other cars. * @param distance number of miles to drive. */ public void drive2(double distance) { //compute the efficiency used for the begining and end of the trip double localEfficiency = fuelEfficiency * CITY_EFFICIENCY_MULT; if (this.model.equals(PRIUS)) localEfficiency = PRIUS_BATTERY_EFFICIENCY; /* * compute fuel need for this trip * if trip longer than start and finish low mileage distances use localEfficiency for start * and end distances and regular fuel efficiency for remainder of the distance */ double fuelNeeded = 0.0; if (distance > START_LOW_EFFIC_MILES + END_LOW_EFFIC_MILES) fuelNeeded = (START_LOW_EFFIC_MILES + END_LOW_EFFIC_MILES)/localEfficiency + (distance - START_LOW_EFFIC_MILES - END_LOW_EFFIC_MILES)/fuelEfficiency; else fuelNeeded = distance * localEfficiency; /* * compute the possible range of the car based on its fuel level * first see if enough fuel to get from localEfficiency to regular efficiency performance */ double range = 0.0; double fuelUsed = 0.0; if (fuelLevel*localEfficiency > START_LOW_EFFIC_MILES + END_LOW_EFFIC_MILES) { //account for start and end of trip range = START_LOW_EFFIC_MILES + END_LOW_EFFIC_MILES; fuelUsed = range/localEfficiency; //account for middle of the trip range = range + (fuelLevel - fuelUsed) * fuelEfficiency; } else if (fuelLevel*localEfficiency > START_LOW_EFFIC_MILES) { //compute range assuming first localEfficiency then at regular efficiency until fuel gone //account for start of trip range = START_LOW_EFFIC_MILES; fuelUsed = range/localEfficiency; //account for middle of the trip range = range + (fuelLevel - fuelUsed) * fuelEfficiency; } else { range = fuelLevel*localEfficiency; } //now update fuelLevel and mileage as before using computed range and fuelNeeded //alterntatively you can test (fuelLevel >= fuelNeeded) if (range >= distance) { fuelLevel = fuelLevel - fuelNeeded; mileage = mileage + distance; } else { fuelLevel = 0; mileage = mileage + range; } } //get and set Methods /** * Sets the fuel amount to the specified value. * @param fuelAmount amount of fuel in gallons. */ public void setFuelLevel(double fuelAmount) { fuelLevel = fuelAmount; } /** * Gets the current fuel level. * @return current fuel level in gallons. */ public double getFuelLevel() { return fuelLevel; } /** * Sets the fuel efficiency to the specified value. * @param efficiency fuel efficiency in miles/gallon. */ public void setFuelEfficiency(double efficiency) { fuelEfficiency = efficiency; } /** * Sets the fuel efficiency based on the specified auto model * (not the model of this auto). * @param model the name of the model which this auto should have the same efficiency as. */ public void setFuelEfficiency(String theModel) { //See Automobile2 for a slightly more elegant and easier to maintain solution double efficiency = DEFAULT_FUEL_EFFICIENCY; //set local variable for efficiency depending on model and if no match use default value if (theModel.equals(CIVIC)) efficiency = CIVIC_EFFICIENCY; else if (theModel.equals(TAURUS)) efficiency = TAURUS_EFFICIENCY; else if (theModel.equals(PRIUS)) efficiency = PRIUS_EFFICIENCY; else efficiency = DEFAULT_FUEL_EFFICIENCY; //now set this automobile's efficiency once which makes the above easier to read //and reduces the chance of making an error when assigning the value. this.setFuelEfficiency(efficiency); } /** * Computes and sets the fuel efficiency based on the vehicle's model, year, and mileage. */ public void computeFuelEfficiency() { //set the efficiency as if a new car of this model setFuelEfficiency(this.model); final int carAge = CURRENT_YEAR - this.year; double efficiency = this.fuelEfficiency; if (carAge >= AGE_CUTOFF && this.mileage >= HIGH_MILE_LIMIT) { efficiency = HIGH_MILE_MULT * efficiency - HIGH_MILE_MULT2 * Math.floor(mileage/MILEAGE_DIVISOR); } else if (carAge >= AGE_CUTOFF || this.mileage >= LOW_MILE_LIMIT) { efficiency = LOW_MILE_MULT * efficiency; } //otherwise the efficiency is like that of a new car which we already set //now set this automobile's efficiency once fuelEfficiency = efficiency; } /** * Gets the current fuel efficiency. * @return current fuel efficiency in miles/gallons. */ public double getFuelEfficiency() { return fuelEfficiency; } /** * Sets the mileage to the specified value. * @param miles mileage value. */ public void setMileage(double miles) { mileage = miles; } /** * Gets the current fuel efficiency. * @return current fuel efficiency in miles/gallons. */ public double getMileage() { return mileage; } /** * Sets the manufacture year of the vehicle to the specified year. * @param year the year the vehicle was made. */ public void setYear(int theYear) { year = theYear; } }