CS 70, Spring 2004
Assignment 8: Bar Simulation

The program for this assignment, and everything else except the README file, is due at 9 P.M. on Wednesday, April 7th, 2004. As usual, the README file is due at midnight the same day (i.e., the moment that Thursday starts). Refer to the homework policies page for general homework guidelines.

The primary purpose of this assignment is to familiarize you with C++ templates. In fact, once you have finished converting your list class to support templates, you will discover that there is relatively little else to be done.

NOTE: the templated list class you develop in this assignment MUST be based on your solution to assignment 7. It will also be central to assignment 9. A correct solution to this assignment will NOT be distributed to the class.


Not far from Deep Glen Polytechnic University is Storm's Juice Bar. On any typical night, it is packed with rowdy DGP students who are assiduously avoiding their studies.

Wesley Storm, the owner and bartender, is a very busy man. Known as "Wes the Bar Monkey" because of his long arms and seeming ability to mix four drinks at once, he works all day, every day, to ensure that his customers are happy. Since Storm's is a fairly large place, he also employs several students as table servers. If a customer is seated at the bar, Wes serves drinks directly, but the servers carry drinks to customers at the tables. Servers have priority over individual customers. When a server arrives, Wes stops mixing drinks for individual customers, and doesn't return to that task until there are no table servers waiting.

Recently, Wes has become concerned about the quality of the service he is providing. It seems to him that he is slowing down, and he worries that he will lose customers if they find themselves waiting too long for their next drink.

To address the problem, Wes has asked you and a friend, Janet McMudd, to develop a simulation of the bar's operation. His hope is that by experimenting with the simulation parameters, he will be able to find out how long he can continue to work alone before his customers become unhappy. Janet wrote a lot of useful code, but unfortunately she took a break and headed over to Storm's, where she is currently passed out under a table, the victim of severe sleep deprivation. Your job is to finish the simulation so that Wes will fulfill his promise of free drinks for the remainder of your college career.

Introduction to the Simulation

The bar simulation will be done using a technique called "discrete-event simulation". This method is used for systems where the activity can be broken down into individual events, such as bank customers using an ATM. (The other type of simulation is "continuous-system simulation," used for things where the behavior is continuous, such as spacecraft flight.) A typical discrete-event simulation is based on one or more queues, in which the events are stored until it is time to process them.

To simplify the job of doing the simulation, Janet's design concentrates on the bartender. The program assumes that individual drinkers and table servers arrive at the bar and place orders at random times. As is common in simulations (and in real life), the arrival pattern is exponentially distributed (more accurately, the time between arrivals is exponentially distributed). Don't worry if you don't know what that means, because Janet already finished that part of the code.

The main part of the simulation runs from two queues: one containing individual drinkers, the other containing table servers. The queues are sorted by arrival time. The simulation merely needs to choose a customer from one queue or the other, provide the appropriate service, and record useful statistics about the customer. For simplicity, the finite population of customers and servers is modeled as an infinite population; this saves the trouble of simulating the time spent drinking and wandering around between tables.

Since your friend Janet is a big C++ fan, she decided to implement the queues using an existing linked-list class. However, since the simulation needs to store two different data types (Drinker and TableServer) in the two queues, she decided to convert the list into a templated class so she could use the same code for both queues. She didn't finish the conversion, so you are stuck with that job.

Data Structures

