Back to Index

#include <iostream.h>

#include <conio.h>

#include <fstream.h>

#include <stdlib.h>

#include <dos.h> // for "delay"

#include <ctype.h> // for "toupper"

#include <stdio.h> // for "getchar"

#define TRUE 1

#define FALSE 0

const int MAXPHOTOCELLNUMBER = 16;

const int MAXTURNOUTS = 6;

const int CLOCKWISE = 1;

const int COUNTERCLOCKWISE = 0;

const int BATCH = 1;

const int INTERACTIVE = 0;

const int MAXTRAINS = 10;


char turnouts[MAXTURNOUTS];

char tempturnouts[MAXTURNOUTS];

int trackmanager[MAXPHOTOCELLNUMBER];

int trackchange[MAXPHOTOCELLNUMBER];

int tomanager[MAXTURNOUTS];

int tochange[MAXTURNOUTS];


class Train{

public:

Train();

int speed;

int maxspeed;

int directionaroundtrack;

char direction;

int phas;

int pnext;

int headlightbool;

int taillightbool;

int id;

int tohas;

char lastcommand[15];

int blockingpc;

int blockingto;


};

//********** Node definition - Used by the "List" class

class Node {

public:

Node(int, int, char);

int photocell;

int turnout;

int changedirection;

char switchdirection;


Node * link;

};

Node::Node(int pc = 0, int to = -1, char sd = 'n'){

//*************************************************************

// Constructor - initialize the node

//*************************************************************

photocell = pc;

turnout = to;

switchdirection = sd;

}


//********** List class

class List {

public:

List(); // Create the list

void Add(int pc, int to, char sd);

void FindNext(int&, int&);

int FindCount();


//void Delete(string keyval);

void Print();

void Load();

void Save();

void clear();

private:

Node *top; // pointer to top of the list.

}; // List





Train::Train(){


direction = 'f';

directionaroundtrack = COUNTERCLOCKWISE;

phas = 12;

pnext = 6;

tohas = -1;

id = -1;

blockingto = -1;

blockingpc = -1;


}




List::List() {

//************************************************

// Create a new list

//************************************************

top = new Node(-1,-1,'s');

if (top==NULL){

cout << "Out of Memory... Program will close down";

getch();

exit(123);

}

top->link = top; // circle header list



} // List


//page

void List::Add (int pc, int to, char sd){

//*******************************************************************

// Creates a new node on the list from data in

// "keyval" and "commentval".

//*******************************************************************

Node *x; // points to new node


x = new Node(pc, to ,sd);

if (x==NULL){

cout << "Out of memory... Program will shut down";

getch();

exit(123);

}

x-> link = top->link;

top-> link = x;

} // Add


/*void List::Delete(string keyval) {

//*******************************************************************

// Deletes the node with "keyval" from this list.

//*******************************************************************

Node *prev, *p; // used for tag along

prev=top;

p=top-> link;

while (p!=top){

if (p->key == keyval){

prev-> link =p -> link;

delete p;

cout << keyval << " was deleted";

return;

}

prev=p;

p=p->link;

}

cout << keyval << " was not found in list";

getch();

} // Delete

*/


//page

void List::Print() {

//***********************************************************************

// Prints (shows) the contents of the list onto the screen.

//***********************************************************************

Node *p;

int nlines; // line counter

int items; // counts number of items in list

char opt;

// clrscr();

cout << " L I S T D A T A\n\n";

p = top->link;

nlines = 2;

items = 0;

while (p != top) {

// List the next item

nlines++; items++;

cout << p->photocell << " " << p->turnout << " " << p->changedirection

<< " " << p->switchdirection << "\n";

// Check if screen is full

if (nlines % 22 == 0) {

cout << "\nMore? "; opt = getch();

opt = toupper(opt);

if (opt == 'N') return;

}

// Advance to next item in the list

p = p->link;

} //while

cout << "\nThere are " << items << " items in the list.";

cout << " Press <cr> to continue... ";

getch();

cout << endl;

} //Print




