Please note that successful completion of the public tests is required for the successful submission of this sheet. The Praktomat will reject your submission if one of the following rules is violated. A rejected submission is automatically awarded zero points. Allow adequate time for your first delivery attempt.
– Make sure that the program code compiles without errors.
– Do not use elements of the Java libraries, except for elements of the packages java.lang, java.util, java.util.regex and java.util.function.
– Be careful not to create too long lines, methods and files. You must be present at adhere to a maximum line width of 120 characters for your solutions.
– Comply with all whitespace rules.
– Comply with all rules for variable, method and packet naming.
– Choose appropriate visibility for your classes, methods and attributes.
– Do not use the default package.
– System.exit() and Runtime.exit() must not be used.
– Follow the rules for Javadoc documentation.
– Also stop all other Checkstyle rules.
These processing instructions are relevant for the evaluation of your submission, but the Praktomat will not reject your submission if one of the following rules is violated.
– Note that your submissions are evaluated in terms of both object-oriented modeling and functionality.Follow the instructions for modeling in the ILIAS Wiki.
– Program code must be written in English.
– Comment your code appropriately: as much as necessary, as little as possible.
– The comments should be written uniformly in English or German.
– Choose meaningful names for all your identifiers.
Only independently developed solutions are accepted.Submitting solutions from other people, even if only partial solutions from third parties, from books, the Internet or other sources such as the solution proposals of the training company, is an attempt at deception and leads to the rating “failed”.Expressly excluded from this are source code snippets from the lecture slides.All aids used must be fully and accurately specified and anything taken from work carried out by others, either unchanged or with modifications, must be clearly marked. For further details, please refer to the declaration of consent (disclaimer).
For this task, download the Terminal class and make sure you place it in the edu.kit.informatik package.The Terminal.readLine() method reads user input from the console and replaces System.in.The method Terminal.printLine() writes output to the console and replaces System.out.Use the Terminal class for any console input or console output.Never use System.in or System.out.Error messages are only output via the terminal class and must start with Error,␣ for technical reasons.Among other things, this can be done conveniently using the Terminal.printError method. Never upload the terminal class together with your submission.
Model railway simulation (20 points)
In this final task you will develop a model railway simulator. The final task consists of two interdependent subtasks.The first sub-task is the modelling of the route network and the rolling stock (wagons, locomotives, multiple units).The second subtask is the driving simulation.
The track network is represented by tracks.Simplified, tracks are represented by two or three points in two-dimensional space.A point is a tuple of two 32-bit integers and represents a coordinate.All tracks have a unique identifier starting at 1, which is only unique for tracks (see example sequence).The identifier is a 32-bit integer and is assigned in ascending order.A line consists of several tracks.There are two types of tracks: normal tracks and track switches (turnouts).Normal tracks are described by two points in space, the start and end points.The coordinates can lie anywhere in space, with the restriction that track parts are always horizontal or vertical. Only one change in the x-direction is horizontal and one change only in the y-direction is vertical.Furthermore, with the exception of the first track, a start or end point must always be adjacent to a start or end point of an existing track.Only one other track (normal track or track switch) can be connected at any one point on a track. Each track has a length1, which depends on its start and end coordinates.For simplification, the length is always shown as rounded positiveInteger2 specified. Track switches serve to split a line into two sections.They are described by three coordinates, a starting point and two end points.Track switches have the additional property of saving the current switch position.The current track switch setting determines the passability of a track switch.The length of a track switch depends on its current position.Figure 0.1 illustrates a possible route network.The black dots show the respective start and end points for track material.Track switches are marked by the label “Switch X”, where X is a placeholder for a positive integer. The current track switch position is indicated by the black line.The red line indicates the alternative selection option. A train can only run on the black line. This is also the route network which is used in the example sequence.
Figure 0.1: Example of a simple line with track switches and tracks
(gleis = track and weiche = track witsches)
Tracks cannot cross each other, i.e. if tracks are seen as straight lines, they must not intersect.Figure 0.2 shows a prohibited track crossing.It is also not allowed to connect tracks outside of start and end points.In this task this would also be a crossing of tracks.In addition, a start or end point can only have exactly one other track.
Figure 0.2: Not allowed crossing of tracks
The rolling stock generally describes all objects running on rails, e.g. a railway wagon.For the sake of simplicity, we assume that there are only the following types:Cars, locomotives, multiple units.Common to all types is that they have a name and a length, e.g. a locomotive could have the name Emma and length 1.
(a) Passenger carriages. (b)Goods carriages (c) Special carriages
Figure 0.3: Graphical representation of carriages
To simplify matters, only passenger, freight and special wagons are available as wagon types.The passenger car is used to transport people, the freight car to transport goods and special cars are e.g. a crane car or a fire engine. The different types of cars are represented graphically as in Figure 0.3.All wagons have a unique 32-bit integer ascending identifier starting at 1, which is only unique for wagons (see example sequence).Each car has at least one, but no more than two couplings.These are always located at the beginning and end of a car.There may also be a maximum of one coupling on one side (start, end).These couplings allow the composition of rolling stock (see composition of rolling stock)
There are three different types of locomotives: electric locomotives, diesel locomotives and steam locomotives. All locomotives have a unique ID. This ID is made up of the class and the name of the locomotive. These are separated by a hyphen, for example, the class “103” and the name “118” result in the ID “103-118”. Both the name and the series can contain letters and numbers.Whereby the series must not be the character string “W”.Each locomotive has at least one, but no more than two couplers.These are always located at the beginning and end of a locomotive.There may also be a maximum of one coupling on one side (start, end).These couplings allow the composition of rolling stock (see Composition of rolling stock).Figure 0.4 shows the graphical representation of locomotives.
All multiple units have one series.The multiple unit ID is composed according to the same rules as for locomotives.For this reason, locomotives and multiple units share the same ID space.A multiple unit has a special type of coupling and can therefore only be composed with the same series of multiple units (see Composition of Rolling Stock). otherwise the same rules apply as for locomotives.Figure 0.5 shows the graphical representation of multiple units
(a) Steam locomotive. (b) Electric locomotive. (c) Diesel locomotive
Figure 0.4: Graphical representation of locomotives
Figure 0.5: Graphical representation of multiple unit trains
Composition of rolling stock:
Rolling stock can be composed into a train. The following restrictions must be observed when composing:
– At the beginning or end of a valid train there must always be at least one locomotive/train set.-
During composition, it must always be considered whether the rolling stock has a suitable coupling at the desired composition point.
– The rolling stock that is being composed is not yet used in another train.
All trains have a unique ID starting at 1, which is a 32-bit integer and is assigned in ascending order.This ID is only unique for trains (see example sequence).A move can also be output graphically on the console.The individual representations of the rolling stock are concatenated according to their position in the train.The individual representations are separated by a space.Figure 0.6 shows an output for a train with one steam locomotive and two passenger cars.Figure 0.7 shows another train example with an electric locomotive and a passenger car.
Figure 0.6: Example representation of a train with steam locomotive
Figure 0.7: Example representation of a train with electric locomotive
In order to simulate the operation of a model railway, a train must first be placed on a track. The whole train is always placed on the track. A direction vector must be specified when placing the train on the track. This vector indicates the initial direction of the train. The direction vector corresponds to the direction vector of the track or is exactly the opposite vector. When rerailing, it must be noted that the used tracks are still free, i.e. no other train is standing there and there is a track at all.Of course, the length of a train also plays a role.Trains can only be set up on lines with track switches when the track switch position has been set.Furthermore, trains can only be set on the section that is the current track switch position.If track points on which a train is already standing are switched, the train on top of them derails.When trains are on the track, they can only move on the track.They initially move in the direction of the direction vector and follow the course of the rail.Before a train can move, a track switch position must be set for all track switches.As usual with small model railroad layouts, all trains that are on the layout run here.The speed is the same for all trains.In general, the train will move by n x units for horizontal tracks and by n y units for vertical tracks.The simulation here is calculated in steps. For this purpose, n ∈ Z16-bit is transferred at each step.To illustrate this, an example is shown in Figure 0.8, where the points are indicated by a tuple of integers.The head of a train (red dot) stands at (2,0) on the track from (1,0) to (4,0) and moves towards point (4,0).At point (4,0) a track switch with the end points (4,2) and (6,0) is connected.The current track switch position is set to (6.0).After a step with n = 1, the traction head (blue point) would be at (3.0) (see Figure 0.8a).After a further step with n = 2, the traction head (yellow dot) would be at (5,0). In the second example (see Figure 0.8b), the head of the train (red dot) stands at (0,0) on the track from (0,3) to (0,-1) and moves towards point (0,3). After a step with n = 2 the train head (blue point) would be at (0.2). In a further step with n = 2 the train head would (yellow dot) to (1,3).
(a) Driving simulation with switch. (b) Trip simulation with curve
Figure 0.8: Direction of movement of trains
During the simulation, collisions of different trains may occur.A collision occurs when two trains are on the same track or position.During the check, the start/end points always belong to the track on which the rest of the train is standing.For example track 1 (G1) from (10,1) to (20,1) and track 2 (G2) from (20,1) to (30,1). If a train with length 4 is now at (20,1) and is moving in direction (30,1), then G1 would be occupied and G2 would still be free.If there is a collision, the trains involved derail.Trains can go beyond the track, i.e. if the track ends and there is no siding, e.g. as in Figure 0.1 (track 7) the train derails.When trains derail, they take you off the track.However, they remain in the train database.They can then be put back on again.
Interactive user interface:
After startup, your program accepts various types of commands via the console using Terminal.readLine(), which are specified in more detail below.After processing a command, your program waits for further commands until the program is terminated at some point by the exit command.Make sure that executing the following commands does not violate the previously defined basics and conditions, and always issue a meaningful error message in these cases.If an input does not correspond to the specified format, an error message is always issued.After that the program should wait for the next input.For error messages, you are free to choose the text, but it should make sense.However, every error message must begin with Error, and may not contain any line breaks.Because we perform automatic tests of your interactive user interface, the output must be exactly as specified.
In particular, lower and upper case letters as well as spaces and line breaks should match exactly. Also, do not output any additional information. Start submitting early to test your solution and use the forum to clarify any ambiguities.
Please note that in the description of the input and output formats, the words between angle brackets ( < and > ) stand for placeholders, which are replaced by values in the actual input and output. These actual values do not contain brackets for the input and output. Please also compare the respective example sequences.
Please note that in the following example procedures, the input lines are introduced with the > character followed by a space. These two characters are explicitly not part of the entered command, but are only used to distinguish between input and output lines.
If lists are to be output, they are always output line by line, unless a command explicitly specifies otherwise. Unique identifiers and IDs that consist of exactly one 32-bit integer are always assigned in ascending order starting with 1. I.e. the first ID would be 1 and the second 2. In addition, the next free ID is always selected. For example, if the IDs 1,3,4,5 are assigned, the next ID is 2.
A point is a tuple of two 32-bit integers and describes a coordinate in 2D space. The tuple is enclosed in “round” brackets. The two integers are separated by a comma. The first 32-bit integer enters the x coordinate and the second 32-bit integer enters the y coordinate.
The add track command
Adds a normal track.A start point <startpoint> and an end point<endpoint> selected.If the track is not the first track, one of the two points must always be on a start or end point of another track.Tracks can only be horizontal or vertical.
If successful, the unique ID of the track is output. In the event of an error (e.g. no connection to a previous track), a meaningful error message is output, beginning with Error.
The add switch command
Adds a track switch.One starting point and two end points are selected.The individual track switch sections must always be horizontal or vertical.If the track is not the first track, one of the three points must always be on a start or end point of another track.
add switch <startpoint> -> <endpoint1>,<endpoint2>
If successful, the unique ID of the track is output.In the event of an error (e.g., no connection to a previous track) a meaningful error message is output, beginning with Error.
The delete track command
Deletes any track (normal track, track switch).The track to be deleted is selected via the<trackID> selected.When deleting, it must be checked that no two independent tracks exist after removal, i.e. that all tracks are connected and that there are no track sections that are not connected.In addition, no train may be on the track.
delete track <trackID>Output format If successful, OK is displayed.
In the event of an error (e.g., <trackID> not found), a meaningful error message is output, beginning with Error.
The list tracks command
Outputs a list of all tracks (track switches and normal tracks) line by line. The output contains the type, the unique track ID <trackID>, the starting point, the end point and the length.For track switches, the length is only output if the track switch position has already been set.In this case the length, then the length of the vector from the starting point to the matching end point of the current track switch position.The list is sorted by track ID in ascending order.
For normal tracks: t <trackID> <startpoint> -> <endpoint> <length>
For track switches: s <trackID> <startpoint> -> <endpoint1>,<endpoint2> <length>
s or t describe the track type. <trackID> is a 32-bit integer ID.
If a track does not exist, return “No track exists”.
The set switch command
For a turnout with the <trackID> selects the turnout position that connects the starting point of the turnout with the selected end point (<point>).
set switch <trackID> position <point>
If successful, OK is displayed.In the event of an error (e.g. point not present or track ID not found) a meaningful error message is output, beginning with Error.
The create engine command
Create a locomotive. <engineType> describes the type of locomotive ( electrical ,steam , diesel ). The series is set using the placeholder <class>.<name> is the name of the locomotive. specifies the length of a locomotive as a 32-bit integer.<couplingFront> and are truth values that indicate whether a couplingis present at the front and or rear.The truth value can be set to true or false.Here true indicates that a coupling is present.A locomotive can only be added if no locomotive or multiple unit with the same ID exists yet.
create engine <engineType> <class> <name> <length> <couplingFront> <couplingBack>
If successful, the unique ID of the locomotive is output. In the event of an error (e.g., wrong input format or ID already exists), a meaningful error message is output, starting withError, output.
The list engines command
Outputs a list of all locomotives line by line. The list is lexicographically sorted according to the locomotive ID.
<trainID> <engineType> <class> <name> <length> <couplingFront> <couplingBack>
<trainID> is the ID of the train to which the locomotive belongs.If none is set yet, the output is displayed.<engineType> identifies the type of the locomotive.Where e stands forelectric s for steam and d for diesel.All other placeholders have the same meaning as in the create engine command.If no locomotive exists yet, “No engine exists” is displayed.
The create coach command
Create a wagon. <coachType> describes the type of the car. There are the following types:
Passenger, freight, special.
create coach <coachType> <length> <couplingFront> <couplingBack>
If successful, the unique car ID is output. In case of an error (e.g., wrong input format), a meaningful error message is output, starting with Error.
The list coaches command
Outputs a list of all cars line by line. The list is sorted in ascending order by car ID.
<coachID> <trainID> <coachType> <length> <couplingFront> <couplingBack>
<coachID> is the ID of the wagon. <trainID>is the ID of the train to which the wagon belongs. If none is set yet, none is output. <coachType> identifies the type of the car. Where p stands for passenger cars, f for freight cars and s for special cars.All other placeholders have the same meaning as in the list engine command.If no coach exists yet, No coach exists is displayed.
The create train-set command
Create a multiple unit. The other parameters and error cases are described in the create engine commanddescribed
create train-set <class> <name> <length> <couplingFront> <couplingBack>
If successful, OK is displayed.In the event of an error (e.g., wrong input format), a meaningful error message is output, beginning with Error.
The list train-sets command
Outputs a list of all multiple units line by line.The list is lexicographically based on the multiple unitID ordered.
<trainID> <class> <name> <length> <couplingFront> <couplingBack>
All placeholders have the same meaning as the command. If no multiple unit exists yet, No train-set exists is output.
The delete rolling stock command
Deletes a rolling stock.The rolling stock is identified by its unique ID.For a car, the ID is presented with a W.Rolling stock can only be unloaded if it is not used on any train.
delete rolling stock <id>
If successful, OK is displayed. In case of an error (e.g., wrong input format), a meaningful error message is output, beginning with Error.
The add train command
Adds rolling stock to the train with the 32-bit integer <trainID>.If the train with the ID does not yet exist, it will be created automatically.The <rollingStockID> is either the ID of a train, locomotive or wagon.For wagons, a W is placed in front of the ID.The train must be valid with regard to the couplings, but not valid with regard to the locomotives.The rolling stock is added in sequence, i.e. the first rolling stock added to a train is the head of the train (front) and the last rolling stock added is the tail of the train.
add train <trainID> <rollingStockID>
If successful, <type> <stockID> added to <trainID> is displayed. <type> is the type. The following values can be assumed electrical engine, steam engine, diesel engine, train-set, passenger coach, freight coach, special coach.<stockID> is the ID of the rolling stock, whereby for wagons a W is placed in front of it.<trainID> is the ID of the trainIn case of an error (e.g., incorrect clutch), a meaningful error message is issued, beginning with Error.
The delete train command
Deletes the move with the <ID> . If the train is on the line, it will also beTrack removed.
delete train <ID>
If successful, OK is displayed. In case of an error (e.g., wrong input format), a meaningful error message is output, beginning with Error.
The list trains command
Outputs a list of all moves line by line.The list is sorted in ascending order by train ID.
The <trainID> is the current ID of the train and Members is a list of the IDs of the rolling stock used.The individual IDs are separated by spaces.The ID of a wagon is preceded by a W to indicate that it is a wagon. e.g. 1 103-118 W1 for train 1 with locomotive 103-118 and wagon 1.
The show train command
The command prints the graphical representation of the train. trainID is the ID of the train.
show train <trainID>
If successful, the graphical representation is output for each rolling stock.In the event of an error (e.g. train not present), a meaningful error message is displayed beginning with Error,output.(see example procedure)
The put train command
Places a valid (see Rolling Stock Composition) train on a track at the position <point> . The initial direction of movement is determined by the integers4 <x>,<y> which serve as direction vectors.When rerailing, make sure that the train is valid and that there is no other train on the required tracks (note the length of the train) and that the direction vector corresponds to the direction of the track at the rerailing point (or to opposite).
train <trainID> at <point> in direction <x>,<y>
If successful, OK is displayed.In case of an error (e.g., wrong input format, or invalid move) a meaningful error message is displayed, beginning with Error.
The step command
Makes all trains run by <speed> units. is a 16 bit integer.Subsequentlythe position of all train heads ( ), which are standing on a track, is output line by line.This is done in ascending order of the train ID.In case of a collision during operation, the trains involved will be issued.For the description of the ride and the collision behaviour, see Driving Mode.Trains that are not affected by the collision continue to run normally.
Train <trainID> at <headPoint>Line by line output of moves.If there is no train on the track yet, OK is displayed.In case of a collision, Crash of train <trains> is output.Where <trains> is a list of train IDs separated by commas (sorted in ascending order).If there is a collision of several, this is output line by line.Note that the trains must not overlap, i.e. if train 1 has a collision with train 3 and train 3 has a collision with train 4 this would be considered a collision and the output would be Crash of train 1,3,4. If there are multiple independent collisions, the output is sorted by the smallest train ID of each collision. The same applies if there is a mixture of collisions and normal output. For example, train 11 and train 12 have an accident and train 9 and train 22 have one too. But move 10 and 8 do not, then the output would be without consideration of the position:
The exit command
The parameterless command allows to terminate the running program completely.Please note that methods like System.exit() or Runtime.exit() must not be used for this.
In case of success no output will take place.In the event of an error (e.g. an incorrectly specified input format), a meaningful error message is output, beginning with Error.