Created
December 15, 2016 03:36
-
-
Save rossgoodwin/da9a6c7e2a72ee1431ece85ecccde525 to your computer and use it in GitHub Desktop.
roulette.py v0.1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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