int List::FindCount() {


Node *p;

int items = 0; // counts number of items in list


p = top->link;



while (p != top) {

// List the next item

items++;

p = p->link;

} //while

return items;



} //findcount



int FindCountList(List list){

return list.FindCount();

}

/*

//page

void AddTo(List &list){

//************************************************************************

// Requests data from user and adds this data to the list.

// Continues until an "empty" key field is input.

//************************************************************************

string keyval, commentval;

// clrscr();

do {

cout << "\nEnter KEY value (return to quit) "; get_line(cin, keyval);

if (keyval != "") {

cout << "Enter COMMENT field "; get_line(cin, commentval);

// Add to the list

list.Add(keyval, commentval);

} // if

} while (keyval != "");

} //Add

*/

/*


//page

void DeleteFrom(List &list){

//************************************************************************

// Deletes the node specified by the user. The key field of the

// node is input from the user.

//************************************************************************

string keyval, commentval;

clrscr();

do {

cout << "\nEnter KEY value to delete (return to quit) ";

get_line(cin, keyval);

if (keyval != "") {

// delete from the list

list.Delete(keyval);

} // if

} while (keyval != "");

} //Delete


*/

/*

//page

void Load(List &list) {

//***********************************************************************

// Adds to the existing list by loading data from a file and adding

// this data to the list.

//***********************************************************************

ifstream df;

string fname;

string line1, line2;

char tempname[80];

int done;

char ans;

//********** Obtain the input data file

do {

done = 1;

cout << "\nEnter name of file to load "; getline(cin, fname);

//--- Insure file exists

cp_cstring(tempname, fname, 80);

df.open(tempname, ios::in);

if (!df) {

done = 0;

cout << "\n" << fname << " does not exist. Try again (y/n)? ";

ans = getchar();

ans = toupper(ans);

if (ans == 'N') {

cout << "\nLoad not performed.\n";

return;

}; // if

}; //if

} while (!done);

getline(df,line1);

if (df.eof()){

cerr << "File is empty...";

getch();

df.close();

return;

}

getline(df,line2);

if (df.eof()){

cerr << "comment value is blank";

getch();

df.close();

return;

}

while (!df.eof()){

list.Add(line1,line2);

getline(df,line1);

if (df.eof())

break;

getline(df,line2);

}// end while

cout << "File has been loaded onto list... Press <Enter>";

getch();

df.close();

} //Load

*/


//int fexists(string filename){

/************************************************************************

returns true if the file already exists

*************************************************************************/

/* ifstream df;

char temp[80];

cp_cstring(temp,filename,80);

df.open(temp, ios::in);

if (df) {df.close(); return 1;}

else {df.close(); return 0;}

}

*/

//page

/*

void List::Save() {

//***********************************************************************

// Saves the current list unto a file. The file name is requested

// from the user.

//***********************************************************************

Node *p;

ofstream fout;

char fname[80]; // temp for filename

string filename;

char ans;

clrscr();

do {

cout << "Enter the filename to save to: ";

get_line(cin, filename);

if (!fexists(filename)) break;

cout << filename << " already exists. Overwrite? ";

cin >> ans;

if (ans=='Y' || ans=='y') break;

readln();

}

while (1);


cp_cstring (fname,filename,80);

fout.open(fname);

p = top->link;

while (p != top) {

// List the next item

fout << p->key << endl << p->comment << "\n";

p = p->link;

} //while

fout << endl;

fout.close();

cout << "Save done... Press <Enter>";

getch();

} //Save

*/

List CW[MAXPHOTOCELLNUMBER];

List CC[MAXPHOTOCELLNUMBER];

Train TrainList[MAXTRAINS];



