-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpycraps.py
More file actions
executable file
·190 lines (151 loc) · 5.72 KB
/
pycraps.py
File metadata and controls
executable file
·190 lines (151 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/usr/bin/env python
import random, sys, argparse, numpy
r = random.Random()
def dice():
return r.randint(1,6) + r.randint(1,6)
def play():
ret = []
while True:
roll = dice()
ret.append(roll)
if roll == 7:
break
return ret
numbers = [4,5,6,8,9,10]
# multiplier here is flat odds bet, meaning non-flat payout, eg for multiplier of 2:
# if roll is 4, stake is 10, odds is 20, payout is 40
# if roll is 4, stake is 10, odds is 20, payout is 30
# if roll is 4, stake is 10, odds is 20, payout is 25
def dopass(rolls, stake=10, multiplier=3):
win = [7,11]
loss = [2,3,12]
push = []
wins = [x for x in rolls if x in win]
losses = [x for x in rolls if x in loss]
pushes = [x for x in rolls if x in push]
for x in numbers:
c = rolls.count(x)
if c > 1:
wins.extend([x] * (c-1))
if c:
losses.extend([x])
# front line
dollas = stake * (len(wins) - len(losses))
risk = stake * len(rolls)
# odds line
for w in [x for x in wins if x in numbers]:
odds_win = odds(w, stake, multiplier, True)
dollas += odds_win
risk += stake * multiplier
for l in [x for x in losses if x in numbers]:
odds_loss = stake * multiplier
dollas -= odds_loss
risk += odds_loss
return (risk, dollas)
# simple interpretation of multiplier here gives a flat lay bet
# meaning the payout schedule is not flat, eg for multiplier of 3:
# if roll is 4, stake is 10, lay is 30, payout is 15
# if roll is 5, stake is 10, lay is 30, payout is 20
# if roll is 6, stake is 10, lay is 30, payout is 25
# notice this is slightly different than how to treat a multiplier for pass
# but the code is simpler and is easy to adjust from the player's pov anyway.
def dontpass(rolls, stake=10, multiplier=3):
win = [2,3]
loss = [7,11]
push = [12]
wins = [x for x in rolls if x in win]
losses = [x for x in rolls if x in loss]
pushes = [x for x in rolls if x in push]
for x in numbers:
c = rolls.count(x)
if c > 1:
losses.extend([x] * (c-1))
if c:
wins.extend([x])
# front line
dollas = stake * (len(wins) - len(losses))
risk = stake * len(rolls)
# odds line
for w in [x for x in wins if x in numbers]:
odds_win = odds(w, stake, multiplier, False)
dollas += odds_win
risk += stake * multiplier
for l in [x for x in losses if x in numbers]:
odds_loss = stake * multiplier
dollas -= odds_loss
risk += odds_loss
return (risk, dollas)
def odds(r, stake, multiplier, rightway):
if rightway: inv = 1
else: inv = -1
if r == 4 or r == 10:
factor = 2 ** inv
elif r == 5 or r == 9:
factor = (3./2) ** inv
elif r == 6 or r == 8:
factor = (6./5) ** inv
else:
raise Exception("no odds for {}".format(r))
return int(stake * multiplier * factor)
def main():
parser = argparse.ArgumentParser(description = 'Craps simulator')
parser.add_argument('bankroll', type=int, help='starting bankroll')
parser.add_argument('N', type=int, default=10, help='number of points to simulate')
parser.add_argument('--dontpass', action='store_true', default=False, help="Play the don't pass side (program defaults to pass)")
parser.add_argument('--trials', type=int, default=1, help='number of trials (ie casino visits)')
parser.add_argument('-c', '--csv', action='store_true', help='output in csv format')
parser.add_argument('--silent' , action='store_true', default=False, help='silent output')
parser.add_argument('--stats' , action='store_true', default=False, help='calculate statistics for trials')
args = parser.parse_args()
csv = args.csv
N = args.N
trials = args.trials
silent = args.silent
stats = args.stats
initial_bankroll = args.bankroll
# store results in arrays for statistics
results = []
risked = []
while trials:
trials -= 1
trial_risk = 0
# reset trial variables
bankroll = initial_bankroll
N = args.N
while N:
N -= 1
a = play()
if args.dontpass:
(risk, reward) = dontpass(a)
else:
(risk, reward) = dopass(a)
trial_risk += risk
bankroll += reward
if not csv and not silent:
print "-" * 40
print "{} rolls: {}".format(len(a), a)
print "outcome: ${}".format(reward)
print "risked: ${}".format(risk)
print "bankroll: ${}".format(bankroll)
if not csv and not silent:
print "-" * 40
if csv and not silent:
print bankroll
results.append(bankroll)
risked.append(trial_risk)
if stats:
bankroll_array = numpy.array(results)
risked_array = numpy.array(risked)
avg_bankroll_result = numpy.mean(bankroll_array)
bankroll_stddev = numpy.std(bankroll_array)
print "mean = {:.03f}".format(avg_bankroll_result)
print "stddev = {:.03f}".format(bankroll_stddev)
print "min = {}".format(numpy.min(bankroll_array))
print "max = {}".format(numpy.max(bankroll_array))
avg_risked = numpy.mean(risked_array)
total_risked = numpy.sum(risked_array)
print "average risked = {}".format(avg_risked)
print "total risked = {}".format(total_risked)
print "house = {:.03f}%".format((avg_bankroll_result - initial_bankroll) / avg_risked * 100)
if __name__ == "__main__":
main()