#include<String>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<ctime>
#include "Passenger.hpp"
#include "PassengerQueue.hpp"
#include "Platform.hpp"
#include "Train.hpp"
#include "CTrainLine.hpp"
#include "PassengerList.hpp"
using namespace std;
void wait(int sec);
int main(){
Platform a1UptownRed("a1","up","red"),
a2UptownRed("a2","up","red"),
a3UptownRed("a3","up","red"),
a3DowntownRed("a3","down","red"),
a2DowntownRed("a2","down","red"),
a1DowntownRed("a1","down","red");
CTrainLine redLine;
redLine.add(a1UptownRed);
redLine.add(a2UptownRed);
redLine.add(a3UptownRed);
redLine.add(a3DowntownRed);
redLine.add(a2DowntownRed);
redLine.add(a1DowntownRed);
redLine.getNext(a1UptownRed);
redLine.getNext(a2UptownRed);
redLine.getNext(a3UptownRed);
redLine.getNext(a3DowntownRed);
redLine.getNext(a2DowntownRed);
redLine.getNext(a1DowntownRed);
//TRAIN TEST
Train pelham(redLine, a1UptownRed);
for(int n = 0; n < 60; n++){
pelham.displayTrainInfo();
pelham.update();
wait(1);
}
/* seeking the seg fault
Platform *a1u, *a2u, *a3u, *a1d, *a2d, *a3d;
a1u = &a1UptownRed;
a2u = &a2UptownRed;
a3u = &a3UptownRed;
a3d = &a3DowntownRed;
a2d = &a2DowntownRed;
a1d = &a1DowntownRed;
a1d = 0;
Platform gru;
gru = redLine.getNext(*a1u);
gru = redLine.getNext(*a2u);
gru = redLine.getNext(*a3u);
gru = redLine.getNext(*a3d);
gru = redLine.getNext(*a2d);
cout << "HERE?" << endl;
gru = redLine.getNext(*a1d);
cout << "!!!!" << endl;
*/
/* Passenger.onSameLine() test
Passenger anon;
cout << "a3 and b3 on same line?" << endl;
cout << anon.onSameLine("a3","b3") << endl;
cout << "a1 and a4 on same line?" << endl;
cout << anon.onSameLine("a1","a4") << endl;
cout << "b1 and a4 on same line?" << endl;
cout << anon.onSameLine("b1","a4") << endl;
/*
/* PASSENGERLIST TEST
Passenger john("John"), paul("Paul"), george("George"), ringo("Ringo"), anon;
PassengerList pList;
pList.add(john);
pList.add(paul);
pList.add(george);
pList.add(ringo);
pList.add(anon);
pList.displayList();
*/
/* TRAINLINE TEST
redLine.displayList();
cout << "\n\nThere are " << redLine.getNumStops(a1UptownRed,a3UptownRed) << " stops between A1 & A3 going uptown" << endl;
cout << "\n\nThere are " << redLine.getNumStops(a1DowntownRed,a3DowntownRed) << " stops between A1 & A3 going downtown" << endl;
*/
/* //PLATFORM LINE TEST
Passenger * pDoe;
for(int n = 0; n < 50; n++){
pDoe = new Passenger;
a1UptownRed.placeOnLine(*pDoe);
}
a1UptownRed.displayWaitLines();
for(int n = 0; n < 25; n++){
try{
a1UptownRed.getNextPassenger(n%3+1);
} catch(...){}
}
a1UptownRed.displayWaitLines();
*/
system("PAUSE");
return 0;
}
void wait(int sec){
clock_t endwait;
endwait = clock() + sec * CLK_TCK;
while (clock() < endwait) {}
}
#ifndef CTrainLine_class
#define CTrainLine_class
#include "Platform.hpp"
#include <iostream>
using namespace std;
class CTrainLine{
public:
struct ListNode{
Platform data;
ListNode * next;
};
CTrainLine();
~CTrainLine(); //Destructor deletes all nodes to prevent memory leak
bool isEmpty();
void add(Platform P);
ListNode * find(int pos); //Returns a pointer to a node by position number
ListNode * find(Platform plat);
int getSize();
Platform remove(int pos); //Removes & deletes a node
Platform retrieve(int pos); //Retrieves the data of node
Platform getNext(Platform plat);
void displayList();
int getNumStops(Platform p1, Platform p2);
private:
ListNode * head;
ListNode * last;
int size;
};
CTrainLine::CTrainLine() {
size = 0;
head = new ListNode;
}
bool CTrainLine::isEmpty(){
if(!size)
return true;
else return false;
}
void CTrainLine::add(Platform item){
ListNode * temp = new ListNode;
temp->data = item;
if(isEmpty()){
head->next = temp;
temp->next = temp;
}
else {
temp->next = head->next;
last->next = temp;
}
last = temp;
size++;
}
int CTrainLine::getSize(){
return size+1;
}
struct CTrainLine::ListNode * CTrainLine::find(int pos){
if(pos < 1 || pos > size)
throw 1;
else{
ListNode * temp = head;
for(int n = 0; n < pos; n++)
temp = temp->next;
return temp;
}
}
struct CTrainLine::ListNode * CTrainLine::find(Platform plat){
ListNode * curr = head;
for(int n = 0; n < size; n++){
curr = curr->next;
if(curr->data == plat)
return curr;
}
cout << "ERROR: ";
plat.displayInfo();
cout << "\n ... not found on line" << endl;
}
Platform CTrainLine::remove(int pos){
try{
if(pos < 1 || pos > size)
throw 5;
else{
Platform data;
ListNode * curr,
* prev;
if(pos == 1)
prev = head;
else
prev = find(pos-1);
curr = prev->next;
prev->next = curr->next;
data = curr->data;
if(curr == last)
last = prev;
delete curr;
size--;
return data;
}
} catch(...){
cout << "ERROR: CTrainLine trying to remove nonexistant item" << endl;
}
}
Platform CTrainLine::retrieve(int pos){
ListNode * curr = find(pos);
return curr->data;
}
Platform CTrainLine::getNext(Platform plat){
ListNode * curr = find(plat);
return ((curr->next)->data);
}
void CTrainLine::displayList(){
ListNode * curr = head;
cout << "Total size of list: " << size << endl;
if(!isEmpty()){
for(int n = 0; n < size; n++){
curr = curr -> next;
curr->data.displayInfo();
if(n < size-1)
cout << "... links to ..." << endl;
}
curr = curr -> next;
cout << "... which links back to ..." << endl;
curr->data.displayInfo();
}
}
int CTrainLine::getNumStops(Platform p1, Platform p2){
ListNode * curr = find(p1);
for(int n = 0; n < size; n++){
if (curr->data == p2)
return n;
else
curr = curr->next;
}
cout << "ERROR: ";
p1.displayInfo();
cout << "... and ... " << endl;
p2.displayInfo();
cout << "Don't appear on the same track." << endl;
return -1;
}
CTrainLine::~CTrainLine(){
for(int n = size; size > 0; n--)
remove(n);
}
#endif
#ifndef platform_class
#define platform_class
#include "Passenger.hpp"
#include "PassengerQueue.hpp"
using namespace std;
class Platform{
public:
Platform();
Platform(string station, string direction, string tLine);
string direction,
station,
line;
PassengerQueue waitLines[12];
void placeOnLine(Passenger pass);
int getTotalWaiting();
string getStation();
string getDirection();
string getLine();
bool isEmpty();
Passenger getNextPassenger(int carSection);
void displayInfo();
bool operator==(Platform &p2);
bool hasTrain();
void setTrain(bool T);
void displayWaitLines();
private:
bool train;
int totalWaiting,
lastQueueUsed;
};
Platform::Platform(){
station = "DEFAULT STATION";
direction = "DEFAULT DIRECTION";
line = "DEFAULT LINE";
totalWaiting = 0;
lastQueueUsed = 0;
train = false;
}
Platform::Platform(string stat, string dir, string tLine){
station = stat;
direction = dir;
line = tLine;
totalWaiting = 0;
lastQueueUsed = 0;
train = false;
}
Passenger Platform::getNextPassenger(int carSection){
try{
int line = ((carSection - 1)*4)+lastQueueUsed%4; //randomly unloads a line within a car range 1:0-3, 2:4-7,3:8:11
lastQueueUsed++;
Passenger result = (waitLines[line]).dequeue();
result.setWaiting(false);
totalWaiting--;
return result;
} catch(...){}
}
string Platform::getStation(){
return station;
}
string Platform::getDirection(){
return direction;
}
string Platform::getLine(){
return line;
}
void Platform::placeOnLine(Passenger pass){
(waitLines[lastQueueUsed]).enqueue(pass);
pass.setWaiting(true);
totalWaiting++;
lastQueueUsed++;
lastQueueUsed %= 12;
}
void Platform::displayInfo(){
cout << getLine() << "\t" << getDirection() << "\t" << getStation() << "\t" << "Waiting: " << getTotalWaiting() << endl;
}
int Platform::getTotalWaiting(){
return totalWaiting;
}
bool Platform::isEmpty(){
return (totalWaiting == 0);
}
bool Platform::operator==(Platform &p2){
return (getLine() == p2.getLine() &&
getDirection() == p2.getDirection() &&
getStation() == p2.getStation());
}
bool Platform::hasTrain(){
return train;
}
void Platform::setTrain(bool t){
train = t;
}
void Platform::displayWaitLines(){
int tLine;
cout << "Waitlines for " << direction << " platform on " << line << " line at " << station << " station..." << endl;
for(int j = 0; j < 3; j++){ //1 to 3 cars
cout << "Car " << (j+1) << " : ";
for(int k = 0; k < 4; k++){ // 0 to 3 lines
if(k) cout << "\t";
tLine = j*4 + k;
cout << "Line " << (k+1) << " ... " << waitLines[tLine].getSize() << endl;
}
}
}
#endif
#ifndef train_class
#define train_class
#include "Passenger.hpp"
#include "PassengerQueue.hpp"
#include "PassengerList.hpp"
#include "Platform.hpp"
#include "CTrainLine.hpp"
#define CAR_CAPACITY 64
#define TRIP_LENGTH 3
class Train{
public:
Train(CTrainLine tLine, Platform start);
Train(CTrainLine tLine, Platform prev, int travelTime);
void update();
void travel();
void board();
CTrainLine getLine();
Platform getNextPlat();
Platform getPrevPlat();
Platform getCurrPlat();
string getStatus();
void setStatus(string newstat);
int getPop();
int getTripTime();
void displayTrainInfo();
private:
PassengerList cars[3];
CTrainLine trainline;
string status,
location;
Platform * nextPlat, * prevPlat, * currPlat;
int tripTime;
};
Train::Train(CTrainLine tLine, Platform start){
location = start.getStation();
trainline = tLine;
currPlat = new Platform;
prevPlat = new Platform;
nextPlat = new Platform;
*currPlat = start;
*nextPlat = tLine.getNext(start);
prevPlat = 0;
tripTime = 0;
status = "traveling";
}
Train::Train(CTrainLine tLine, Platform prev, int travelTime){
trainline = tLine;
*nextPlat = trainline.getNext(prev);
currPlat = 0;
*prevPlat = prev;
tripTime = travelTime;
location = "Between " + prev.getStation() + " and " + nextPlat->getStation();
status = "traveling";
}
void Train::update(){
if(status != "boarding"){
tripTime++;
if(tripTime >= TRIP_LENGTH){
if(getNextPlat().hasTrain()){
status = "waiting";
} else {
board();
}
}
} else
travel();
}
void Train::travel(){
currPlat->setTrain(false);
status = "traveling";
prevPlat = currPlat;
currPlat = 0;
tripTime = 0;
location = "Between " + prevPlat->getStation() + " and " + nextPlat->getStation();
}
//INCOMPLETE
void Train::board(){
tripTime = 0;
currPlat = nextPlat;
nextPlat = new Platform;
/*
cout << "3" <<endl;
nextPlat->displayInfo();
currPlat->displayInfo();
*/
Platform currP = *currPlat;
// currP.displayInfo();
// cout << "3.25" << endl;
Platform next = trainline.getNext(currP);
// cout << "3.5" << endl;
*nextPlat = next;
// cout << "4" << endl;
/*
if(nextPlat && currPlat)
11(*nextPlat) = trainline.getNext(*currPlat);
*/
// cout << "5" << endl;
currPlat->setTrain(true);
status = "boarding";
Passenger thisP;
for(int n = 0; n < 3; n++){ //Let off passengers
int total = cars[n].getSize()+1;
for(int k = 1; k < total; k++){ //For every passenger in every car
thisP = cars[n].retrieve(k);
if(thisP.getNextStation() == currPlat->getStation()){ //If this is his station...
cars[n].remove(k); // he leaves the car
thisP.popStation(); // he crosses this station off his path
if(thisP.isAtDestination()){ // If this is his final destination...
// passMan.removePassenger(thisP); //He should be removed from the simulation
} else{ //Otherwise...
// Platform nextPlat = passMan.findRoute(*currPlat.getStation(), thisP.getNextStation()); //He finds the platform to go to the next station
nextPlat->placeOnLine(thisP); //And he gets on line
}
}
}
}
}
CTrainLine Train::getLine(){
return trainline;
}
Platform Train::getNextPlat(){
return *nextPlat;
}
Platform Train::getPrevPlat(){
return *prevPlat;
}
Platform Train::getCurrPlat(){
return *currPlat;
}
string Train::getStatus(){
return status;
}
void Train::setStatus(string newstat){
status = newstat;
}
int Train::getPop(){
return (cars[0].getSize() + cars[1].getSize() + cars[2].getSize());
}
int Train::getTripTime(){
return tripTime;
}
void Train::displayTrainInfo(){
cout << "Train is at " << location << " -- " << status << " -- " << getPop() << " passengers" << endl;
}
#endif
#ifndef PassengerQueue_class
#define PassengerQueue_class
#include "Passenger.hpp"
using namespace std;
class PassengerQueue{
public:
struct qNode{
Passenger data;
qNode * next;
};
PassengerQueue();
bool isEmpty();
int getSize();
void enqueue(Passenger pass);
Passenger dequeue();
void displayQueue();
~PassengerQueue();
private:
qNode * front;
qNode * back;
int size;
};
PassengerQueue::PassengerQueue(){
size = 0;
front = 0;
back = 0;
}
bool PassengerQueue::isEmpty(){
return (!front);
}
int PassengerQueue::getSize(){
return size;
}
void PassengerQueue::enqueue(Passenger item){
qNode * node = new qNode;
node -> data = item;
node -> next = 0;
if(!front)
front = node;
else
back -> next = node;
back = node;
size++;
}
Passenger PassengerQueue::dequeue(){
try{
if(isEmpty())
throw 1;
else{
qNode * temp = front;
front = front -> next;
if(!front)
back = 0;
Passenger result = temp -> data;
delete temp;
size--;
return result;
}
}
catch(...){
// cout << "ERROR: Attempt to dequeue empty queue" << endl;
}
}
void PassengerQueue::displayQueue(){
cout << "Queue Size: " << getSize() << endl;
qNode * temp;
for(int n = 0; n < size; n++){
if(!n)
temp = front;
else
temp = temp -> next;
cout << "Item " << n << ": " << (temp->data).getName() << endl;
}
}
PassengerQueue::~PassengerQueue(){
qNode * curr;
qNode * next;
for(int n = 0; n < size; n++)
dequeue();
}
#endif
#ifndef passengerlist_class
#define passengerlist_class
#include <iostream>
#include "Passenger.hpp"
using namespace std;
class PassengerList{
public:
struct pNode{
Passenger data;
pNode * next;
};
PassengerList();
~PassengerList(); //Destructor deletes all nodes to prevent memory leak
bool isEmpty();
void add(Passenger P);
pNode * find(int pos); //Returns a pointer to a node by position number
int getSize();
Passenger remove(int pos); //Removes & deletes a node
Passenger retrieve(int pos); //Retrieves the data of node
void displayList();
private:
pNode * head;
int size;
};
PassengerList::PassengerList() {
size = 0;
head = new pNode;
}
bool PassengerList::isEmpty(){
if(!size)
return true;
else return false;
}
void PassengerList::add(Passenger item){
pNode * temp = new pNode;
temp->data = item;
if(isEmpty())
head->next = temp;
else
find(size)->next = temp;
size++;
}
int PassengerList::getSize(){
return size;
}
struct PassengerList::pNode * PassengerList::find(int pos){
if(pos < 1 || pos > size)
throw 1;
else{
pNode * temp = head;
for(int n = 0; n < pos; n++)
temp = temp->next;
return temp;
}
}
Passenger PassengerList::remove(int pos){
try{
if(pos < 1 || pos > size || isEmpty())
throw 5;
else{
Passenger data;
pNode * curr,
* prev;
if(pos == 1)
prev = head;
else
prev = find(pos-1);
curr = prev->next;
prev->next = curr->next;
data = curr->data;
delete curr;
size--;
return data;
}
} catch(...){
cout << "ERROR: PassengerList trying to remove nonexistant item" << endl;
}
}
Passenger PassengerList::retrieve(int pos){
pNode * curr = find(pos);
return curr->data;
}
void PassengerList::displayList(){
pNode * curr = head;
cout << "List size: " << size << endl;
for(int n = 0; n < size; n++){
curr = curr->next;
cout << "Entry " << (n+1) << ": " << curr->data.getName() << endl;
}
}
PassengerList::~PassengerList(){
for(int n = size; size > 0; n--)
remove(n);
}
#endif
#ifndef passenger_class
#define passenger_class
#include <String>
#define LATE_THRESH 45
using namespace std;
class Passenger{
public:
Passenger();
Passenger(string pName, string entry, string dest);
void update();
void update(int min);
int getWaitTime();
int getTotalTime();
string getName();
string getPOE();
string getDestination();
bool isAtDestination();
void popStation();
string getNextStation();
void setWaiting(bool w);
bool isWaiting();
bool isLate();
bool mustTransfer();
private:
bool onSameLine(string entry,string dest);
string name,
path[3];
int destPointer,
waitTime,
totalTime;
bool transfer,
waiting,
late;
};
Passenger::Passenger(){
name = "John Doe";
waitTime = 0;
totalTime = 0;
waiting = false;
late = false;
}
Passenger::Passenger(string pName, string entry = "DEFAULT", string dest = "DEFAULT"){
name = pName;
path[0] = entry;
destPointer = 0;
if(onSameLine(entry,dest)){
path[1] = dest;
transfer = false;
}
else{
path[1] = "b3";
path[2] = dest;
transfer = true;
}
waitTime = 0;
totalTime = 0;
waiting = false;
late = false;
}
void Passenger::update(){
update(1);
}
void Passenger::update(int min){
waitTime += min;
totalTime += min;
if((!late) && (totalTime > LATE_THRESH))
late = true;
}
int Passenger::getWaitTime(){
return waitTime;
}
int Passenger::getTotalTime(){
return totalTime;
}
string Passenger::getName(){
return name;
}
string Passenger::getPOE(){
return path[0];
}
string Passenger::getDestination(){
if(transfer)
return path[2];
else
return path[1];
}
bool Passenger::isAtDestination(){
if((transfer && destPointer == 3) ||
(!transfer && destPointer == 4))
return true;
else
return false;
}
void Passenger::setWaiting(bool w){
waiting = w;
}
bool Passenger::isLate(){
return late;
}
bool Passenger::isWaiting(){
return waiting;
}
bool Passenger::mustTransfer(){
return transfer;
}
string Passenger::getNextStation(){
return path[destPointer];
}
void Passenger::popStation(){
destPointer++;
}
bool Passenger::onSameLine(string entry, string dest){
bool result = true;
if(entry != "b3" || dest != "b3"){ //if either begins or ends at B3, we know its on the same line
string redLine[6] = {"a1", "a2", "a3", "a4", "b4", "b5"};
string blueLine[3] = {"b1", "b2", "a5"};
for(int n = 0; n < 6; n++){
if(result){ //prevents search from continuing if answer found
for(int j = 0; j < 3; j++){ //For each combo of red line and blue line
if((redLine[n] == entry && blueLine[j] == dest) || //If the entry is red and the dest is blue or vice versa
(redLine[n] == dest && blueLine[j] == entry))
result = false; //answer is that they're not on the same line
}
}
}
}
return result;
}
#endif