void List::clear() {

/**************************************************************************

clears all members of the current list

***************************************************************************/

Node *p,*prev; // for tag along

prev=top;

p = top->link;

top-> link = top;

while (p != top) {

// Advance to next item in the list

prev=p;

p = p->link;

delete prev;


} //while

cout << "List has been cleared... Press <Enter>" << endl;

getch();

}// end clear




void toggledir(int & dir){

if (dir == CLOCKWISE)

dir = COUNTERCLOCKWISE;

else

dir = CLOCKWISE;



}

void toggleto(int to){

if (tomanager[to] != 0){

cout << "Cannot toggle turnout "<< to << " because it is under os control" << endl;

return;

}


if (turnouts[to] == 's'){

turnouts[to] = 'c';

tempturnouts[to] = 'c';

}

else

{

turnouts[to] = 's';

tempturnouts[to] = 's';

}



}



Train * FindTrain(int id1){

for (int i = 0; i< MAXTRAINS; i++){

if (TrainList[i].id == id1)

return &TrainList[i];



}

return NULL;


}



void toggletempto(int to){


if (tempturnouts[to] == 's'){

tempturnouts[to] = 'c';

}

else

{

tempturnouts[to] = 's';

}



}


void AddNewTrain(int id1, int & next){

if (id1 > 0 && FindTrain(id1) == NULL){




if (trackmanager[12] == 0 && trackmanager[6] == 0){

Train T;

T.id = id1;

TrainList[next] = T;

next++;

trackmanager[12] = id1;

trackmanager[6] = id1;


}

else

cout << "Cannot Add Train right now Train blocking " << endl;

}

else{

cerr << "Error invalid id number--must be positive and unique" << endl;

return;

}


}




void List::FindNext(int & nextphotocell, int & nextto){

Node * p;

p = top->link;


if (p->turnout == -1){

nextphotocell = p->photocell;

nextto = p->turnout;

}


else

{

if (p->switchdirection == tempturnouts[p->turnout]){

nextphotocell = p->photocell;

nextto = p->turnout;

}

else

{

if (p->link == top){


nextphotocell = -1; //p->photocell;

nextto = p->turnout;



}

else{

p = p->link;

if (p->switchdirection == tempturnouts[p->turnout]){

nextphotocell = p->photocell;

nextto = p->turnout;

}

else{

nextphotocell = -1;

nextto = -1;

}



}


}


}


}





void GetNext(Train *thistrain, int read, int & pc, int & to){

if (thistrain->directionaroundtrack == CLOCKWISE)

CW[read].FindNext(pc, to);

else

CC[read].FindNext(pc, to);

}


void ToggleMode(int& mode){

if (mode == BATCH){

mode = INTERACTIVE;

cout << "mode changed to interactive" << endl;

}

else{

mode = BATCH;

cout << "mode changed to batch " << endl;

}

}


void PrintTurnoutStatus(){

for (int i= 0 ; i< MAXTURNOUTS;i++)

cout << "turnout " << i << " is " << turnouts[i] << endl;

}


int CheckResourceAvail(int pc, int to){


if (trackmanager[pc] == 0){

if (to != -1){

if (tomanager[to] == 0){

return TRUE;

}

else{

return FALSE;

}

}

else {

return TRUE;

}

}

else {

return FALSE;

}

}


void UpdateResources(Train * T, int pc, int to){


trackmanager[T->phas] = 0;

tomanager[T->tohas] = 0;

T->phas = T->pnext;

T->pnext = pc;

T->tohas = to;

trackmanager[T->phas] = T->id;

trackmanager[T->pnext] = T->id;

if (to != -1){

tomanager[to] = T->id;

}



}

void PrintResourceTables(){

cout << "TrackMananger" << endl;

for (int j= 0; j < MAXPHOTOCELLNUMBER; j++){

cout << "photocell " << j << " is: " << trackmanager[j] << endl;

}

cout << "PressKey" << endl;

getch();

cout << "TO Manager" << endl;


for (j = 0; j< MAXTURNOUTS; j++){

cout << "turnout " << j << " is: " << tomanager[j] << endl;

}

cout << "PressKey" << endl;

getch();


}


