Skip to content

Instantly share code, notes, and snippets.

@rossgoodwin
Created December 15, 2016 03:36
Show Gist options
  • Select an option

  • Save rossgoodwin/da9a6c7e2a72ee1431ece85ecccde525 to your computer and use it in GitHub Desktop.

Select an option

Save rossgoodwin/da9a6c7e2a72ee1431ece85ecccde525 to your computer and use it in GitHub Desktop.
roulette.py v0.1
import random
import time
import json
import os
class Player(object):
def __init__(self, name, init_chips):
self.name = name
# cur_chips starts with init_chips
# cur_chips changes, init_chips doesn't
self.init_chips = init_chips
self.cur_chips = init_chips
self.bet_history = list()
self.performance = list()
class Wheel(object):
# OUTSIDE BETS
valid_bets = {
2: [
# first 1/2
range(1,19),
# second 1/2
range(19,37),
# odd
range(1,37,2),
# even
range(2,37,2)
# TODO
# BLACK AND RED
],
3: [
# first 1/3
range(1,13),
# second 1/3
range(13,25),
# third 1/3
range(25,37),
# left column
range(1,37,3),
# middle column
range(2,37,3),
# right column
range(3,37,3)
],
# INSIDE BETS
6: map(lambda i: range(i,i+6), range(1,32,3)),
9: map(lambda i: [i,i+1,i+3,i+4], range(1,34,3)+range(2,34,3)) + \
[range(4)], # special case: 0,1,2,3
12: map(lambda i: range(i,i+3), range(1,37,3)),
18: map(lambda i: [i,i+1], range(1,37,3)+range(2,37,3)) + \
map(lambda i: [i,i+3], range(1,34)) + \
[ [0,1], [0,2], [0,3] ], # special cases for zero
36: map(lambda i: [i], range(37))
}
def __init__(self, players, seed=65536, min_outside=5, name=str(int(time.time()*1000))):
self.name = name
# `seed` pseudorandom number generator
self.seed = seed
random.seed(self.seed)
# player objects
self.players = {p.name:p for p in players}
# `min_outside` == int
# number of min-bet chips for an
# outside bet
self.min_outside = min_outside
# `board` is a dict, key is cell number.
# Val in dict is number of min-bet chips.
# Val is float b/c certain inside bets
# split a chip between 2 and 6 cells.
# This dictionary will reset every roll.
self.board = {p.name:{i:0.0 for i in range(37)} for p in players}
# `cur_bets` is the var actually used
# for computation. like `board`, it
# resets each roll.
self.cur_bets = list()
# `history` is a list of 2-item
# tuples, where 1st item is spin result
# and 2nd item is board dict for that
# spin.
self.spin_history = list()
# wheel profits
self.house_profit = 0
def bet(self, player_name, amount, cells):
# `bet_type` is integer N
# signifying N:1 bet
# `amount` is number of min-bet chips
# `cells` (list) is distribution of
# cells bet is placed across. Must be
# in ascending order.
# `player` is Player instance
# do we have chips left?
if amount > self.players[player_name].cur_chips:
raise Exception('Player "%s" does not have enough chips for that bet!' % player_name)
else:
# if so, remove chips from stack
self.players[player_name].cur_chips -= amount
# print 'PLACING BET: %i\n\tCHIP STACK: %i' % (amount, self.players[player_name].cur_chips)
odds_to_one = 36/len(cells)
# ensure min outside bet is met
if odds_to_one <= 3 and amount < self.min_outside:
raise Exception('Outside bets must be at least %i chips!' % self.min_outside)
# convert from text
if cells == 'even':
cells = range(2,37,2)
elif cells == 'odd':
cells = range(1,37,2)
# make sure bet is valid
if not cells in self.valid_bets[odds_to_one]:
raise Exception('Invalid cell group!')
# add to board for histogram
for i in cells:
self.board[player_name][i] += float(amount)/len(cells)
# add to cur_bets for calculation
self.cur_bets.append( (player_name, amount, cells) )
# add to player's bet history
self.players[player_name].bet_history.append( (amount, cells) )
def spin(self):
result = random.randint(0,36)
self.spin_history.append( (result, self.board) )
for p in self.players:
self.players[p].performance.append( 0 )
for player_name, amount, cells in self.cur_bets:
# winning bets
if result in cells:
win_amount = (36/len(cells))*amount
# update chips
self.players[player_name].cur_chips += win_amount
# add to performance history
self.players[player_name].performance[-1] += (win_amount - amount)
self.house_profit -= (win_amount - amount)
# losing bets
else:
# update performance history
self.players[player_name].performance[-1] -= amount
self.house_profit += amount
# print stats
print '\n\n\n'
print '------------------------------------'
print 'SPIN #: %i' % len(self.spin_history)
print 'RESULT: %i' % result
print '------------------------------------'
for p in self.players:
print '\n', self.players[p].name, self.players[p].performance[-1], self.players[p].cur_chips, self.players[p].init_chips
# see if broke
if self.players[p].cur_chips == 0:
print 'PLAYER IS BROKE (LOST %i CHIPS)' % self.players[p].init_chips
print '\n'
print '------------------------------------'
print 'HOUSE PROFIT: %i' % self.house_profit
print '------------------------------------'
# reset board and cur_bets
self.board = {p:{i:0.0 for i in range(37)} for p in self.players}
self.cur_bets = list()
def dump_stats(self):
board_history = dict()
board_history['house_profit'] = self.house_profit
board_history['history'] = self.spin_history
with open(os.path.join('data', 'rouletteSim_%s_boardHistory.json'%self.name), 'w') as outfile:
json.dump(board_history, outfile)
player_history = dict()
for p in self.players:
out_obj = {
'bet_history': self.players[p].bet_history,
'performance': self.players[p].performance
}
player_history[p] = out_obj
with open(os.path.join('data', 'rouletteSim_%s_playerHistory.json'%self.name), 'w') as outfile:
json.dump(player_history, outfile)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment