The first section is a survey of the classes gleaned from the general problem statement in Problem Statement as well as the problem details in Roulette Details. This survey is drawn from a quick overview of the key nouns in these sections.
Given this survey of the candidate classes, the second section is a walkthrough of the possible design that will refine the definitions, and give us some assurance that we have a reasonable architecture. We will make some changes to the preliminary class list, revising and expanding on our survey.
We will also include a number of questions and answers about this preliminary design information. This should help clarify the design presentation and set the stage for the various development exercises in the chapters that follow.
To provide a starting point for the development effort, we have
to identify the objects and define their responsibilities. The central
principle behind the allocation of responsibility is
encapsulation; we do this by attempting to
isolate the information or isolate the
processing that must be done. Encapsulation assures that
the methods of a class are the exclusive users of the fields of that
class. It also makes each class very loosely coupled with other
classes; this permits change without a ripple through the application.
For example, each Outcome contains both the
name and the payout odds. That way each Outcome
can be used to compute a winning amount, and no other element of the
simulation needs to share the odds information or the payout
calculation.
In a few cases, we have looked forward to anticipate some future
considerations. One such consideration is the house
“rake”, also known as the
“vigorish”,
“vig”, or
commission. In some games, the house makes a 5%
deduction from some payouts. This complexity is best isolated in the
Outcome class. Roulette doesn't have any need
for a rake, since the presence of the 0 and 00 on the wheel gives the
house a little over 5% edge on each bet. We'll design our class so
that this can be added later when we implement Craps.
In reading the background information and the problem statement, we noticed a number of nouns that seemed to be important parts of the game we are simulating.
| Wheel |
| Bet |
| Bin |
| Table |
| Red |
| Black |
| Green |
| Number |
| Odds |
| Player |
| House |
One common development milestone is to be able to develop a class model in the Unified Modeling Language (UML) to describe the relationships among the various nouns in the problem statement. Building (and interpreting) this model takes some experience with OO programming. In this first part, we'll avoid doing extensive modeling. Instead we'll simply identify some basic design principles. We'll focus in on the most important of these nouns and describe the kinds of classes that you will build.
The following table summarizes some of the classes and responsibilities that we can identify from the problem statement. This is not the complete list of classes we need to build. As we work through the exercises, we'll discover additional classes and rework some of these preliminary classes more than once.
| Class | Responsibilities | Collaborations |
|---|---|---|
Outcome | A name for the bet and the payout odds. This isolates the calculation of the payout amount. Example: "Red", "1:1". | Collected by Wheel into the bins that
reflect the bets that win; collected by
Table into the available bets for the
Player; used by Game
to compute the amount won from the amount that was bet. |
Wheel | Selects the Outcomes that win. This
isolates the use of a random number generator to select
Outcomes; and it encapsulates the set of
winning Outcomes that are associated with
each individual number on the wheel. Example: the “1”
bin has the following winning Outcomes:
“1”, “Red”, “Odd”,
“Low”, “Column 1”, “Dozen
1-12”, “Split 1-2”, “Split 1-4”,
“Street 1-2-3”, “Corner 1-2-4-5”,
“Five Bet”, “Line 1-2-3-4-5-6”,
“00-0-1-2-3”, “Dozen 1”,
“Low” and “Column 1”. | Collects the Outcomes into bins; used
by the overall Game to get a next set of
winning Outcomes. |
Table | A collection of bets placed on
Outcomes by a
Player. This isolates the set of possible
bets and the management of the amounts currently at risk on each
bet. This also serves as the interface between the
Player and the other elements of the
game. | Collects the Outcomes; used by
Player to place a bet amount on a specific
Outcome; used by
Game to compute the amount won from the
amount that was bet. |
Player | Places bets on Outcomes, updates the
stake with amounts won and lost. | Uses Table to place bets on
Outcomes; used by
Game to record wins and losses. |
Game | Runs the game: gets bets from Player,
spins Wheel, collects losing bets, pays
winning bets. This encapsulates the basic sequence of play into a
single class. | Uses Wheel,
Table, Outcome,
Player. The overall statistical analysis
will play a finite number of games and collect the final value of
the Player's stake. |
The class Player has the most important
responsibility in the application, since we expect to update the
algorithms this class uses to place different kinds of bets. Clearly,
we need to cleanly encapsulate the Player, so
that changes to this class have no ripple effect in other classes of
the application.