void PrintTrackGraphs(){


for (int i = 0; i<MAXPHOTOCELLNUMBER; i++){

CW[i].Print();

CC[i].Print();

}

}


void SetUpToTables(){



turnouts[0] = 's';

turnouts[1] = 's';

turnouts[2] = 's';

turnouts[3] = 'c';

turnouts[4] = 'c';

turnouts[5] = 'c';


tempturnouts[0] = 's';

tempturnouts[1] = 's';

tempturnouts[2] = 's';

tempturnouts[3] = 'c';

tempturnouts[4] = 'c';

tempturnouts[5] = 'c';


}

void SetUpToAllocationTables(){

for (int j = 0; j<MAXPHOTOCELLNUMBER; j++)

trackmanager[j] = 0;

for (j = 0; j< MAXTURNOUTS; j++)

tomanager[j] = 0;

for (j = 0; j< MAXPHOTOCELLNUMBER; j++)

trackchange[j] = 0;

for (j = 0; j< MAXTURNOUTS; j++)

tochange[j] = 0;


}


void SetUpTrackGraphs(){

CW[0].Add(2,1,'s');

CW[1].Add(2,1,'c');

CW[2].Add(7,-1,'n');

CW[3].Add(1,0,'s');

CW[4].Add(5,-1,'n');

CW[5].Add(6,-1,'n');

CW[6].Add(12,-1,'n');

CW[7].Add(15,2,'s');

CW[8].Add(0,-1,'n');

CW[9].Add(3,-1,'n');

// CW[10].Add(-1,-1,'n');

CW[11].Add(6,-1,'n');

CW[12].Add(15,2,'c');

CW[13].Add(8,4,'s');

CW[13].Add(9,4,'c');

CW[14].Add(11,-1,'n');

CW[15].Add(13,3,'s');

CW[15].Add(14,3,'c');


CC[0].Add(8,-1,'n');

CC[1].Add(3,0,'s');

CC[2].Add(1,1,'c');

CC[2].Add(0,1,'s');

CC[3].Add(9,-1,'n');

CC[4].Add(6,-1,'n');

CC[5].Add(4,-1,'n');

CC[6].Add(5,-1,'n');

CC[7].Add(2,-1,'s');

CC[8].Add(13,4,'s');

CC[9].Add(13,4,'c');

// CC[10].Add(-1,-1,-1,'n');

CC[11].Add(14,-1,'n');

CC[12].Add(6,-1,'n');

CC[13].Add(15,3,'s');

CC[14].Add(15,3,'c');

CC[15].Add(7,2,'s');

CC[15].Add(12,2,'c');

}

void PrintMenu(){

cout << endl;

cout << "-1: to exit program" << endl;

cout << "0-15: to signal that turnout has been covered" << endl;

cout << "16: to toggle a turnout" << endl;

cout << "17: to toggle the direction of a train" << endl;

cout << "18: to add a new train to the course" << endl;

cout << "19: to toggle the mode between BATCH and INTERACTIVE" << endl;

cout << "20: to print the turnout status" << endl;

cout << "21: for the menu" << endl;

}


void swap(int & x, int & y){

int temp = x;

x = y;

y = temp;

}



//page

