This is a rather long chapter, which describes a number of design considerations surrounding Outcome, Bin and Wheel. The second section presents a number of algorithms to group Outcomes based on the geometry of the table. These algorithms are presented at a high level, leaving much of the detailed design to the student.
It is clear that enumerating each Outcome in the 38 Bins is a tedious undertaking. Most Bins contain about fourteen individual Outcomes.
It is often helpful to create a class that is used to build an instance of another class. This is a design pattern sometimes called a Builder. We’ll design an object that builds the various Bins and assigns them to the Wheel. This will fill the need left open in the Wheel Class.
Additionally, we note that the complex algorithms to construct the Bins are only tangential to the operation of the Wheel object. While not essential to the design of the Wheel class, we find it is often helpful to segregate these rather complex builder methods into a separate class.
The BinBuilder class will have a method that enumerates the contents of each of the 36 number Bins, building the individual Outcome instances. We can then assign these Outcome objects to the Bins of a Wheel instance. We will use a number of steps to create the various types of Outcomes, and depend on the Wheel to assign each Outcome object to the correct Bin.
The Roulette Outcomes. Looking at the Available Bets in Roulette gives us a number of geometric rules for determining the various Outcomes that are combinations of individual numbers. These rules apply to the numbers from one to thirty-six. A different – and much simpler – set of rules applies to 0 and 00. First, we’ll survey the table geometry, then we’ll develop specific algorithms for each kind of bet.
,
, and
, where
.The Bins for zero and double zero can easily be enumerated. Each bin has a straight number bet Outcome, plus the Five Bet Outcome (00-0-1-2-3, which pays 6:1).
One other thing we’ll probably want are handy names for the various kinds of odds. While can define an Outcome as Outcome( "Number 1", 35 ) , this is a little opaque. A slightly nicer form is Outcome( "Number 1", RouletteGame.StraightBet ). These are specific to a game, not general features of all Outcomes. We haven’t designed the game yet, but we can provide a stub class with these these outcome odds definitions.
This section provides the algorithms for nine kinds of bets.
Straight bet Outcomes are the easiest to generate.
For All Numbers. For each number, n,
:
Create Outcome. Create an Outcome from the number, n, with odds of 35:l.
Zero. Create an Outcome from the “0” with odds of 35:l. Assign this to Bin 0.
Double Zero. Create an Outcome from the “00” with odds of 35:l. Assign this to Bin 37.
Split bet Outcomes are more complex because of the various cases: corners, edges and down-the-middle.
We note that there are two kinds of split bets:
We can look at the number 5 as being part of 4 different pairs: (4,4+1), (5,5+1), (2,2+3), (5,5+3). The corner number 1 is part of 2 split bets: (1,1+1), (1,1+3).
We can generate the “left-right” split bets by iterating through the left two columns; the numbers 1, 4, 7, ..., 34 and 2, 5, 8, ..., 35.
For All Rows. For each row, r, where
:
First Column Number. Set
. This will create values 1, 4, 7, ..., 34.
Column 1-2 Split. Create a “n, n +1” split Outcome with odds of 17:1.
Assign to Bins. Associate this object with two Bins: n and n +1.
Second Column Number. Set
. This will create values 2, 5, 8, ..., 35.
Column 2-3 Split. Create a “n , n +1” split Outcome.
Assign to Bins. Associate this object to two Bins: n and n +1.
A similar algorithm must be used for the numbers 1 through 33, to generate the “up-down” split bets. For each number, n, we generate a “n, n +3” split bet. This Outcome belongs to two Bins: n and n +3.
Street bet Outcomes are very simple.
We can generate the street bets by iterating through the twelve rows of the layout.
For All Rows. For each row, r,
:
First Column Number. Set
. This will create values 1, 4, 7, ..., 34.
Street. Create a “n, n +1, n +2” street Outcome with odds of 11:1.
Assign to Bins. Associate this object to three Bins: n, n +1, n +2.
Corner bet Outcomes are as complex as split bets because of the various cases: corners, edges and down-the-middle.
Eacn corner has four numbers, n , n +1, n +3, n +4. This is two numbers in the same row, and two numbers in the next higher row.
We can generate the corner bets by iterating through the numbers 1, 4, 7, ..., 31 and 2, 5, 8, ..., 32. For each number, n, we generate four corner bets: “n , n +1, n+3 , n +4`” corner bet. This Outcome object belongs to four Bins.
We generate corner bets by iterating through the various corners based on rows and columns. There is room for two corners within the three columns of the layout: one corner starts at column 1 and the other corner starts at column 2. There is room for 11 corners within the 12 rows of the layout.
For All Lines Between Rows. For each row, r,
:
First Column Number. Set
. This will create values 1, 4, 7, ..., 31.
Column 1-2 Corner. Create a “n , n +1, n +3, n +4” corner Outcome with odds of 8:1.
Assign to Bins. Associate this object to four Bins: n, n +1, n +3, n +4.
Second Column Number. Set
. This will create values 2, 5, 8, ..., 32.
Column 2-3 Corner. Create a “n , n +1, n +3, n +4`” corner Outcome withs odds of 8:1.
Assign to Bins. Associate this object to four Bins: n, n +1, n +3, n +4.
Line bet Outcomes are similar to street bets. However, these are based around the 11 lines between the 12 rows.
For lines s numbered 0 to 10, the numbers on the line bet
can be computed as follows:
,
,
,
,
,
. This Outcome
object belongs to six individual Bins.
For All Lines Between Rows. For each row, r,
:
First Column Number. Set
. This will create values 1, 4, 7, ..., 31.
Line. Create a “n, n +1, n +2, n +3, n +4, n +5` line Outcome withs odds of 5:1.
Assign to Bins. Associate this object to six Bins: n, n +1, n +2, n +3, n +4, n +5.
Dozen bet Outcomes require enumerating all twelve numbers in each of three groups.
For All Dozens. For each dozen, d,
:
Create Dozen. Create an Outcome for dozen d +1 with odds of 2:1.
For All Numbers. For each number, m,
:
Assign to Bin. Associate this object to Bin.
Column bet Outcomes require enumerating all twelve numbers in each of three groups. While the outline of the algorithm is the same as the dozen bets, the enumeration of the individual numbers in the inner loop is slightly different.
For All Columns. For each column, c,
:
Create Column. Create an Outcome for column c +1 with odds of 2:1.
For All Rows. For each row, r,
:
Assign to Bin. Associate this object to Bin.
The even money bet Outcomes are relatively easy to generate.
Create the Red outcome, with odds of 1:1.
Create the Black outcome, with odds of 1:1.
Create the Even outcome, with odds of 1:1.
Create the Odd outcome, with odds of 1:1.
Create the High outcome, with odds of 1:1.
Create the Low outcome, with odds of 1:1.
For All Numbers. For each number, n,
:
Low? If
, associate the low Outcome with Bin n.
High? Otherwise,
, associate the high Outcome with Bin n.
Even? If
, associate the even Outcome with Bin n.
Odd? Otherwise,
, associate the odd Outcome with Bin n.
Red? If n is one of 1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, or 36, associate the red Outcome with Bin n.
BinBuilder creates the Outcomes for all of the 38 individual Bin on a Roulette wheel.
Creates the Outcome instances and uses the addOutcome() method to place each Outcome in the appropropriate Bin of wheel .
| Parameter: | wheel (Wheel) – The Wheel with Bins that must be populated with Outcomes. |
|---|
There should be separate methods to generate the straight bets, split bets, street bets, corner bets, line bets, dozen bets and column bets, even money bets and the special case of zero and double zero.
Each of the methods will be relatively simple and easy to unit test. Details are provided in Bin Builder Algorithms.
There are three deliverables for this exercise. The new classes will have Javadoc comments or Python docstrings.
An an advanced topic, we need to avoid hard coding the names of the bets. Both Java and Python provide extensive tools for localization (l10n) of programs. Since both applications already use Unicode strings, they support non-Latin characters, handling much of the internationalization (i18n) part of the process.
Python localization depends on the locale and gettext modules. The locale module provides a number of functions and constants to help format dates and times for the user’s selected locale. The gettext module provides a mechanism for getting translated text from a message catalog with messages in a variety of languages.
We won’t dwell on the l10n issue. However, the right preparation for l10n is to isolate all Strings used for messages, and format all dates and numbers with formatters found in the locale module. In this case, our Outcome names may be displayed, and should be isolated into a separate object. Even something as simple as blackBetName = _("Black") will set the stage for fetching strings from a gettext message catalog.
In order to define the _(string) function, the following fragment should be used. While not ubiquitous in Python programs, doing this now establishes a standard practice that will permit easy localization of an application program.
import gettext
gettext.NullTranslations().install()
print _("String To Be Translated")