CIT 591 Assignment 5: Small Town Traffic
Fall 2009, David Matuszek

Purposes of this assignment:

To try to give you a better understand of classes and objects.

General idea of the assignment:

Program a simulation of traffic passing through a small Town. There are two kinds of Vehicles, Cars and Ambulances. All streets in the town are one-way. The car to the right has right-of-way, except that ambulances always have right-of-way (except to other ambulances).

Detailed rules:

The town will be represented by a NxN "array", that is, a list of N lists of N elements each. (Actually, a town has two such arrays, but we'll talk about that later.) Every location in the array will contain a Car, an Ambulance, or None.

  • In even-numbered rows, vehicles can move to the right (increasing column numbers), but not to the left.
  • In odd-numbered rows, vehicles can move to the left (decreasing column numbers), but not to the right.
  • In even-numbered columns, vehicles can move down (increasing row numbers), but not up.
  • In odd-numbered columns, vehicles can move up (decreasing row numbers), but not down.
  • Remember: In Python, numbering starts from zero, which is an even number. Hence, the top row and leftmost column have even numbers.
  • If a car and an ambulance both want to enter an "intersection" (location in the array), the vehicle in the counterclockwise direction ambulance has the right of way (is allowed to move); the other must wait.
  • If two cars both want to enter an "intersection", the vehicle in the counterclockwise direction has the right of way; the other must wait.
  • If two ambulances both want to enter an "intersection", the vehicle in the counterclockwise direction has the right of way; the other must wait.
In each case, if the two vehicles are the same (both cars, or both ambulances), the red one is permitted to move, and the black one must wait.

Vehicles enter the town, pass through it, and leave the town, according to the following rules:

The simulation progresses in a series of "turns." On each turn,

  1. Figure out which vehicles are allowed to move (have right of way).
  2. Place any entering vehicles in their new locations (which must not already contain a vehicle; do step #1 first).
  3. Any vehicles that are in their goal location are removed from the town.

Vehicles move "all at once," rather than one at a time. The way we do this is to create a second (empty) NxN array. Then, for each vehicle, we figure out where it should be on the next "turn," and put it in that position in this secondary array. When all vehicles have been placed, assign this secondary array to the variable that held the original array, and create a new secondary array.

Getting started

The town starts out empty (it's early morning). Then, cars begin entering. After each turn, the town is printed out. The program continues until all cars have passed through the town, and the town is empty again.

The main() method should read cars in as tuples: (type of vehicle, initial row, initial column, goal row, goal column). In your test class, though, you don't do any input; you provide the tuples. And you don't print the results.

To make the program more readable (and consistent with my unit tests), use these global variables to represent directions:

up = 1
right = 2
down = 3
left = 4

You should also have, outside of any of your classes, a main() method. Here's what the main() method should do:

  1. Create an empty town of a reasonable size (say, 10x10 or 12x12).
  2. Tell the town to make a step (move all vehicles). The first time you do this, of course, the town will be empty, so no vehicles will actually move.
  3. Read in a line from an input file. (If no lines remain, skip this step.) The line should contain, in whatever format you choose, a description of one or more vehicles. Place those vehicles into the town. Since I have specified the methods getRandomEntryLocationAndDirection and getRandomExitLocation, you can generate new vehicles using these, rather than reading in from a file. At each step you should decide how many vehicles are entering the town (possibly zero); but after some number of steps, vehicles should stop entering the town, so that the simulation will eventually end.
  4. Print the town.
  5. Repeat, from step 2, until the town is empty and there are no more lines to be read in you are no longer creating new vehicles.

Use this file as your starting code.

Also, add the method __str__(self) to both the Car and the Ambulance class. In the Car class, it should return one of the strings ' ^ ', ' > ', ' v ', or ' < '; in the Ambulance class, one of the strings ' ^!', ' >!', ' v!', or ' <!'. For convenience in printing, these are all three-character strings.


Unit test all methods, except those that do I/O. I will have my own unit tests for the methods in the starting code, so be sure to have those methods exactly as described. Please check the web site often in case I have to make changes to the definition of these methods.


Good style. Good, complete unit tests. The program works as defined above.

Due date:

Before 6 AM, Friday October 16, 2009, via Blackboard.