void main() {




int dir = CLOCKWISE;

int pc;

int to;

int next = 0;

int read;

int thistrainid;

int resgood;

int good = TRUE;

int mode = INTERACTIVE;

int id;


SetUpToTables();

SetUpToAllocationTables();

SetUpTrackGraphs();

Train * thistrain;


cout << "Welcome to Train OS Version 0.1" << endl;

cout << "Enter Command Number 21 for menu" << endl;

cout << "Please enter id for the initial train on the track: ";

cin >> id;

AddNewTrain(id, next);


cout << "Enter command number (21 for menu): " ;

cin >> read;

while (read != -1){


if (read == 6){


thistrainid = trackmanager[6];

thistrain = FindTrain(thistrainid);

if (thistrain == NULL){

cerr << "Error in operating system Train Was not found";

getch();

exit(123);

}

if (thistrain->phas == 11){

to = -1;

pc = 5;

}

else if (thistrain->phas == 12 ){

to = -1;

pc = 4;

}

else if (thistrain->phas == 5 ){

to = -1;

pc = 11;

}

else if (thistrain->phas == 4 ){

to = -1;

pc = 12;

}


toggledir(thistrain->directionaroundtrack);



}


else if (read == 16){

cout << "Which turnout: " ;

cin >> to;

toggleto(to);

cout << "turnout " << to << " is " << turnouts[to] << endl;

if (tochange[to] != 0){



cout << "system is checking to see if any trains can be woken up" << endl;

id = tochange[to];

thistrain = FindTrain(id);

GetNext(thistrain, thistrain->pnext, pc, to);

cout << "Next PC: " << pc << " Next TO: " << to << endl;

goto here;




}

cout << "Enter command number (21 for menu): " ;

cin >> read;

continue;

}

else if (read == 17){

cout << "Which train id to switch direction: " << endl;

cin >> id;

thistrain = FindTrain(id);

if (thistrain == NULL){

cerr << "Error in operating system Train Was not found";

getch();

exit(124);

}

toggledir(thistrain->directionaroundtrack);

swap(thistrain->phas, thistrain->pnext);

cout << "direction switched to " << thistrain->directionaroundtrack << endl;

cout << "Enter command number (21 for menu): " ;

cin >> read;

continue;

}

else if (read == 18){


cout << "New Train id: " ;

cin >> id;

AddNewTrain(id, next);

cout << "Enter command number (21 for menu): " ;

cin >> read;

continue;

}

else if (read == 19){

ToggleMode(mode);

cout << "Enter command number (21 for menu): " ;

cin >> read;

continue;

}

else if (read == 20){

PrintTurnoutStatus();

cout << "Enter command number (21 for menu): " ;

cin >> read;

continue;

}

else if (read == 21){

PrintMenu();

cout << "Enter command number (21 for menu): " ;

cin >> read;

continue;

}

else{


thistrainid = trackmanager[read];

thistrain = FindTrain(thistrainid);

if (thistrain == NULL){

cerr << "Error in operating system Train Was not found" << endl;

getch();

exit(125);

}

GetNext(thistrain, read, pc, to);

}



cout << "Train " << thistrain->id << " Next PC: " << pc << " Next to: " << to << endl;


here:


if (pc == -1 && mode == BATCH){

toggletempto(to);

GetNext(thistrain, read, pc, to);

cout << "Next PC after adjustment: " << pc << " Next to: " << to << endl;

resgood = CheckResourceAvail(pc, to);

if (resgood){

cout << "System found that toggling turnout in batch mode is safe...toggling to " << to;

toggleto(to);

if (tochange[to] != 0){

cout << "Checking if system can wake up any trains" << endl;

}

UpdateResources(thistrain, pc, to);


}

else{

cout << "Resources Not Available" << endl;

PrintResourceTables();

}



}

else if (pc == -1 && mode == INTERACTIVE){

cout << "stop the train due to turnout in position that makes" << endl

<< "further travel impossible. Please toggle turnout " << to << endl;

tochange[to] = thistrain->id;

}


else if (pc != -1){

resgood = CheckResourceAvail(pc, to);

if (resgood){

UpdateResources(thistrain, pc, to);

}

else{

cout << "Resources Not Available" << endl;

PrintResourceTables();

}

}



cout << "Would you like to see the resource tables" << endl;

if (toupper(getch()) == 'Y'){

PrintResourceTables();

}

cout << "Enter command number (21 for menu): " ;

cin >> read;




}


}// main