// Copyright 1999 Regents of The University of Michigan
// This makes all public classes defined for the simulator package available to this class
import umich.coabs.simulator.*;
/**
This class is a decision maker that controls the single transport
in its entities list. The transport wanders aimlessly through
the network, stopping at each location to allow evacuees to embark
or disembark. It has a very simple state machine and can get stuck
if one of its actions fails.
@author Brad Clement, bradc@umich.edu
*/
public class TransportDecisionMaker extends DecisionMaker {
int state = 0; // the state of the state machine
Location destination; // global variable for keeping track of where it wants to go
/**
Just passes basics up to the costructor of the parent class, DecisionMaker
*/
public TransportDecisionMaker(String i, LinkedList e, Control c) {
super(i, e, c);
}
/**
This is the method that is called on each decision cycle by the Control
object of the simulator. It controls the behavior of the transport in
its entities list. Sometimes the transports will not successfully
move to a location. The results of these action failures are defined in
the Transport class. The default is nothing changes, and a message is printed.
Additionally, this decision maker often winds up in the wrong state and gets
stuck when an action fails. For example, this can happen when two transports
try to go opposite ways on a one-lane road or when a transport tries to traverse
a route that has been destroyed.
*/
public void TakeStep() {
ListElement elem; // for stepping through lists
int i, n;
Route r; // the chosen route to traverse
double time = 0.0; // used to wait for a specified time
Transport me = (Transport)entities.head.data; // get the transport at the front of the entities list
// Take step for state 0
if (state == 0) {
// pick a random route to traverse; assign it to r
n = (int) (me.getCurLocation().getRoutes().size * java.lang.Math.random());
if (n == me.getCurLocation().getRoutes().size)
--n;
elem = me.getCurLocation().getRoutes().head;
for (i = 0; i < n; i++)
elem = elem.next;
r = (Route) elem.data;
// get the location at the other end of the route
if (r.getEndpt1() == me.getCurLocation())
destination = r.getEndpt2();
else
destination = r.getEndpt1();
// move the transport along the chosen route; additionally destroy the route with 0.0 probability
if (java.lang.Math.random() < 1.0)
me.Move(destination, r);
else
me.MoveAndDestroy(destination, r);
// go to next state
state = 1;
} else
// take step for state 1
if (state == 1) {
// if transport has arrived at its destination, set a timer to wait at the current location
// to let evacuees embark or disembark
if (me.getCurLocation() == destination) {
time = ctrl.getTime();
state = 2;
}
} else
// take step for state 2
if (state == 2) {
// if time is up go back to state 0 to move to another location
if (ctrl.getTime() - time >= 4.0)
state = 0;
}
}
}