As mentioned above, the templated list class is used as a queue. This is the only data structure you need to implement. (Properly speaking, it's used as three-fourths of a deque: your class must support pushing and popping at the head, but only pushing at the tail. That means that your singly linked list from assignment 7 is sufficient.)

The program also uses several other structures: BarRequester is a base class for Drinker and TableServer, which represent individual customers and table servers, respectively. There is also a SimulationTime class that keeps track of the simulated time during a run. Janet finished writing and debugging those classes, so you don't have to worry about them (although they are worth studying, since Janet is known as a pretty talented coder).

What You Need to Build

To complete this assignment, you must do the following tasks:

The most difficult part of the assignment is the last item: template conversion. Although superficially easy, this task is often very painful for newcomers to C++. The syntax is messy, the requirements often don't make sense, and (at least with g++) the error messages are monumentally unhelpful. Worse, some of your compile errors won't show up until you actually use the templates, so piecemeal error-finding techniques won't work.

The single biggest thing you can do to ease your task is to ask for help. It turns out that there is almost nothing to be learned from trying to solve template compilation errors on your own. It's all a bunch of tricks, with no logic to them, and the best way to learn them is to have somebody else show them to you. So if you find yourself puzzling over a compilation error for more than 5 minutes, we strongly suggest that you find somebody to help you with it. You will save yourself an astounding amount of time. (Prof. Kuenning likes to tell about the time he got rid of 187 template-related compilation errors in 3 minutes flat!)

You must create or modify the following files:

The usual README file that documents your code. You do not need to extensively document the supplied code, but you must mention its existence (files and classes).
This must be the file that you downloaded from this Web page, with additions at the "ADD STUFF" parts. You may not change any other part of the file.
You must create your own Makefile for this assignment. We strongly suggest that you use the HW07 Makefile as a guide. In particular, the "depend" rule will make your life much easier.
This file will contain the interface definition for the templated list class (which must be named List) and its templated iterator, ListIterator. Note that both classes must be defined by this file, either by placing both definitions in the file, or by having it #include whatever file(s) contain the remaining definitions. (Note: ListIterator is not used in this assignment. However, you will need it for the next assignment, so it's better to convert it to use templates now if at all possible.)
Any other header files that you feel are necessary to implement your code. (There is no requirement that there be any other header files, but you might find it useful.)
Any other source files that you feel are necessary to implement your code.
Any other includable source files that you feel are necessary to implement your code.

In addition, you will need to download the following files that are part of the program, but you may not modify them:

This header file defines the BarRequester class and its derivatives: Drinker and TableServer. It also defines the TimeStatistics class for collecting statistical information.
This file contains the implementation of BarRequester and its related classes.
mtwist.c, mtwist.h, and mtwist.3
A fast random-number generation package. The ".3" file is the manual page; you can format it with "nroff -man mtwist.3 | less -s. For CS70 purposes, you can treat the random-number generator as an opaque package.
randistrs.c, randistrs.h, and randistrs.3
A package for generating random numbers from various distributions. For CS70 purposes, you can treat it as opaque.
This header file contains various constants that are useful to the simulation. Most of them are defaults for the simulation parameters.
This header file defines the SimulationTime class.
This file contains the implementation of the SimulationTime class.

In assign_08.cc, you must provide the main simulation loop, in the barMonkey function. Since this is not a class in simulation, that file contains pseudocode to help guide you in writing the loop.

The places where you need to provide code are marked by "ADD STUFF" comments.

Since assign_08.cc is provided to you, you must maintain stylistic consistency in that file. However, you are not required to use any specific coding style in the other files that you create. Since you are creating them from scratch, any good style is acceptable. In particular, you do not have to match the style of assign_08.cc in those files.

As usual, you must check out the provided files by using "cs70checkout hw08".

When you have a working solution, you must submit your files with cs70submit. If you create any new files, you need to tell the submission system about them by mentioning them once on a cs70submit command line. For convenience, we have provided dummy versions of README, Makefile, and list.hh so that they will be sure to get submitted.


Testing is your responsibility. We will not provide exact test cases for you. You should test your program a number of times, under different conditions.

In its default condition, the program is nondeterministic (i.e., two successive runs may produce different results). To make testing easier, the program accepts a switch that makes it deterministic. If you use "-S all n", where n is an integer, the random seed will be set to that value. (More accurately, n will be used to set several random seeds, since the program uses four different pseudorandom number generators, or PRNGS.) Specifying the random seed will allow you to control the program's behavior so that you can reproduce bugs.

You will also find it instructive to run the program with various values for the -D, -M, -P, -r, -s, and -T switches. Judicious reading of the comments, together with experimentation, will reveal the purpose of these switches and how they interact.

We will not limit ourselves to running only simple test cases. You can expect that we will run stress tests in an attempt to break your program.

Sample Output

To help you be sure you have written correct code, we have provided a sample of the output from a simulation run with the switches "-S all 1".

Emacs and icc Files

By default, emacs doesn't know that icc files contain C++ code. There are three ways to tell emacs to use C++ mode:

  1. Execute "ESC x c++-mode RET" each time you visit the file. Obviously, this is a pain.
  2. Add the line "// ;-*-C++-*-" as the first line of the file. Emacs will recognize the line and automatically switch to C++ mode. This is less of a pain, but you still have to do it to every file.
  3. Add the following line to your ".emacs" file in your home directory. (If you don't have a ".emacs" file, create one containing this line):
    (setq auto-mode-alist (append '(("\\.icc$" . c++-mode)) auto-mode-alist))
    The line must be inserted exactly as given above, including the double backslash, the parentheses, and the funny single quote.

Tricky Stuff

As usual there are some tricky parts to this assignment. Some of them are:

© 2004, Geoff Kuenning

This page is maintained by Geoff Kuenning.