(E) Traffic lights

Tavoite: I will learn more about dynamic memory management and the use of pointers.

Ohjeita: Retrieve the code template: templates/08/traffic/ -> student/08/traffic/.

Vehicles waiting in traffic lights can be described as a queue, where the first-come vehicle goes on first, and the new-comers stay after the last vehicle in the queue. Thus, a queue is a data structure that enables adding elements at the end and removing elements from the beginning. These operations are typically called enqueue and dequeue, respectively.

Since we are practicing dynamic memory management, your task is to implement the necessary class without using STL containers or the C++ array.

Necessary functionalities

Traffic lights in the program to be implemented work as follows. The class has an integer attribute cycle_ telling how many vehicles can at most pass the lights during the same green period. This parameter is passed as a parameter for the constructor, but it can be changed afterwards.

If the color of the traffic light is red, you can add new vehicles at the end of the queue. If the color is green, new vehicles will not stop to wait, instead they can go on directly. In other words, they will not be inserted in the queue at all.

You can remove vehicles from the queue only, if the color of the traffic light is green. If you try to remove vehicles on red light, nothing happens.

You can switch the color of the traffic light from red to green and vice versa. (There is no yellow light, since it would not cause any actions.) If the new color is green (the color was switched from red to green), the number of vehicles that can go on is at most cycle_. (If there is less vehicles than cycle_, then all of them can go on.) In addition, the register numbers of the passed vehicles will be printed. After these vehicles have gone on, the color of the traffic light will be switched back to red (spontaneously i.e. without any request from the user).

If the new color is red, the queue remains the same. In this case, only the situation of the traffic lights will be printed. Similarly, if the queue is empty at the first place, only the situation will be printed.

The situation of the traffic lights can be printed as follows. First, the color is printed, followed by a colon. After that the register numbers of the waiting vehicles are printed. If the queue is empty, information about it is printed.

The program as a whole

The class describing traffic lights has the public methods enqueue, switch_light, reset_cycle, and print, the functionality of which can be seen in the example below. The main program consists of an infinite loop, where the user can give commands, the effect of which can, as well, be seen in the example below:

Current cycle is 3, i.e. at most 3 vehicles can pass during the same green period
(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: a
  Input a register number: IV-10

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: a
  Input a register number: IIT-896

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: a
  Input a register number: 313

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: a
  Input a register number: ABC-111

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: p
RED: Vehicle(s) IV-10 IIT-896 313 ABC-111 waiting in traffic lights

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: s
GREEN: Vehicle(s) IV-10 IIT-896 313 can go on

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: p
RED: Vehicle(s) ABC-111 waiting in traffic lights

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: s
GREEN: Vehicle(s) ABC-111 can go on

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: p
RED: No vehicles waiting in traffic lights

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: s
GREEN: No vehicles waiting in traffic lights

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: s
RED: No vehicles waiting in traffic lights

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: s
GREEN: No vehicles waiting in traffic lights

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: a
  Input a register number: 313
GREEN: The vehicle 313 need not stop to wait

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: p
GREEN: No vehicles waiting in traffic lights

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: r
  Input a new amount for cycle: 2

(a)dd, (p)rint, (s)witch light, (r)eset cycle, (q)uit: q

Phases of the example execution above have beed depicted in the figures below. Let’s start from the situation, when the user has added four vehicles.

Four cars stopped at traffic lights

Then the user switches the color from red to green,

User has switched the color to green, but the cars have not moved yet

which means that the first three vehicles can go on. After that the color of the traffic lights will be switched to red automatically (without any command from the user).

Color switched to red automatically

Then the user gives the switch command that switches the color from red to green.

User has switched the color to green, but the car has not moved yet

This means the only remaining vehicle can go, and the color is switched automatically to red.

Color switched to red, but no new cars have come

After that color is switched by user commands a few times, but situation is not otherwise different, since there no vehicles waiting in the traffic lights. Finally, during the green period, the user adds a new vehicle (the register number of which is 313), but that vehicle is not added into queue, instead it can pass the traffic lights directly.

The automated test system tests the class without the main program. This means that the check does not care what you are doing in your own main program. It might be a good idea to save some of the original tests so that you can compare their prints with the model print above.

Tips for completing the assignment:

  • It is a good idea to implement a (private) method dequeue that removes one vehicle from the queue if possible (if the color is green). After that the method switch_light can call dequeue a suitable amount of times.
  • To begin, just implement the two most necessary methods (enqueue and print) and use comments to take all the calls of other methods off the main program. For this purpose, it is handy to use the multi-line comment /* this part is taken off with comments */.
  • When implementing each operation, please remember what the situations are that you need to consider when handling a linked data structure (see the summary of the previous material section).
  • Automated tests require proper use of dynamic memory management, e.g. all allocated memory must be deallocated. These tests use valgrind tool that will be introduced on the next round.

A+ presents the exercise submission form here.