There are two classes to design: a stub
Player that we can use for testing, and the
actual Game.
PlayerStub constructs a
Bet based on the
Outcome named
"Black". This is a very persistent
player.
We'll need a source for the Black outcome. We have several
choices; we looked at these in Building Bets. First, we can
build the Black outcome from scratch as a distinct object. This
works well for a stub that will only participate in a unit test.
However, it's annoying to have to specify the odds each time.
Second, we can interrogate the Wheel or
BinBuilder for a specific
Outcome object. Third, we can generalize this
approach by adding a Map to the Wheel, and
getting Outcome objects from the Map.
For now, we can create the black
Outcome manually.
In the long run, we'll have to define a
Player superclass, and make this class a
proper subclass of Player. However, our focus
now is on getting the Game designed and
built.
Outcome black = null;This is the outcome on which this player focuses their
betting. For now, we'll build this Outcome the hard way. In
the long run, we should get this from some souce
(Game, Wheel or
Table) using a well-known bet
name.
Table table ;Used to place individual bets.
PlayerStub(Table aTable);Constructs the Player with a
specific table for placing bets. This also creates the
“black” Outcome. This is
saved in the black variable for use in
creating bets.
void placeBets();Updates the Table with the
various bets. This version creates a
Bet instance from the
black Outcome. It
uses Table
placeBet to place that bet.
void win(Bet theBet);Notification from the Game that
the Bet was a winner. The amount of
money won is available via theBet
winAmount.
void lose(Bet theBet);Notification from the Game that
the Bet was a loser.
Game manages the sequence of actions
that defines the game of Roulette. This includes notifying the
Player to place bets, spinning the
Wheel and resolving the
Bets actually present on the
Table.
Wheel theWheel ;Contains the wheel that returns a randomly selected
Bin of
Outcomes.
Table theTable ;Contains the bets placed by the player.
Player thePlayer ;Places bets on the table.
We based the Roulette constructor on a design that allows any of the fields to be replaced. This is the Strategy design pattern. Each of these objects is a replaceable strategy, and can be changed by the client that uses this game.
Additionally, we specifically do not include the
Player instance in the constructor. The
Game exists independently of any
particular Player, and we defer binding
the Player and
Game until we are gathering statistical
samples.
Game(Wheel aWheel,
Table aTable);Constructs a new Game, using a
given Wheel and
Table.
void cycle(Player aPlayer);This will execute a single cycle of play with a given
Player. It will call
thePlayer
placeBets to get bets. It will call
theWheel next to
get the next winning Bin. It will then
call theTable's
bets to get an
Iterator over the
Bets. Stepping through this
Iterator returns the individual
Bet objects. If the winning
Bin contains the
Outcome, call the
thePlayer win,
otherwise call the thePlayer
lose.