Homework 6, Train Cars are Stacking Up
For this program you will implement a simulation of a simple railroad switching yard.
Goals
- Implement a simple structure.
- Implement a stack using an array and a structure.
- Employ a stack to solve a simple problem.
- Implement an enumerated type.
- Combine many source code files to form a single executable.
- Test each component of your implementation.
Formal Description
You are working for a railroad company with a number of small switching yards. They have
hired you to implement a simulation of the flow of traffic in these yards.
A yard is configured as follows:
- There is a Main Line which allows trains to pass the yard. This is of no concern to your simulation.
- There is a Arrival/Departure West Spur where east bound cars are dropped off and west bound cars are picked up.
- There is a Arrival/Departure East Spur where west bound cars are dropped off and east bound cars are picked up.
- There is a Local Service Spur where cars for local delivery are placed are stored. Cars from local industry to be shipped out arrive here. You will place cars to be delivered to local industry on this spur.
- There is a Yard Spur which you can use for rearranging cars in the yard. At the beginning of every action, the yard spur should be empty.
- The Action Area is a place where your single switching engine is located. This engine can remove cars from any spur and place them in any other spur.
You should assume each spur can hold no more that 100 cars. If any spur ever exceeds this limit, the program should report the error message
ERROR spur capacity exceeded!
If there is an attempt to place more than the maximum number of cars of a spur, discard the car that would cause the spur to overflow.
In a similar manner, if an attempt is made to remove a car from an empty spur the program should report the error message
ERROR spur is empty, cannot remove a car!
If this error occurs, any function responsible for returning a car should return ERROR_CAR which is defined below.
Commands
Your simulation should respond to the following commands:
- exit exit the simulation
- arrive spur trainlist the newly arrived train is added to any cars currently on the given spur. These cars need to be added to the end of the cars on the spur furthest from the Action area.
- Assume that the local spur holds cars A-B-C.
LOCAL
C
B
A
- The command arrive local D-E-F is issued
- D-E-F are added to the local spur
LOCAL
F
E
D
C
B
A
This action will be the only one that sort of breaks the simulation. We assume that all tracks but the yard track lead to some other destination. To accomplish this we will need to
- Remove all of the cars from the spur where the new cars are arriving by placing them in the yard track.
- place the arriving cars in the yard track in the order they are listed.
- remove all cars from the yard track and place them in the given spur.
In the case of the example above the following action would occur
LOCAL YARD
C
B
A
Remove A from the Local spur and place it on the Yard spur.
LOCAL YARD
C A
B
Remove B from the Local spur and place it on the Yard spur.
LOCAL YARD
C A
B
Remove C from the Local spur and place it on the Yard spur.
LOCAL YARD
A
B
C
Remove D from the arriving train and place it on the Yard spur.
LOCAL YARD
A
B
C
D
Remove E from the arriving train and place it on the Yard spur.
Remove F from the arriving train and place it on the Yard spur.
LOCAL YARD
A
B
C
D
E
F
Remove F from the Yard spur and place in the the Local spur.
LOCAL YARD
F A
B
C
D
E
Remove E from the Yard spur and place in the the Local spur.
Remove D from the Yard spur and place in the the Local spur.
Remove C from the Yard spur and place in the the Local spur.
LOCAL YARD
F A
E B
D
C
Remove B from the Yard spur and place in the the Local spur.
Remove A from the Yard spur and place in the the Local spur.
LOCAL YARD
F
E
D
C
B
A
Cars will never arrive on the yard spur.
- depart spur
The cars on the given spur are removed.
Cars will never depart the yard spur.
- sort spur
Sort the cars on the given spur using only the given spur and the yard. Use the following algorithm
Remove all cars from the local spur and place them in the source spur.
While the source spur is not empty
remove first car on the source spur
put the car on the local spur
if the destination of the first car in the local spur is not local
while the destination of the car in the front of the yard spur is larger than the destination of the car in the local spur
remove the car from the yard spur and place it on the source spur
remove the car from the local spur and put it on the yard spur
remove all cars from the yard spur and place them in the source spur.
For the following example, assume that for car A-n n is the destination. Assume that this is station 0. The local spur contains A-1 B-3 and the west spur contains C-2 D-0 E-4.
Initial Configuration
LOCAL YARD
B-3
WEST A-1
E-4 D-0 C-2
Remove A from the Local spur and place it on the West spur.
Remove B from the Local spur and place it on the West spur.
WEST LOCAL YARD
E-4 D-0 C-2 A-1 B-3
Remove B from the West spur and place it on the Local spur.
(since the yard spur is empty)
Remove B from the Local spur and place it on the Yard spur.
LOCAL YARD
WEST B-3
E-4 D-0 C-2 A-1
Remove A from the West spur and place it on the Local spur.
LOCAL YARD
WEST A-1 B-3
E-4 D-0 C-2
(since the destination of A is less than the destination of B)
Remove A from the Local spur and place it on the Yard spur.
LOCAL YARD
B-3
WEST A-1
E-4 D-0 C-2
Remove C from the West spur and place it on the Local spur.
LOCAL YARD
C-2 B-3
WEST A-1
E-4 D-0
(since the destination of C is greater than the destination of A)
Remove A from the Yard spur and place it on the West spur.
LOCAL YARD
WEST C-2 B-3
E-4 D-0 A-1
(since the destination of C is less than the destination of B)
Remove C from the Local spur and place it on the Yard spur.
LOCAL YARD
B-3
WEST C-2
E-4 D-0 A-1
(A will now be moved to the yard spur via the local spur)
LOCAL YARD
B-3
C-2
WEST A-1
E-4 D-0
(D will be placed on the local spur, it will never be removed)
LOCAL YARD
D-0 B-3
C-2
WEST A-1
E-4
(E will be placed on the local spur)
LOCAL YARD
D-0 B-3
E-4 C-2
WEST A-1
(All of the cars in the yard will be removed and placed on the west spur
since all have destinations less than E)
LOCAL YARD
D-0
WEST E-4
A-1 C-2 B-3
(The process will continue until)
LOCAL YARD
D-0 E-4
B-3
C-2
WEST A-1
(remove all cars from the yard and place them in the west spur)
LOCAL YARD
WEST D-0
A-1 C-2 B-3 E-4
Only the East and West spurs will be sorted.
- move source spur destination spur
All cars from the source spur are moved to the destination spur.
For example if the east spur contains ABC and the west spur contains DEF the command move east west would produce the following
WEST EAST
FED ABC
Remove A from the East spur and place it on the West spur.
WEST EAST
FEDA BC
Remove B from the East spur and place it on the West spur.
Remove C from the East spur and place it on the West spur.
WEST EAST
FEDABC
- print spur
Prints all of the cars in the given spur. Your program should output the following
The XXX spur contains:
Name, Destination
Name, Destination
Each car should be indented with a tab. The cars should be printed from front to back. A blank line should be printed after the last car. For example if the west spur contains A-0 B-1 C-2 :
WEST EAST
CBA
The command print west should produce
The West spur contains:
A, 0
B, 1
C, 2
A trainlist consists of a comma separated list of train cars, listed from front to back. A train car consists of a car id, which is a unique string, a colon and a destination, which is a string. See below for a full list of destinations.
Assume all spurs are empty. The command arrive Local C:Oakland,B:Cleveland,A:Denver would produce the following
LOCAL YARD
C
B
WEST A EAST
General Operation
Your program should prompt the user for a file with the prompt
Enter the file name =>
There should be a space after the > in this prompt. Note, this prompt does not include the newline character. However, after you have read the file name, please print a newline character.
The first word in the file will be the station name. This will be a valid destination.
The program should then attempt to execute the commands in the file. You may assume all commands are valid.
The following is an example of a valid input file
Edinboro
arrive local A:Albion,B:Cambridge Springs
ArrIve wEsT C:Bradford,D:Edinboro,E:Erie
SORT wesT
Move west East
Depart East
Output
As commands are executed
- The program should print
Executing command
where command is the command as it appears in the input.
- The actions taken by the command in the form:
Remove XXX from the Xxxx spur and place it on the Xxxx spur.
- For Depart print
A train departs from the Xxxx spur.
- For Sort print
Sorting the Xxxx spur.
<commands to accomplish the sort>
- For Move print
Moving from the Xxxx spur to the Xxxx spur.
<commands to accomplish the move>
- For Arrive print
New train arriving on the Xxxx spur.
<commands to accomplish the arrival>
Note, this will include moving the current train to the yard. When adding a car to the spur print
Remove XXX from the arriving train and place it on the Yard spur.
- For Exit print
Thank you for using the Xxxx Switching Station
Where Xxxx is the name of the station.
A blank line should be printed after each command is executed.
Implementation
Please implement your program as follows:
- Implement a DestinationT as a strong enumerated type
- Place this definition/implementation in destination.[h,C/cpp]
- The domain is: Albion, Bradford, Cambridge Springs, Edinboro,Erie,UNKNOWN
- Please use these strings, make up whatever internal constants you wish.
- Please note, this list may be expanded.
- Please provide the following constants
- FIRST_DESTINATION, LAST_DESTINATION
- FIRST_DESTINATION should be the first destination on the line
- LAST_DESTINATION should be UNKNOWN
- Please provide the following functions
- DestinationT NextDestination(DestinationT dest);
- Should return the next destination in the domain
- Should return UNKNOWN when UNKNOWN is the input.
- DestinationT PrevDestination(DestinationT dest);
- Should return the previous destination in the range.
- Should return the first destination when the first destination is the input.
- std::string DestinationTToString(DestinationT dest);
- This should produce a string as listed in the domain.
- DestinationT StringToDestinationT(std::string name);
- This should match a destination string in any case.
- DestinationT RandomDestination(void);
- You should consider creating a program which tests this type.
- Implement a CarT as a structure
- Place this definition/implementation in car.[h,C/cpp]
- The domain consists of
- A string representing the name of the car.
- A destination, where the car is to be delivered.
- Please provide the following constants
- Please provide the following definitions for the stack type
- Define ItemT to be a CarT
- ITEM_OVERFLOW_ERROR to be a string to print when a spur is full
- NO_ITEM_ERROR to be a string to print when an attempt is made to move a car that does not exits.
- NO_ITEM to be ERROR_CAR
- Please provide the following functions
- std::string CarTToString(const CarT & c);
- Return a string containing
- The car name
- A comma
- A space
- The destination
- CarT StringToCarT(const std::string & car);
- Given a string containing name:destination construct a car
- bool IsSmaller(const CarT & a, const CarT & b);
- If the destination of a is "less than" the destination of b, return true, otherwise return false.
- std::string CarName(const CarT & c);
- Return the name of the car.
- DestinationT CarDestination(const CarT & c);
- Return the destination of the car.
- You should consider creating a program which tests this type.
- Implement a StackT as a structure
- Place this definition/implementation in stack.[h,C/cpp]
- The domain consists of
- Whatever you need to implement the stack
- Please provide the following functions. You must implement these functions as given, you may not add any functions to this list.
- void InitStack(StackT & s);
- void Push(StackT & s, ItemT i);
- Add an item to the stack if possible.
- Print an error message (ITEM_OVERFLOW_ERROR) if this would cause the stack to overflow.
- ItemT Pop(StackT & s);
- Remove the top item from the stack and remove it.
- Print an error message (NO_ITEM_ERROR) the stack is empty.
- Return NO_ITEM if the stack is empty.
- ItemT Top(const StackT & s);
- Return the top item on the stack.
- DO NOT remove the top item.
- Print an error message (NO_ITEM_ERROR) the stack is empty.
- Return NO_ITEM if the stack is empty.
- int Size(const StackT & s);
- Return the size of the stack.
- bool IsEmpty(const StackT & s);
- Return true if the stack is empty, false otherwise.
- bool IsFull(const StackT & s);
- Return true if the stack is full, false otherwise.
- You should consider creating a program which tests this type.
Required Test File
- I will be producing my own test driver.
- Please follow the naming convention.
- To assist you, make sure the program in BasicTests.C" can be built. I will replace this file with my own which has MUCH MORE EXTENSIVE tests.
- To assist you, I have provided a basic Makefile.
Discussion
Required Files
A tar file containing the all source code required to build both programs in this project. This file should also contain a Makefile capable of building the programs required for this project. It should not contain executable or object files.
Submission
Send the tar file to your instructor as an attachment to an email message by the due date.