Simple Craps Players¶
This chapter defines a variety of player strategies. Most of this is based on strategies already defined in Roulette, making the explanations considerably simpler. Rather than cover each individual design in separate chapters, we’ll rely on the experience gained so far, and cover four variant Craps players in this chapter. We’ll mention a fifth, but leave that as a more advanced exercise.
In Simple Craps Players Analysis we’ll expand on existing definition of craps players. We’ll add a number of betting strategies. In Craps 1-3-2-6 Player, Craps Cancellation Player, and Craps Fibonacci Player we’ll look at different betting strategies and how those can be implemented for a craps player.
In CrapsPlayer Design we’ll look at the general design for these simple players. We’ll look at the superclass in CrapsSimplePlayer superclass. We’ll look at each of the strategies in Craps Martingale Player, Player1326 State, Craps1326 Player and CrapsCancellation Player.
In Simple Craps Players Deliverables we’ll detail the deliverables for this chapter.
Simple Craps Players Analysis¶
The Player
class hierarchy suggests there are a number
of betting strategies for the Pass Line Odds bet. We
use the Martingale strategy for our CrapsMartingale
player.
We could also use the 1-3-2-6 system, the Cancellation system, or the
Fibonacci system for those odds bets. In each of these cases, we are
applying the betting strategy to one of the two bets the player will use.
An additional design note for this section is the choice of the two basic bets: the Pass Line and the Pass Line Odds bet. It is interesting to compare the results of these bets with the results of the Don’t Pass Line and the Don’t Pass Odds Bet. In particular, the Don’t Pass Odds Bets involve betting large sums of money for small returns; this will be compounded by any of these betting systems which accelerate the amount of the bet to cover losses. This change should be a simple matter of changing the two base bets used by all these variant players.
All of these players have a base bet (either Pass Line or Don’t Pass)
and an odds bet (either Pass Line Odds or Don’t Pass Odds). If we create
a superclass, called SimpleCraps
, we can assure that all
these simple betting variations will work for Pass Line as well as Don’t
Pass Line bets. The responsibility of this superclass is to define a
consistent set of fields and constructor for all of the subclasses.
Craps 1-3-2-6 Player¶
This player uses the 1-3-2-6 system for managing their
odds bet. From the Roulette 1-3-2-6 player (see Player 1-3-2-6 Analysis) we can
see that this player will need to use the Player1326State
class hierarchy. The craps player will use one of these objects track
the state changes of their odds. The base bet will not change.
However, the current definitions of the Player1326State
class hierarchy specifically reference Roulette1326
.
Presenting us with an interesting design problem. How do we repair our
design so that Player1326State
can work with Roulette1326
and Craps1326
?
The only dependency is the field outcome
,
which both Roulette1326
and Craps1326
must
provide to Player1326State
objects.
Problem. Where do store the Outcome
object
used by both the player and the state?
Forces. We have some common choices:
Create a Mixin Class. We extract the field and make it part of an mixin class that is required by
Player
subclasses that use the 1-3-2-6 strategy.Create a Common Superclass. In this case, we refactor the field up to the superclass.
Delegate to The State Object. This changes the defintion of
Player1326State
to make it more self-contained.
Mixin Class.
The relationship between a subclass of the
Player
class and thePlayer1326State
class can be formalized through an mixin class definition. We can define aBet1326_Able
class, which contains theOutcome
attribute and use this for theRoulette1326
andCraps1326
classes.class Bet1326_Able: def __init__(self) -> None: self.outcome = None class CrapsPlayer(Bet1326_Able, Player): def __init__(self) -> None: super().__init__()In this case, this appears to be an example of the Very Large Hammer design pattern. We’re using a very large hammer to pound a very small nail. The problem seems too small for this complex-looknig language feature.
Common Superclass.
We can refactor the single instance variable up to the superclass. This is a relatively minor change. However, it places a feature in a superclass which all but a few subclasses must ignore. This is another example of Swiss Army Knife design, where we will be subtracting or trying to ignore a feature from a superclass.
Delegate to the State Class.
If we change the
Player1326State
class to keep its own copy of the desiredOutcome
instance we cleanly remove any dependence onPlayer
class. ThePlayer
class is still responsible for keeping track of theOutcome
instances, and has subcontracted or delegated this responsibility to an instance of thePlayer1326State
classThe down side of this is that we must provide this
Outcome
instance to each state constructor as the state changes.
Solution. The solution we embrace is changing the definition of the Player1326State
class
to include the Outcome
instance. This delegates responsibility to
the state, where it seems to belong. This will change all of the
constructors, and all of the state change methods, but will cleanly
separate the Player1326State
class hierarchy from the Player
class hierarchy.
Craps Cancellation Player¶
When we examine the Roulette Cancellation Cancellation Player Analysis player we see that this player will need to use a list of individual betting amounts. Each win for an odds bet will cancel from this list, and each loss of an odds bet will append to this list.
As with the Craps Martingale player, we will be managing a base Pass Line bet, as well as an odds bet that uses the Cancellation strategy. The Cancellation algorithm can be easily transplanted from the original Roulette version to this new Craps version.
Craps Fibonacci Player¶
We can examine the Roulette Fibonacci Fibonacci Player Analysis and see that this player will need to compute new betting amounts based on wins and losses. THis will parallel the way the cancellation player works.
We’ll can have a Fibanacci series for some bets (like pass line bets) but a flat bet for the behind the line odds bet.
CrapsPlayer Design¶
We’ll extend the CrapsPlayer
class to create a CrapsSimplePlayer
class
to place both Pass Line and Pass Line Odds bets, as well as Don’t
Pass Line and Don’t Pass Odds bets. This will allow us to drop the CrapsPlayerPass
class, and revise the existing CrapsMartingale
class.
We have to rework the original Roulette-focused Player1326State
class
hierarchy, and the Roulette1326
class to use the new
version of the state objects.
Once this rework is complete, we can add the Craps1326
and CrapsCancellation
player subclasses.
For additional exposure, the more advanced student can rework the
Roulette Fibonacci player to create a CrapsFibonacci
player.
CrapsSimplePlayer superclass¶
-
class
CrapsSimplePlayer
¶ The
CrapsSimplePlayer
is a subclass ofCrapsPlayer
class and places two bets in Craps. The simple player has a base bet and an odds bet. The base bet is one of the bets available on the come out roll (either Pass Line or Don’t Pass Line), the odds bet is the corresponding odds bet (Pass Line Odds or Don’t Pass Odds). This class implements the basic procedure for placing the line bet and the behind the line odds bet. However, the exact amount of the behind the line odds bet is left as an abstract method. This allows subclasses to use any of a variety of betting strategies, including Martingale, 1-3-2-6, Cancellation and Fibonacci.
Fields¶
Constructors¶
-
CrapsSimplePlayer.
__init__
(self, table: Table, line: Outcome, odds: Outcome) → None¶ - Parameters
Constructs the
CrapsSimplePlayer
instance with a specificTable
object for placingBet
instances. Additionally a line bet (Pass Line or Don’t Pass Line) and odds bet (Pass Line Odds or Don’t Pass Odds) are provided to this constructor. This allows us to make either Pass Line or Don’t Pass Line players.
Methods¶
-
CrapsSimplePlayer.
placeBets
(self) → None¶ Updates the
Table
instance with the variousBet
instances. There are two basic betting rules.If there is no line bet, create the line
Bet
instance from theline
Outcome
object.If there is no odds bet, create the behind the line odds
Bet
instance from theodds
Outcome
object.
It’s essentual to check the price of the
Bet
instance before placing it. Particularly, Don’t Pass Odds bets may have a price that exceeds the player’s stake. This means that theBet
object must be constructed, then the price tested against thestake
to see if the player can even afford it. If thestake
is greater than or equal to the price, subtract the price and place the bet. Otherwise, simply ignore it the unafforableBet
object.
Craps Martingale Player¶
-
class
CrapsMartingale
¶ CrapsMartingale
is a subclass ofCrapsSimplePlayer
who places bets in Craps. This player doubles their Pass Line Odds bet on every loss and resets their Pass Line Odds bet to a base amount on each win.
Fields¶
-
CrapsMartingale.
lossCount
¶ The number of losses. This is the number of times to double the pass line odds bet.
-
CrapsMartingale.
betMultiple
¶ The the bet multiplier, based on the number of losses. This starts at 1, and is reset to 1 on each win. It is doubled in each loss. This is always .
Methods¶
-
CrapsMartingale.
placeBets
(self) → None¶ Extension to the superclass
placeBets()
method. This version sets the amount based on the value ofCrapsMartingale.betMultiple
.
-
CrapsMartingale.
win
(self, bet: Bet) → None¶ - Parameters
bet (
Bet
) – The bet that was a winner
Uses the superclass
win()
method to update the stake with an amount won. This method then resetslossCount
to zero, and resetsbetMultiple
to1
.
-
CrapsMartingale.
lose
(self, bet: Bet) → None¶ - Parameters
bet (
Bet
) – The bet that was a loser
Increments
lossCount
by1
and doublesbetMultiple
.
Player1326 State¶
Player1326State
is the superclass for all of the states in
the 1-3-2-6 betting system.
Constructors¶
Methods¶
Much of the original design for this state hierarchy should remain in place. See Player 1-3-2-6 Class for more information on the original design.
-
Player1326State.
nextLost
(self) → Player1326State¶ Constructs the new
Player1326State
instance to be used when the bet was a loser. This method is the same for each subclass: it creates a new instance ofPlayer1326NoWins
class.This method is defined in the superclass to assure that it is available for each subclass. This will use the
outcome
to be sure the new state has theOutcome
object on which the owning Player will be betting.
Craps1326 Player¶
-
class
Craps1326
¶ Craps1326
is a subclass ofCrapsSimplePlayer
class who places bets in Craps. This player changes their Pass Line Odds bet on every loss and resets their Pass Line Odds bet to a base amount on each win. The sequence of bet multipliers is given by the currentPlayer1326State
object.
Fields¶
-
Player1326State.
state
¶ This is the current state of the 1-3-2-6 betting system. It will be an instance of one of the four states: No Wins, One Win, Two Wins or Three Wins.
Constructors¶
-
Player1326.
__init__
(self, table: CrapsTable, line: Outcome, odds: Outcome) → None¶ - Parameters
Uses the superclass to initialize the
Craps1326
instance with a specificTable
object for placingBet
instances, and set the line bet (Pass Line or Don’t Pass Line) and odds bet (Pass Line Odds or Don’t Pass Odds).Then the initial state is an instance of the
Player1326NoWins
class, constructed using the odds bet.
Methods¶
-
Player1326.
placeBets
(self) → None¶ Updates the
Table
instance with a bet created by the current state. This method delegates the bet creation tostate
object’scurrentBet()
method.
CrapsCancellation Player¶
-
class
CrapsCancellation
¶ CrapsCancellation
is a subclass ofCrapsSimplePlayer
who places bets in Craps. This player changes their Pass Line Odds bet on every win and loss using a budget to which losses are appended and winings are cancelled.
Fields¶
-
CrapsCancellation.
sequence
¶ This
list
keeps the bet amounts; wins are removed from this list and losses are appended to this list. THe current bet is the first value plus the last value.
Constructors¶
-
CrapsCancellation.
__init__
(self, table: CrapsTable, line: Outcome, odds: Outcome) → None¶ - Parameters
Invokes the superclass constructor to initialize this instance of
CrapsCancellation
. Then callsresetSequence()
to create the betting budget.
Methods¶
There are few real changes to the original implementation of CancellationPlayer.
See Cancellation Player Class for more information.
-
CrapsCancellation.
placeBets
(self) → None¶ Creates a bet from the sum of the first and last values of
sequence
and the preferred outcome.This uses the essential line bet and odds bet algorithm defined above. If no line bet, this is created.
If there’s a line bet and no odds bet, then the odds bet is created.
If both bets are created, there is no more betting to do.
Simple Craps Players Deliverables¶
There are eight deliverables for this exercise.
The
CrapsSimplePlayer
abstract superclass. Since this class doesn’t have a body for theoddsBet()
method, it can’t be unit tested directly.A revised
CrapsMartingale
class, that is a proper subclass ofCrapsSimplePlayer
. The existing unit test forCrapsMartingale
should continue to work correctly after these changes.A revised
Player1326State
class hierarchy. Each subclass will use theoutcome
field instead of getting this information from aPlayer1326
instance. The unit tests will have to be revised slightly to reflect the changed constructors for this class.A revised
Roulette1326
class, which reflects the changed constructors for thisPlayer1326State
. The unit tests should indicate that this change has no adverse effect.The
Craps1326
subclass ofCrapsSimplePlayer
. This will use the revisedPlayer1326State
.A unit test class for
Craps1326
. This test should synthesize a fixed list ofOutcome
instances,Throw
instances, and calls aCraps1326
instance with various sequences of craps, naturals and points to assure that the bet changes appropriately.The
CrapsCancellation
subclass ofCrapsSimplePlayer
.A unit test class for
CrapsCancellation
. This test should synthesize a fixed list ofOutcome
instances,Throw
instances, and calls aCrapsCancellation
instance with various sequences of craps, naturals and points to assure that the bet changes appropriately.
Looking Forward¶
This is a large number of alternative playing strategies. It’s important to see how the betting schemes are their own class hierarchy, separate from the overall players.
In the next chapter we’ll at some more stateful player alterives. In this case, a player that counts rolls and adds “hedge bets” to guard against losses.