\"Create a system to simulate vehicles at an intersection. Assume that there is one lane going in
each of four directions, with stoplights facing each direction. Vary the arrival average of vehicles
in each direction and the frequency of the light changes to view the \"behavior\" of the
intersection.\"
You canNOT use the Java built-in Queue or Deque class. Use an Array or Linked List
implementation of a queue as explained in the text. This means a jsjf package containing
QueueADT.java file with CircularArrayQueue.java or LinkedQueue.java and LinearNode.java.
Include user-defined exceptions and javadoc comments.
Be sure to test thoroughly, and document your results.
Be sure to label your outputs so that when I run your code I can readily understand what you\'re
doing.
Determine what is the optimal light-change time to maximize car throughput.
WANT KNOW HOW CAN I MAKE IT RUN!
import java.lang.Math;
import java.io.*;
import jsjf.*;
import jsjf.exceptions.*;
import java.util.*;
import java.net.*;
import java.io.*;
/**
*This class is where all action resides. It contains all the queues that represent the lanes at the
intersection.
* It also contains all methods that pertain to populating the intersection and moving the vehicles
in their
* retrospective directions.
*/
public class Simulator {
/** This queue will hold only vehicle objects that enter in the left lane on Main Street headed
East. */
private LinkedQueue EMainL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Main Street headed
East. */
private LinkedQueue EMainR = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the left lane on Main Street headed
West. */
private LinkedQueue WMainL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Main Street headed
West. */
private LinkedQueue WMainR = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the left lane on Church Street
headed North. */
private LinkedQueue NChurchL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Church Street
headed North. */
private LinkedQueue NChurchR = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the left lane on Church Street
headed South. */
private LinkedQueue SChurchL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Church Street
headed South. */
private LinkedQueue SChurchR = new LinkedQueue();
/** This integer value will keep track of the current time during the simulation.*/
int time = 0;
/** This integer value will be used to make sure only two vehicles move during each light
change for each lane. */
int i = 0;
/** This integer value will keep track of the vehicle numbers of the cars that arrive at the
intersection. */
int vehicleNum = 1;
/** This creates a filewriter object that allows us for the ability to write streams o.
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
Create a system to simulate vehicles at an intersection. Assume th.pdf
1. "Create a system to simulate vehicles at an intersection. Assume that there is one lane going in
each of four directions, with stoplights facing each direction. Vary the arrival average of vehicles
in each direction and the frequency of the light changes to view the "behavior" of the
intersection."
You canNOT use the Java built-in Queue or Deque class. Use an Array or Linked List
implementation of a queue as explained in the text. This means a jsjf package containing
QueueADT.java file with CircularArrayQueue.java or LinkedQueue.java and LinearNode.java.
Include user-defined exceptions and javadoc comments.
Be sure to test thoroughly, and document your results.
Be sure to label your outputs so that when I run your code I can readily understand what you're
doing.
Determine what is the optimal light-change time to maximize car throughput.
WANT KNOW HOW CAN I MAKE IT RUN!
import java.lang.Math;
import java.io.*;
import jsjf.*;
import jsjf.exceptions.*;
import java.util.*;
import java.net.*;
import java.io.*;
/**
*This class is where all action resides. It contains all the queues that represent the lanes at the
intersection.
* It also contains all methods that pertain to populating the intersection and moving the vehicles
in their
* retrospective directions.
*/
public class Simulator {
/** This queue will hold only vehicle objects that enter in the left lane on Main Street headed
East. */
private LinkedQueue EMainL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Main Street headed
East. */
private LinkedQueue EMainR = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the left lane on Main Street headed
2. West. */
private LinkedQueue WMainL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Main Street headed
West. */
private LinkedQueue WMainR = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the left lane on Church Street
headed North. */
private LinkedQueue NChurchL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Church Street
headed North. */
private LinkedQueue NChurchR = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the left lane on Church Street
headed South. */
private LinkedQueue SChurchL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Church Street
headed South. */
private LinkedQueue SChurchR = new LinkedQueue();
/** This integer value will keep track of the current time during the simulation.*/
int time = 0;
/** This integer value will be used to make sure only two vehicles move during each light
change for each lane. */
int i = 0;
/** This integer value will keep track of the vehicle numbers of the cars that arrive at the
intersection. */
int vehicleNum = 1;
/** This creates a filewriter object that allows us for the ability to write streams of characters
to a file. */
FileWriter fw;
/** This creates a bufferedwriter object that allows for the efficient writing to the file. */
BufferedWriter bw;
/** This creates a printwriter object that allows for the ability to use the print methods when
writing to the file. */
PrintWriter outFile;
/**
* This is a constructor. It sets up the ability for a simulator object to be instantiated.
*/
3. public Simulator() {}
/**
* This method calls all others methods in this class. It firsts instantiates the objects associated
with
* writing to the file. It then calls the populate method to start the simulation and create car
objects. The
* amount of car objects created is between 7 and 12. Until all queues are empty, the simulation
will continue
* to run. During the simulation, the cars will move in the North/South direction for 6 seconds,
then more
* cars will arrive (between 8 and 15). Then the cars will move in the East/ West direction for 6
seconds,
* and more cars will arrive (between 3 and 15).
* @throws IOException this is done in case their is an error printing to the file
*/
public void Simulate() {
try {
fw = new FileWriter("output.txt");
bw = new BufferedWriter(fw);
outFile = new PrintWriter(bw);
outFile.print("---Start of simulation, time set to 0.--- ");
populate((int)(Math.random() * (13 - 7) + 7));
while(!queuesEmpty()) {
outFile.print("---Light changed. Now processing north/south-bound traffic--- ");
moveNorthSouth();
populate((int)(Math.random() * (16 - 8) + 8));
outFile.println();
outFile.print("---Light changed. Now processing east/west-bound traffic--- ");
moveEastWest();
populate((int)(Math.random() * (16 - 3) + 3));
outFile.println();
}
outFile.close();
}
catch(IOException e){
4. System.err.println("Error printing to file");
}
}
/**
* This method is only called once when first populating the intersection. It instantiates the
amount of cars
* according to the number that is passed in. The time they are created, their arrival times, is
* the current time in the simulation. Each time a new vehicle is created, the vehicle number
increases by 1.
* Depending on what lane and direction the car enters the simulation, it is placed correctly into
its
* corresponding queue.
* @param number of cars to be instantiated
*/
private void populate(int randomNum) {
int count = 0;
while (count < randomNum&& vehicleNum <=120) {
Vehicle car = new Vehicle(vehicleNum, time, time);
count++;
vehicleNum++;
if (car.getStreet() == Vehicle.Street.Main && car.getDirection() == Vehicle.Direction.E
&& car.getLane() == Vehicle.Lane.Left)
EMainL.enqueue(car);
else if (car.getStreet() == Vehicle.Street.Main && car.getDirection() ==
Vehicle.Direction.E && car.getLane() == Vehicle.Lane.Right)
EMainR.enqueue(car);
else if (car.getStreet() == Vehicle.Street.Main && car.getDirection() ==
Vehicle.Direction.W && car.getLane() == Vehicle.Lane.Left)
WMainL.enqueue(car);
else if (car.getStreet() == Vehicle.Street.Main && car.getDirection() ==
Vehicle.Direction.W && car.getLane() == Vehicle.Lane.Right)
WMainR.enqueue(car);
else if (car.getStreet() == Vehicle.Street.Church && car.getDirection() ==
Vehicle.Direction.N && car.getLane() == Vehicle.Lane.Left)
NChurchL.enqueue(car);
else if (car.getStreet() == Vehicle.Street.Church && car.getDirection() ==
5. Vehicle.Direction.N && car.getLane() == Vehicle.Lane.Right)
NChurchR.enqueue(car);
else if (car.getStreet() == Vehicle.Street.Church && car.getDirection() ==
Vehicle.Direction.S && car.getLane() == Vehicle.Lane.Left)
SChurchL.enqueue(car);
else
SChurchR.enqueue(car);
}
}
/**
* This method simulates the movement of vehicles in the North / South direction. Four queues
are operated
* on at this traffic light, but the NChurchL one will be used to exemplify the functionality of
the method.
* If there are cars waiting to move and while only two are allowed to move, a new vehicle
object is
* instantiated. The first car in the spot is then dequeued and stored into the new car object. Its
departure
* time is set to the current time on the clock, which was previously increased by 3 seconds
each time the loop
* begins.
* @throws EmptyCollectionException this is done in case the queue is empty
*/
private void moveNorthSouth() {
int i = 0;
while (i < 2) {
time+=3;
try {
if (!NChurchL.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = NChurchL.dequeue();
car.setDepartureTime(time);
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
6. try {
if (!NChurchR.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = NChurchR.dequeue();
car.setDepartureTime(time);
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
if (!SChurchL.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = SChurchL.dequeue();
car.setDepartureTime(time);
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
if (!SChurchR.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = SChurchR.dequeue();
car.setDepartureTime(time);
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
i++;
}
}
/**
* This method mimics the above method. However, in this instance, only vehicles in the east
and west
* lanes will be operated on.
*/
private void moveEastWest() {
7. int i = 0;
while (i < 3) {
time+=3;
try {
if (!EMainL.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = EMainL.dequeue();
car.setDepartureTime(time);
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
if (!EMainR.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = EMainR.dequeue();
car.setDepartureTime(time);
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
if (!WMainL.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = WMainL.dequeue();
car.setDepartureTime(time);
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
if (!WMainR.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = WMainR.dequeue();
car.setDepartureTime(time);
outFile.println(car);
8. }
}
catch(EmptyCollectionException e) {}
i++;
}
}
/**
* This method goes through each queue and checks to see if they are empty. At the end, if all
queues are
* empty, it returns a true value. This method is later used to know when to stop the simulation.
*/
private boolean queuesEmpty(){
boolean empty;
empty = EMainL.isEmpty();
if(empty)
empty = EMainR.isEmpty();
if(empty)
empty = WMainL.isEmpty();
if(empty)
empty = WMainR.isEmpty();
if(empty)
empty = NChurchL.isEmpty();
if(empty)
empty = NChurchR.isEmpty();
if(empty)
empty = SChurchL.isEmpty();
if(empty)
empty = SChurchR.isEmpty();
return empty;
}
}
Driver.java
/**
9. * The Driver class acts as a container for the main method. There is not a
* specific inherent purpose for the class.
* @author Leah Lewy
*/
public class Driver {
/**
* All functionality of the Driver application exists within
* main method. It soley instantiates a simulator object and then runs a method
* that performs the entire simulation of the traffic intersection.
* @param args Permits functionality of the command line
*/
public static void main (String[] args) {
Simulator simulator = new Simulator();
simulator.Simulate();
}
}
Vehicle.java
/**
* The Vehicle class encapsulates the representation of a car object. Each vehicle is labeled with
a number.
* It is also marked by the time it arrives at the intersection and the time it departs. The object
also
* keeps track of which of the eight lanes the car is in at the intersection.
* @author Leah Lewy
*/
public class Vehicle {
/**
*This is the creation of the enumerated type direction with its possible values of
* north, east, west, or south.
*/
public enum Direction{N, E, S, W};
/**
*This is the creation of the enumerated type street with its possible values of
* Main or Church. This is later determined by which direction the car is going in.
*/
public enum Street{Main, Church};
10. /**
*This is the creation of the enumerated type lane with its possible values of
* left (car is continuing straight) or right (car is turning).
*/
public enum Lane{Left, Right};
/** This integer value will represent the vehicle number, which will start at 1 and increment
with each new car.*/
private int vehicleNumber;
/** This integer value will represent the time at which the car arrives at the intersection. */
private int arrivalTime;
/** This integer value will represent the time at which the car leaves at the intersection. */
private int departureTime;
/** This enumerated type will represent the street that the car pulls up at. */
private Street street;
/** This enumerated type will represent the direction in which the car is heading. */
private Direction direction;
/** This enumerated type will represent the lane in which the car is in. */
private Lane lane;
/** This string object will later be used in the toString to store the value of northbound,
eastbound, etc. */
private String bound;
/**
*This string object will later be used in the toString to store the phrase of where the car
continues after
*exiting the intersection.
*/
private String continuation;
/**
* This is a constructor. It sets up the ability for a car object to be instantiated.
* Each time a vehicle is created, it is provided a random direction, street, and lane as well
* as given the values it is passed in through the parameters.
* @param vehicleNum The int value of this object's vehicle number.
* @param aTime The int value of this object's arrival time.
* @param dTime The int value of this object's departure time.
*/
public Vehicle (int vehicleNum, int aTime, int dTime) {
11. vehicleNumber = vehicleNum;
arrivalTime = aTime;
departureTime = dTime;
direction = randomDirection();
street = randomStreet();
lane = randomLane();
}
/**
* This method assigns each new vehicle a randomly generated direction using the
Math.random function.
* @return the direction the car is headed
*/
public Direction randomDirection() {
int dirIndicator = (int)(Math.random() * (4 - 0) + 0);
if(dirIndicator == 1)
direction = Direction.N;
else if(dirIndicator == 2)
direction = Direction.E;
else if(dirIndicator == 3)
direction = Direction.S;
else
direction = Direction.W;
return direction;
}
/**
* This method assigns each new vehicle a street based on the previously generated direction
* from the above method.
* @return the street the car is on
*/
public Street randomStreet() {
if(direction == Direction.N || direction == Direction.S) {
street = Street.Church;
}
else
street = Street.Main;
return street;
12. }
/**
* This method assigns each new vehicle a randomly generated lane using the Math.random
function.
* @return the lane the car is in
*/
public Lane randomLane() {
int laneIndicator = (int)(Math.random() * (2 - 0) + 0);
if (laneIndicator ==1)
lane =Lane.Left;
else
lane = Lane.Right;
return lane;
}
/**
*This is an accessor method that allows an outside class to view the direction of a car object.
*@return the direction of the car
*/
public Direction getDirection() {
return direction;
}
/**
*This is an accessor method that allows an outside class to view the street of a car object.
*@return the street of the car
*/
public Street getStreet() {
return street;
}
/**
*This is an accessor method that allows an outside class to view the lane of a car object.
*@return the lane of the object
*/
public Lane getLane() {
return lane;
}
/**
13. *This is a mutator method that allows an outside class to set the departure time of a car object.
*@param the current time
*/
public void setDepartureTime(int time){
departureTime = time;
}
/**
*This is an accessor method that allows an outside class to view the vehicle number of a car
object.
*@return the vehicle number of the object
*/
public int getVehicleNumber() {
return vehicleNumber;
}
/**
* This method sets the string value of bound to the associated direction in which the car starts
off in.
* @return the string representation of the original bound
*/
public String getBound() {
if (direction == Direction.S)
return "southbound";
else if (direction == Direction.N)
return "northbound";
else if (direction == Direction.W)
return "westbound";
else
return"eastbound";
}
/**
* This method sets the string value of continuation to the associated direction in which the car
is headed.
* If the car is going straight, the direction stays the same. If the car is turning, the continuation
value
* mimics that by displaying a new bound that has shifted by 90 degrees.
14. * @return the string representation of the new bound
*/
private String getContinuation() {
if (lane == Lane.Left)
return "continued straight";
else if (lane ==Lane.Right&& direction == Direction.S)
return "turned right and headed westbound";
else if (lane ==Lane.Right&& direction == Direction.N)
return "turned right and headed eastbound";
else if (lane ==Lane.Right&& direction == Direction.W)
return "turned right and headed northbound";
else
return "turned right and headed southbound";
}
/**
*Returns a string representation of the object
*@return string representation
*/
public String toString() {
String waittime = String.format("%02d",
(departureTime - arrivalTime));
return "[Time " + String.format("%02d", departureTime) + "] Vehicle #" +
vehicleNumber + " (" + getBound() + ") " + getContinuation() + ". Total wait time " +
waittime + " seconds.";
}
}
LinearNode.java
package jsjf;
/**
* Represents a node in a linked data structure.
* @author Java Foundations
* @version 4.0
*/
public class LinearNode
{
private LinearNode next;
15. private T element;
/**
* Provides the ability to instantiate an empty node.
*/
public LinearNode()
{
next = null;
element = null;
}
/**
* Provides the ability to instantiate a node with that specific element
* @param the element to be stored
*/
public LinearNode(T elem)
{
next = null;
element = elem;
}
/**
* Returns the next node in the chain.
* @return reference to next node
*/
public LinearNode getNext()
{
return next;
}
/**
* Sets the next node in the chain.
* @param the node you want to be following
*/
public void setNext(LinearNode node)
{
16. next = node;
}
/**
* Returns the element stored in the current node.
* @return element stored at the node
*/
public T getElement()
{
return element;
}
/**
* Sets the element stored in the current node.
* @param element to be stored at the node
*/
public void setElement(T elem)
{
element = elem;
}
}
LinkedQueue.java
package jsjf;
import jsjf.exceptions.*;
/**
* LinkedQueue represents a linked implementation of a queue.
* @author Java Foundations
* @version 4.0
*/
public class LinkedQueue implements QueueADT
{
/** This integer value is used to help determine where you are in the linked queue. */
private int count;
/** This is an instantiation of the generic linked node class that will help move through the
elements of the queue.*/
private LinearNode head, tail;
17. /**
* Provides the ability to instantiate an empty queue.
* Since there are no elements, the front and end will be the same and equivalent to null.
*/
public LinkedQueue()
{
count = 0;
head = tail = null;
}
/**
* Adds the element to the end of this queue.
* @param the element to be added to the tail of the queue
*/
public void enqueue(T element)
{
LinearNode node = new LinearNode(element);
if (isEmpty())
head = node;
else
tail.setNext(node);
tail = node;
count++;
}
/**
* Removes and returns the element at the front of the queue and then moves the counter
accordingly.
* @return the element at the head of this queue
* @throws EmptyCollectionException if the queue is empty
*/
public T dequeue() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("queue");
T result = head.getElement();
head = head.getNext();
count--;
18. if (isEmpty())
tail = null;
return result;
}
/**
* Returns a reference to the element at the head of this queue without removing it.
* @return the first element in this queue
* @throws EmptyCollectionsException if the queue is empty
*/
public T first() throws EmptyCollectionException
{
if(!isEmpty())
return(head.getElement());
else
throw new EmptyCollectionException("Nothing to peek");
}
/**
* Returns true if this queue contains no elements.
* @return true if this queue is empty
*/
public boolean isEmpty()
{
return(count == 0);
}
/**
* Returns the number of elements currently in this queue.
* @return the number of elements in the queue
*/
public int size()
{
return(count);
}
/**
* Returns a string representation of this queue.
19. * @return the string representation of the queue
*/
public String toString()
{
String queueString = "";
try
{
LinearNode elem = head;
T elem2 = elem.getElement();
for(int i = count; i > 0; i--)
{
queueString += (elem2);
if(i > 1)
{
queueString += " ";
elem = elem.getNext();
elem2 = elem.getElement();
}
}
}
catch(NullPointerException e)
{
System.err.println("The tail is empty");
}
return queueString;
}
}
QueueADT.java
package jsjf;
/**
* QueueADT defines the interface to a queue collection.
* @author Java Foundation
20. * @version 4.0
*/
public interface QueueADT {
/**
* Adds one element to the end of the queue.
* @param the element that is going to be added
*/
public void enqueue(T element);
/**
* Removes and returns the element at the front of the queue.
* @return the first element in the queue
*/
public T dequeue();
/**
* Returns without removing the element at the front of the queue.
* @return the first element in the queue
*/
public T first();
/**
* Returns true if this queue contains no elements.
* @return true if this queue is empty
*/
public boolean isEmpty();
/**
* Returns the number of elements in this queue.
* @return the integer value of the size of the queue
*/
public int size();
/**
* Returns a string representation of this queue.
* @return the string representation of the queue
*/
public String toString();
}
EmptyCollectionException.java
21. package jsjf.exceptions;
/**
* Represents the situation in which a collection is empty.
* It inherits from the runtime exception class.
* @author Java Foundations
* @version 4.0
*/
public class EmptyCollectionException extends RuntimeException
{
/**
* Sets up this exception with a fitting message.
* @param the name of the collection
*/
public EmptyCollectionException(String collection)
{
super("The " + collection + " is empty.");
}
}package jsjf.exceptions;
/**
* Represents the situation in which a collection is empty.
* It inherits from the runtime exception class.
* @author Java Foundations
* @version 4.0
*/
public class EmptyCollectionException extends RuntimeException
{
/**
* Sets up this exception with a fitting message.
* @param the name of the collection
*/
public EmptyCollectionException(String collection)
{
super("The " + collection + " is empty.");
}
} Default intersection: Each street has 25.0% chance to get a new car each second Light changes
from red to green every 10 seconds. Simulation length is 1000 seconds 248 239 248 239 Cars
22. acrosS: Delay (tot) 2256 5565 4807 4069 Delay (avg): Stranded: 23 3 19 1 17 15 Enter a new car
creation chance (0.00- 1.00): .5 Enter a new duration for traffic light (seconds) 10 Your
intersection: Each street has 50.0% chance to get a new car each second Light changes from red
to green every 10 seconds. Simulation length is 1000 seconds 465 5028 10 485 8638 17 465
22864 8261 49 485 Cars across: Delay (tot): Delay (avg): Stranded: 17 19
Solution
I changed only three classes.
Driver.java
package jsjf;
import java.util.Scanner;
/**
* The Driver class acts as a container for the main method. There is not a
* specific inherent purpose for the class.
* @author LeahLewy
*/
public class Driver {
private static Scanner sc = new Scanner(System.in);
private int chance = 0;
private int seconds = 0;
/**
*
* All functionality of the Driver application exists within
* main method. It soley instantiates a simulator object and then runs a method
* that performs the entire simulation of the traffic intersection.
* @param args Permits functionality of the command line
*/
public static void main (String[] args) {
// Default intersection
Simulator simulator = new Simulator(0.25, 10);
simulator.Simulate();
int northSouthCars = simulator.getTotalNorthSouthCars();
int eastWestCars = simulator.getTotalEastWestCars();
int northDelay = simulator.getNorthDelay();
23. int southDelay = simulator.getSouthDelay();
int eastDelay = simulator.getEastDelay();
int westDelay = simulator.getWestDelay();
//Printing to screen
System.out.println("Default intersection: ");
System.out.println("Each street has 25% chance to get a new car each second.");
System.out.println("Light changes from red to green every 10 seconds.");
System.out.println("Simulation length is 1000 seconds");
System.out.println("ttNtEtStW");
System.out.println("Cars across:t" + northSouthCars + "t" + eastWestCars + "t" +
northSouthCars + "t" + eastWestCars);
System.out.println("Delay(total):t" + northDelay + "t" + eastDelay + "t" + southDelay
+ "t" + westDelay);
System.out.println("Delay(Avg):t" + (int)(northDelay/northSouthCars) + "t" +
(int)(eastDelay/eastWestCars) + "t" + (int)(southDelay/northSouthCars) + "t" +
(int)(westDelay/eastWestCars));
System.out.println("Stranded:t" + simulator.getNorthStranded() + "t" +
simulator.getEastStranded() + "t"+ simulator.getSouthStranded() + "t" +
simulator.getWestStranded());
// Your intersection
System.out.print(" Enter a new car creation chance (0.00 - 1.00): ");
double chance = sc.nextDouble();
System.out.print(" Enter a new duration for traffic light (seconds): ");
int changeTime = sc.nextInt();
Simulator yourSimulator = new Simulator(chance, changeTime);
yourSimulator.Simulate();
northSouthCars = yourSimulator.getTotalNorthSouthCars();
eastWestCars = yourSimulator.getTotalEastWestCars();
northDelay = yourSimulator.getNorthDelay();
southDelay = yourSimulator.getSouthDelay();
eastDelay = yourSimulator.getEastDelay();
westDelay = yourSimulator.getWestDelay();
//Printing to screen
System.out.print(" Your intersection: ");
System.out.println("Each street has " + (int)chance*100 + "% chance to get a new car each
24. second.");
System.out.println("Light changes from red to green every "+ changeTime+ " seconds.");
System.out.println("Simulation length is 1000 seconds");
System.out.println("ttNtEtStW");
System.out.println("Cars across:t" + northSouthCars + "t" + eastWestCars + "t" +
northSouthCars + "t" + eastWestCars);
System.out.println("Delay(total):t" + northDelay + "t" + eastDelay + "t" + southDelay
+ "t" + westDelay);
System.out.println("Delay(Avg):t" + (int)(northDelay/northSouthCars) + "t" +
(int)(eastDelay/eastWestCars) + "t" + (int)(southDelay/northSouthCars) + "t" +
(int)(westDelay/eastWestCars));
System.out.println("Stranded:t" + yourSimulator.getNorthStranded() + "t" +
yourSimulator.getEastStranded() + "t"+ yourSimulator.getSouthStranded() + "t" +
yourSimulator.getWestStranded());
}
}
Simulator.java
package jsjf;
import java.lang.Math;
import java.io.*;
import jsjf.*;
import jsjf.exceptions.*;
import java.util.*;
import java.net.*;
import java.io.*;
/**
*This class is where all action resides. It contains all the queues that represent the lanes at the
intersection.
* It also contains all methods that pertain to populating the intersection and moving the vehicles
in their
* retrospective directions.
*/
public class Simulator {
/** This queue will hold only vehicle objects that enter in the left lane on Main Street headed
East. */
private LinkedQueue EMainL = new LinkedQueue();
25. /** This queue will hold only vehicle objects that enter in the right lane on Main Street headed
East. */
private LinkedQueue EMainR = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the left lane on Main Street headed
West. */
private LinkedQueue WMainL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Main Street headed
West. */
private LinkedQueue WMainR = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the left lane on Church Street headed
North. */
private LinkedQueue NChurchL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Church Street headed
North. */
private LinkedQueue NChurchR = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the left lane on Church Street headed
South. */
private LinkedQueue SChurchL = new LinkedQueue();
/** This queue will hold only vehicle objects that enter in the right lane on Church Street headed
South. */
private LinkedQueue SChurchR = new LinkedQueue();
/** This integer value will keep track of the current time during the simulation.*/
int time = 0;
/** This integer value will be used to make sure only two vehicles move during each light
change for each lane. */
int i = 0;
/** This integer value will keep track of the vehicle numbers of the cars that arrive at the
intersection. */
int vehicleNum = 1;
/** This creates a filewriter object that allows us for the ability to write streams of characters to
a file. */
FileWriter fw;
/** This creates a bufferedwriter object that allows for the efficient writing to the file. */
BufferedWriter bw;
/** This creates a printwriter object that allows for the ability to use the print methods when
writing to the file. */
26. PrintWriter outFile;
/**
* This is for setting up the chance to get a new car every second
*/
double chance = 0.0;
/**
* This is to specify the time for light change
*/
int lightChangeTime = 0;
/**
* Varaibles to increment the delay time
*/
int totalNorthDelay = 0;
int totalSouthDelay = 0;
int totalEastDelay = 0;
int totalWestDelay = 0;
/**
* Varaibles to count the Number of cars
*/
int totalNorthCars = 0;
int totalEastCars = 0;
/**
* This is a constructor. It sets up the values for chance and light change time.
*/
public Simulator(double chance, int lightChangeTime) {
this.chance = chance;
this.lightChangeTime = lightChangeTime;
}
/**
* This method calls all others methods in this class. It firsts instantiates the objects associated
with
* writing to the file. It then calls the populate method to start the simulation and create car
objects. The
* amount of car objects created is between 7 and 12. Until all queues are empty, the simulation
will continue
* to run. During the simulation, the cars will move in the North/South direction for 6 seconds,
27. then more
* cars will arrive (between 8 and 15). Then the cars will move in the East/ West direction for 6
seconds,
* and more cars will arrive (between 3 and 15).
* @throws IOException this is done in case their is an error printing to the file
*/
public void Simulate() {
try {
fw = new FileWriter("output.txt");
bw = new BufferedWriter(fw);
outFile = new PrintWriter(bw);
int randomNumber;
outFile.print("---Start of simulation, time set to 0.--- ");
randomNumber = carProbability(chance);
populate(randomNumber);
while(time<=1000) {
outFile.print("---Light changed. Now processing north/south-bound traffic--- ");
moveNorthSouth();
randomNumber = carProbability(chance);
populate(randomNumber);
outFile.println();
outFile.print("---Light changed. Now processing east/west-bound traffic--- ");
moveEastWest();
randomNumber = carProbability(chance);
populate(randomNumber);
outFile.println();
}
outFile.close();
}
catch(IOException e){
System.err.println("Error printing to file");
}
}
/**
* This method is only called once when first populating the intersection. It instantiates the
amount of cars
28. * according to the number that is passed in. The time they are created, their arrival times, is
* the current time in the simulation. Each time a new vehicle is created, the vehicle number
increases by 1.
* Depending on what lane and direction the car enters the simulation, it is placed correctly into
its
* corresponding queue.
* @param number of cars to be instantiated
*/
private void populate(int randomNum) {
int count = 0;
while (count < randomNum && time <=1000) {
Vehicle car = new Vehicle(vehicleNum, time, time);
count++;
vehicleNum++;
if (car.getStreet() == Vehicle.Street.Main && car.getDirection() == Vehicle.Direction.E &&
car.getLane() == Vehicle.Lane.Left)
{
EMainL.enqueue(car);
totalEastCars++;
}
else if (car.getStreet() == Vehicle.Street.Main && car.getDirection() == Vehicle.Direction.E
&& car.getLane() == Vehicle.Lane.Right)
{
EMainR.enqueue(car);
totalEastCars++;
}
else if (car.getStreet() == Vehicle.Street.Main && car.getDirection() == Vehicle.Direction.W
&& car.getLane() == Vehicle.Lane.Left)
{
WMainL.enqueue(car);
totalEastCars++;
}
else if (car.getStreet() == Vehicle.Street.Main && car.getDirection() == Vehicle.Direction.W
&& car.getLane() == Vehicle.Lane.Right)
{
WMainR.enqueue(car);
29. totalEastCars++;
}
else if (car.getStreet() == Vehicle.Street.Church && car.getDirection() == Vehicle.Direction.N
&& car.getLane() == Vehicle.Lane.Left)
{
NChurchL.enqueue(car);
totalNorthCars++;
}
else if (car.getStreet() == Vehicle.Street.Church && car.getDirection() == Vehicle.Direction.N
&& car.getLane() == Vehicle.Lane.Right)
{
NChurchR.enqueue(car);
totalNorthCars++;
}
else if (car.getStreet() == Vehicle.Street.Church && car.getDirection() == Vehicle.Direction.S
&& car.getLane() == Vehicle.Lane.Left)
{
SChurchL.enqueue(car);
totalNorthCars++;
}
else
{
SChurchR.enqueue(car);
totalNorthCars++;
}
}
}
/**
* This method simulates the movement of vehicles in the North / South direction. Four queues
are operated
* on at this traffic light, but the NChurchL one will be used to exemplify the functionality of the
method.
* If there are cars waiting to move and while only two are allowed to move, a new vehicle
object is
* instantiated. The first car in the spot is then dequeued and stored into the new car object. Its
departure
30. * time is set to the current time on the clock, which was previously increased by 3 seconds each
time the loop
* begins.
* @throws EmptyCollectionException this is done in case the queue is empty
*/
private void moveNorthSouth() {
int i = 0;
while (i < 2) {
time+=lightChangeTime;
try {
if (!NChurchL.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = NChurchL.dequeue();
car.setDepartureTime(time);
totalNorthDelay = totalNorthDelay + car.getWaitTime();
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
if (!NChurchR.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = NChurchR.dequeue();
car.setDepartureTime(time);
totalNorthDelay = totalNorthDelay + car.getWaitTime();
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
if (!SChurchL.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = SChurchL.dequeue();
car.setDepartureTime(time);
totalSouthDelay = totalSouthDelay + car.getWaitTime();
outFile.println(car);
31. }
}
catch(EmptyCollectionException e) {}
try {
if (!SChurchR.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = SChurchR.dequeue();
car.setDepartureTime(time);
totalSouthDelay = totalSouthDelay + car.getWaitTime();
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
i++;
}
}
/**
* This method mimics the above method. However, in this instance, only vehicles in the east
and west
* lanes will be operated on.
*/
private void moveEastWest() {
int i = 0;
while (i < 3) {
time+=lightChangeTime;
try {
if (!EMainL.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = EMainL.dequeue();
car.setDepartureTime(time);
totalEastDelay = totalEastDelay + car.getWaitTime();
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
32. if (!EMainR.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = EMainR.dequeue();
car.setDepartureTime(time);
totalEastDelay = totalEastDelay + car.getWaitTime();
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
if (!WMainL.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = WMainL.dequeue();
car.setDepartureTime(time);
totalWestDelay = totalWestDelay + car.getWaitTime();
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
try {
if (!WMainR.isEmpty()) {
Vehicle car = new Vehicle(0,0,0);
car = WMainR.dequeue();
car.setDepartureTime(time);
totalWestDelay = totalWestDelay + car.getWaitTime();
outFile.println(car);
}
}
catch(EmptyCollectionException e) {}
i++;
}
}
/**
* This method goes through each queue and checks to see if they are empty. At the end, if all
queues are
* empty, it returns a true value. This method is later used to know when to stop the simulation.
33. */
private boolean queuesEmpty(){
boolean empty;
empty = EMainL.isEmpty();
if(empty)
empty = EMainR.isEmpty();
if(empty)
empty = WMainL.isEmpty();
if(empty)
empty = WMainR.isEmpty();
if(empty)
empty = NChurchL.isEmpty();
if(empty)
empty = NChurchR.isEmpty();
if(empty)
empty = SChurchL.isEmpty();
if(empty)
empty = SChurchR.isEmpty();
return empty;
}
/**
* calculates the number of cars to be created
* @param chance
* @return the number of cars to be created - Integer
*/
private int carProbability(double chance)
{
return (int)(chance*10*Math.random() * (11 - 1) + 1);
}
/**
* Returns the number of total cars across north and south
*/
public int getTotalNorthSouthCars()
34. {
return totalNorthCars;
}
/**
* Returns the number of total cars across East and west
*/
public int getTotalEastWestCars()
{
return totalEastCars;
}
/**
* Returns the number of total delay time for north cars
*/
public int getNorthDelay()
{
return totalNorthDelay;
}
/**
* Returns the number of total delay time for south cars
*/
public int getSouthDelay()
{
return totalSouthDelay;
}
/**
* Returns the number of total delay time for east cars
*/
public int getEastDelay()
{
return totalEastDelay;
}
/**
* Returns the number of total delay time for west cars
*/
public int getWestDelay()
{
35. return totalWestDelay;
}
/**
* Returns the number of cars stranded for West direction
*/
public int getWestStranded()
{
return WMainL.size() + WMainR.size();
}
/**
* Returns the number of cars stranded for North direction
*/
public int getNorthStranded()
{
return NChurchL.size() + NChurchR.size();
}
/**
* Returns the number of cars stranded for South direction
*/
public int getSouthStranded()
{
return SChurchL.size() + SChurchL.size();
}
/**
* Returns the number of cars stranded for East direction
*/
public int getEastStranded()
{
return EMainL.size() + EMainR.size();
}
}
Vehicle.java
package jsjf;
import javax.print.attribute.standard.RequestingUserName;
/**
* The Vehicle class encapsulates the representation of a car object. Each vehicle is labeled with a
36. number.
* It is also marked by the time it arrives at the intersection and the time it departs. The object
also
* keeps track of which of the eight lanes the car is in at the intersection.
* @author LeahLewy
*/
public class Vehicle {
/**
*This is the creation of the enumerated type direction with its possible values of
* north, east, west, or south.
*/
public enum Direction{N, E, S, W};
/**
*This is the creation of the enumerated type street with its possible values of
* Main or Church. This is later determined by which direction the car is going in.
*/
public enum Street{Main, Church};
/**
*This is the creation of the enumerated type lane with its possible values of
* left (car is continuing straight) or right (car is turning).
*/
public enum Lane{Left, Right};
/** This integer value will represent the vehicle number, which will start at 1 and increment
with each new car.*/
private int vehicleNumber;
/** This integer value will represent the time at which the car arrives at the intersection. */
private int arrivalTime;
/** This integer value will represent the time at which the car leaves at the intersection. */
private int departureTime;
/** This enumerated type will represent the street that the car pulls up at. */
private Street street;
/** This enumerated type will represent the direction in which the car is heading. */
private Direction direction;
/** This enumerated type will represent the lane in which the car is in. */
private Lane lane;
/** This string object will later be used in the toString to store the value of northbound,
37. eastbound, etc. */
private String bound;
/**
*This string object will later be used in the toString to store the phrase of where the car
continues after
*exiting the intersection.
*/
private String continuation;
/**
* This is a constructor. It sets up the ability for a car object to be instantiated.
* Each time a vehicle is created, it is provided a random direction, street, and lane as well
* as given the values it is passed in through the parameters.
* @param vehicleNum The int value of this object's vehicle number.
* @param aTime The int value of this object's arrival time.
* @param dTime The int value of this object's departure time.
*/
public Vehicle (int vehicleNum, int aTime, int dTime) {
vehicleNumber = vehicleNum;
arrivalTime = aTime;
departureTime = dTime;
direction = randomDirection();
street = randomStreet();
lane = randomLane();
}
/**
* This method assigns each new vehicle a randomly generated direction using the
Math.random function.
* @return the direction the car is headed
*/
public Direction randomDirection() {
int dirIndicator = (int)(Math.random() * (4 - 0) + 0);
if(dirIndicator == 1)
direction = Direction.N;
else if(dirIndicator == 2)
direction = Direction.E;
else if(dirIndicator == 3)
38. direction = Direction.S;
else
direction = Direction.W;
return direction;
}
/**
* This method assigns each new vehicle a street based on the previously generated direction
* from the above method.
* @return the street the car is on
*/
public Street randomStreet() {
if(direction == Direction.N || direction == Direction.S) {
street = Street.Church;
}
else
street = Street.Main;
return street;
}
/**
* This method assigns each new vehicle a randomly generated lane using the Math.random
function.
* @return the lane the car is in
*/
public Lane randomLane() {
int laneIndicator = (int)(Math.random() * (2 - 0) + 0);
if (laneIndicator ==1)
lane =Lane.Left;
else
lane = Lane.Right;
return lane;
}
/**
*This is an accessor method that allows an outside class to view the direction of a car object.
*@return the direction of the car
*/
public Direction getDirection() {
39. return direction;
}
/**
*This is an accessor method that allows an outside class to view the street of a car object.
*@return the street of the car
*/
public Street getStreet() {
return street;
}
/**
*This is an accessor method that allows an outside class to view the lane of a car object.
*@return the lane of the object
*/
public Lane getLane() {
return lane;
}
/**
*This is a mutator method that allows an outside class to set the departure time of a car object.
*@param the current time
*/
public void setDepartureTime(int time){
departureTime = time;
}
/**
*This is an accessor method that allows an outside class to view the vehicle number of a car
object.
*@return the vehicle number of the object
*/
public int getVehicleNumber() {
return vehicleNumber;
}
/**
* This method sets the string value of bound to the associated direction in which the car starts
off in.
* @return the string representation of the original bound
40. */
public String getBound() {
if (direction == Direction.S)
return "southbound";
else if (direction == Direction.N)
return "northbound";
else if (direction == Direction.W)
return "westbound";
else
return"eastbound";
}
/**
* This method sets the string value of continuation to the associated direction in which the car
is headed.
* If the car is going straight, the direction stays the same. If the car is turning, the continuation
value
* mimics that by displaying a new bound that has shifted by 90 degrees.
* @return the string representation of the new bound
*/
private String getContinuation() {
if (lane == Lane.Left)
return "continued straight";
else if (lane ==Lane.Right&& direction == Direction.S)
return "turned right and headed westbound";
else if (lane ==Lane.Right&& direction == Direction.N)
return "turned right and headed eastbound";
else if (lane ==Lane.Right&& direction == Direction.W)
return "turned right and headed northbound";
else
return "turned right and headed southbound";
}
/**
*Returns a string representation of the object
*@return string representation
*/
public String toString() {
41. String waittime = String.format("%02d",(departureTime - arrivalTime));
return "[Time " + String.format("%02d", departureTime) + "] Vehicle #" + vehicleNumber
+ " (" + getBound() + ") " + getContinuation() + ". Total wait time " + waittime + "
seconds.";
}
/**
*Returns the wait time for the car object
*/
public int getWaitTime()
{
String waittime = String.format("%02d",(departureTime - arrivalTime));
return Integer.valueOf(waittime);
}
}
OUTPUT:
Default intersection:
Each street has 25% chance to get a new car each second.
Light changes from red to green every 10 seconds.
Simulation length is 1000 seconds
N E S W
Cars across: 261 246 261 246
Delay(total): 23230 8050 20020 7760
Delay(Avg): 89 32 76 31
Stranded: 41 9 86 4
Enter a new car creation chance (0.00 - 1.00): 0.5
Enter a new duration for traffic light (seconds): 10
Your intersection: Each street has 0% chance to get a new car each second.
Light changes from red to green every 10 seconds.
Simulation length is 1000 seconds
N E S W
Cars across: 472 448 472 448
Delay(total): 31740 37300 31560 33160
Delay(Avg): 67 83 66 74
Stranded: 148 116 144 80