I was wondering how I could streamline the following code. This was the project assigned to us:
The Canadian Forest Service wants to do a simple simulation of the growth and pruning of forests. Each forest has a name and exactly 10 trees. The trees are planted when they are 1' to 5' tall, and each tree has a individual growth rate of 50%-100% per year. For the simulation new trees are constructed randomly within these bounds. A forest is reaped (by lumberjacks) on demand - all trees above a specifed height are cut down and replaced with new trees.
The user interface to the simulation must allow the user to:
- Display the current forest (with tree heights to 2 decimal places)
- Discard the current forest and create a new forest
- Simulate a year's growth in the current forest
- Reap the current forest of trees over a user specified height, replacing the reaped trees with random new trees.
- Save the information about the current forest to file (named after the forest)
- Discard the current forest and load the information about a forest from a file.
import java.util.Scanner;
import java.util.*;
import java.io.*;
public class Main {
private static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
//initialize variables for Forest object, name, height and other inputs
Forest thisForest = null;
char userInput = ' ';
String forestName;
int height = 0;
String loadName = null;
while((userInput != 'x') && (userInput != 'X' )){
switch (userInput) {
//sets the first prompt
case ' ':
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
break;
//Displays the output but only if the forest exists
case 'D':
case 'd':
if(thisForest != null){
thisForest.display();
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
}else{
System.out.println("No Forrest.\n");
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
}
break;
case 'N':
case 'n':
System.out.print("What is the name of the forest: ");
forestName = scan.next();
thisForest = new Forest(forestName);
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
break;
case 'Y':
case 'y':
//grows the equivalent of a "year".
if(thisForest != null){
thisForest.yearGrowth();
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
}else{
System.out.print("No forest exists.\n");
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
}
break;
case 'R':
case 'r':
//reaps, but only if the forest exists. Catches possible exceptions.
if(thisForest != null){
try{
System.out.print("What height to reap at :");
height = scan.nextInt();
}catch(NumberFormatException e){
System.out.println("ERROR: Invalid height\n");
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
scan.nextLine();
userInput = scan.next().charAt(0);
break;
} catch(InputMismatchException e){
System.out.println("ERROR: Invalid height\n");
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
scan.nextLine();
userInput = scan.next().charAt(0);
break;
}
//end of try-catch
thisForest.reap(height);
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
scan.nextLine();
userInput = scan.next().charAt(0);
break;
//output if there is no forrest
}else{
System.out.print("There is no forest to reap.\n");
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
scan.nextLine();
userInput = scan.next().charAt(0);
}
break;
case 'S':
case 's':
//saves the program
if(thisForest != null){
try{
Forest.saveForest(thisForest);
}catch(IOException e){
System.out.println("Cannot save.");
}
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
}else{
System.out.println("No Forrest exists to save.");
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
}
break;
case 'L':
case 'l':
// loads the program
try{
System.out.print("What is the name of the Forest: ");
loadName = scan.next();
thisForest = Forest.loadForest(loadName);
}catch(IOException e){
System.out.println("Cannot load.");
}
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
break;
default:
System.out.println("ERROR: Invalid Option.");
System.out.print("(D)isplay, (N)ew, (Y)ear, (R)eap, (S)ave, (L)oad, e(X)it :");
userInput = scan.next().charAt(0);
break;
}
}
//after x is received and the while loop breaks.
System.out.println("Goodbye");
}
}
Second Class:
import java.io.*;
import java.util.*;
public class Forest implements Serializable{
//creates variables and constants
private final int MAX_NUM_TREES = 10;
private String name;
private Tree[] arrayOfTrees;
int index;
public Forest(String forestName){
index = 0;
name = forestName;
arrayOfTrees = new Tree[MAX_NUM_TREES];
for(index = 0; index < arrayOfTrees.length; index++){
arrayOfTrees[index] = new Tree();
}
}
public void display(){
// displays the array of trees and the index
index = 0;
if(name != null){
System.out.println(name);
for(index = 0; index < arrayOfTrees.length; index ++){
System.out.printf("%2d : %s\n", (index + 1), arrayOfTrees[index]);
}
}else{
System.out.println("No forest.");
}
}
public void yearGrowth(){
//grows each tree in the array
index = 0;
for(index = 0; index < arrayOfTrees.length ; index ++){
arrayOfTrees[index].grow();
}
}
public void reap(int reapHeight){
//reaps the trees and prints out the old and new information
index = 0;
for(index = 0; index < arrayOfTrees.length; index++){
if(arrayOfTrees[index].getHeight() >= reapHeight){
System.out.println("Cut " + (index+1) + " : " + arrayOfTrees[index] );
arrayOfTrees[index] = new Tree();
System.out.println("New " + (index+1) + " : " + arrayOfTrees[index] );
}
}
}
public static void saveForest(Forest forest) throws IOException {
//saves the forest
String name = forest.getName();
ObjectOutputStream toStream;
toStream = new ObjectOutputStream(new FileOutputStream(name));
toStream.writeObject(forest);
toStream.close();
}
public static Forest loadForest(String fileName) throws IOException {
//loads the forest
ObjectInputStream fromStream = null;
Forest local;
fromStream = new ObjectInputStream(new FileInputStream(fileName));
try {
local = (Forest)fromStream.readObject();
}catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
return(null);
}finally{
try {
if (fromStream != null) {
fromStream.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
return(null);
}
}
return(local);
}
public String getName(){
return (name);
}
}
Third Class
import java.util.Random;
import java.util.*;
import java.io.*;
public class Tree implements Serializable{
//creates the variables as the
private double height;
private double growthRate;
private static Random rand = new Random();
final double MIN_HEIGHT = 1;
final double MIN_GROWTH_RATE = 0.5;
final double MAX_HEIGHT = 5;
final double MAX_GROWTH_RATE = 1.0;
public Tree() {
//creates tree with a height and a growth rate
Random rand = new Random();
height = (MIN_HEIGHT + ((Math.random() * (MAX_HEIGHT - MIN_HEIGHT))));
growthRate = (MIN_GROWTH_RATE + (Math.random() * (MAX_GROWTH_RATE - MIN_GROWTH_RATE)));
}
public double grow(){
//tree grows and returns height
height = height * (1 + growthRate);
return height;
}
public double getHeight(){
return (height);
}
public double getGrowthRate(){
return (growthRate);
}
public String toString(){
//toString formats the output with height and growthrate
return (String.format("%7.2f (%2d%% pa)", height, ((int)(growthRate * 100))));
}
}
```