+++ /dev/null
-import popen2
-from DECK import *
-from GAMEPLAY import *
-global GLOBAL_TXT
-#import psyco; psyco.full()
-
-start_stack = 1000
-blinds = [1,2,4,8,16,25,37,50]
-hand_clock = 20
-
-# Command line arguments
-import sys
-
-try : A = player(sys.argv[1],sys.argv[1])
-except: A = player('Meg')
-try : B = player(sys.argv[2], sys.argv[2])
-except: B = player('Jack')
-try : tournament_N = int(sys.argv[3])
-except: tournament_N = 1
-
-P = [A,B]
-for n in xrange(tournament_N):
- A.cash = start_stack
- B.cash = start_stack
-
- hand_count,b = 0, 0
-
- while A.cash > 0 and B.cash > 0:
- hand_count += 1
-
- if hand_count % hand_clock==0:
- b = b+1 if b < len(blinds)-1 else len(blinds)-1
-
- GLOBAL_TXT = gameplay(DECK, P[0],P[1], blinds[b])
-
- # Allow the players to view the end result
- board = [DECK[n] for n in xrange(4,9)]
- flop,turn,river = board[:3], board[3:4], board[4:5]
- if not A.FOLD and not B.FOLD:
- GP("INFO ",A.name, pp_hand(A.hole), pp_score(A), ' ',A.cash)
- GP("INFO ",B.name, pp_hand(B.hole), pp_score(B), ' ',B.cash)
- GP("INFO GAMEOVER ", hand_count)
- for p in P:
- if p.brain:
- p.GP_FLUSH(returnGP())
- p.GP_BUFFER = []
-
- # Human player text
- if not A.brain or not B.brain: # or True:
- for g in GLOBAL_TXT: print g
- print "INFO BOARD ", pp_hand([DECK[n] for n in xrange(4,9)])
-
- P = [P[-1]] + P[:-1] # Cycle the player order
-
- if A.cash: print A.name, hand_count
- else : print B.name, hand_count
-
-for p in P:
- if p.brain: p.die() # Kill the players!
-
-
-
-
"""Ordered list of face cards.
"""
-DECK = dict([(c/4, c%4) for c in range(52)])
+DECK = [(c/4, c%4) for c in range(52)]
"""Cards in the deck are stored as (n,m), where `n` is the rank number
`n=[0,12]`, and `m` is the suit `m=[0,3]`.
(0,1) is a two of hearts,
(11,0) is a king of spades,
(12,3) is an ace of clubs
+
+>>> DECK[:5]
"""
--- /dev/null
+#!/usr/bin/python
+
+"""Run a poker championship.
+"""
+
+from table import Player, Blinds, Table
+from deck import DECK
+
+
+def run(players, blinds, start_stack, hand_limit, tournaments, verbose=False):
+ for n in xrange(tournaments):
+ for player in players:
+ player.cash = start_stack
+ table = Table(deck=DECK, players=players, blinds=blinds,
+ verbose=verbose)
+ while len(table.players) > 1 and table.hand_count < hand_limit:
+ table.play_round()
+ # keep bots up to date, so they can think in parallel
+ for player in players:
+ if player.brain:
+ player.log_flush(table.log)
+ if len(table.players) == 1:
+ print "INFO WINNER: Player %s" % table.players[0]
+ else:
+ assert table.hand_count >= hand_limit
+ print "INFO Time expired"
+ for player in table.players:
+ print "INFO Tie: Player %s" % player
+
+
+if __name__ == '__main__':
+ from optparse import OptionParser
+
+ usage = '%prog [options] PLAYER PLAYER ...'
+ epilog = ('`PLAYER`s should be name,brain tuples, e.g. (`a,p1.py`). '
+ 'Give just the name for a human playing from the command line.')
+ p = OptionParser(usage=usage, epilog=epilog)
+ p.add_option('-s', '--start-stack', dest='stack', default=1000,
+ type='int', help='start stack (%default)')
+ p.add_option('-b', '--blinds', dest='blinds',
+ default='1,2,4,8,16,25,37,50',
+ help='blind schedule (%default)')
+ p.add_option('-c', '--hand-clock', dest='clock', default=20, type='int',
+ help='hands between blind increments (%default)')
+ p.add_option('-l', '--hand-limit', dest='limit', default=5000, type='int',
+ help='hand limit (-1 for unlimited play, %default')
+ p.add_option('-t', '--tournaments', dest='tournaments', default=1,
+ type='int', help='number of tournaments (%default)')
+ p.add_option('-v', '--verbose', dest='verbose', action='store_true',
+ help='print the log as it is written')
+
+ options,args = p.parse_args()
+
+ blinds = Blinds(blinds=[int(x) for x in options.blinds.split(',')],
+ hand_clock=options.clock)
+
+ players = []
+ for arg in args:
+ fields = [x.strip() for x in arg.rsplit(',', 1)]
+ name = fields[0]
+ if len(fields) == 1:
+ brain = None
+ else:
+ brain = fields[1]
+ players.append(Player(name=name, brain=brain))
+
+ try:
+ run(players=players, blinds=blinds, start_stack=options.stack,
+ hand_limit=options.limit, tournaments=options.tournaments,
+ verbose=options.verbose)
+ finally: # kill the bots
+ for p in players:
+ p.kill()
self.owe = min(self.owe, 0)
return wager
- def _log_flush(self, stream, log):
+ def log_flush(self, log):
"""Show the brain any new log entries."""
+ if self._proc:
+ stream = self._proc.stdin
+ else:
+ stream = sys.stdout
new_index = len(log)
- for line in LOG[self._next_log_index:new_index]:
+ for line in log[self._next_log_index:new_index]:
stream.write(line + '\n')
stream.flush()
self._next_log_index = new_index
self._proc.stdin.write('INFO POT %s\n' % str(pot))
self._proc.stdin.write('INFO MINRAISE %s\n' % str(min_raise))
self._proc.stdin.write('INFO OWE %s\n' % str(self.owe))
- self._proc.stdin.write('INFO HOLE %s\n' % pp_hand(self.hole))
- self._proc.stdin.write('INFO FLOP %s\n' % pp_hand(flop))
- self._proc.stdin.write('INFO TURN %s\n' % pp_hand(turn))
- self._proc.stdin.write('INFO RIVER %s\n' % pp_hand(river))
+ for phase,h in [('HOLE', self.hole), ('FLOP', flop),
+ ('TURN', turn), ('RIVER', river)]:
+ if h:
+ self._proc.stdin.write('INFO %s %s\n' % (phase, pp_hand(h)))
self._proc.stdin.flush()
- self._log_flush(self._proc.stdin, log)
+ self.log_flush(log)
def _human_play(self, active_players, pot, min_raise, flop, turn, river,
log):
"""Ask the human at `sys.stdin`/`sys.stdout` for guidance."""
- self._log_flush(sys.stdout, log)
+ self.log_flush(log)
print '[', pp_hand(self.hole), '] Board: ',
print '[', pp_hand(flop), pp_hand(turn), pp_hand(river), ']'
print 'POT: ', pot, ' OWE: ', self.owe, ' MIN_RAISE: ', min_raise,
>>> t.players
[<BufferedPlayer P3>]
"""
- def __init__(self, deck=None, players=None, blinds=None):
+ def __init__(self, deck=None, players=None, blinds=None, verbose=False):
self.deck = deck
self.players = players # list of surviving players
self.blinds = blinds
+ self.verbose = verbose
self.dealer = 0 # index of player acting as dealer (dealer button)
self.hand_count = 0
self.dead_players = [] # list of players in the order they died
index = index % len(self.players)
return self.players[index:]+self.players[:index]
+ def _log(self, msg):
+ """Add a message to the table log."""
+ self.log.append(msg)
+ if self.verbose:
+ print msg
+
def play_round(self, shuffle=random.shuffle):
self.deal(shuffle=shuffle)
self.ante_up()
if self.hand_complete(): return self.judge()
# FLOP ACTION
self.flop = self.board[:3]
- self.log.append('ACTION FLOP %s' % pp_hand(self.flop))
+ self._log('ACTION FLOP %s' % pp_hand(self.flop))
self.betting_round()
if self.hand_complete(): return self.judge()
# TURN ACTION
self.turn = self.board[3:4]
- self.log.append('ACTION TURN %s' % pp_hand(self.turn))
+ self._log('ACTION TURN %s' % pp_hand(self.turn))
self.betting_round()
if self.hand_complete(): return self.judge()
# RIVER ACTION
self.river = self.board[4:5]
- self.log.append('ACTION RIVER %s' % pp_hand(self.river))
+ self._log('ACTION RIVER %s' % pp_hand(self.river))
self.betting_round()
if self.hand_complete(): return self.judge()
# SHOWDOWN!
self.board = [self.deck[n] for n in xrange(2*N,2*N+5)] # common cards
for i,player in enumerate(self.players):
player.new_hand()
- self.log.append('INFO CHIPCOUNT Player %s %s'
+ self._log('INFO CHIPCOUNT Player %s %s'
% (player, player.cash))
player.hole = [self.deck[n] for n in xrange(2*i, 2*(i+1))]
player.hand = SevenChooseFiveHand(player.hole+self.board)
self.per_player_pot = max(self.per_player_pot, player.pot)
string = 'ACTION Player %s (pot %s) %s' % (player, player.pot, verb)
if append_cost: string += ' %d' % contribution
- self.log.append(string)
+ self._log(string)
return contribution
def betting_round(self, first_round=False):
action = player.decide(
active_players=[player]+active+all_in, pot=self.pot,
min_raise=min_raise, flop=self.flop, turn=self.turn,
- river=self.river)
+ river=self.river, log=self.log)
except IllegalBet, e:
- self.log.append((
+ self._log((
'ACTION Player %s bets %s illegally and FOLDS. '
'Valid bets are %d or anything >= %d')
% (e.player, e.bet, e.player.owe, min_raise))
self.pay_players(winners, losers)
# allow the players to view the end result
flop,turn,river = self.board[:3], self.board[3:4], self.board[4:5]
- self.log.append('INFO board %s' % pp_hand(self.board))
+ self._log('INFO board %s' % pp_hand(self.board))
for p in runcp:
- self.log.append('INFO Player %s hole: %s best: %s cash: %d'
+ self._log('INFO Player %s hole: %s best: %s cash: %d'
% (p, pp_hand(p.hole), p.hand.pp_score(), p.cash))
- self.log.append('INFO GAMEOVER %d' % self.hand_count)
+ self._log('INFO GAMEOVER %d' % self.hand_count)
# prepare for the next round
dead = [p for p in self.players if p.cash == 0]
self.dealer = (self.dealer + 1) % len(self.players)
next_dealing_player = self.players[self.dealer]
for p in dead:
- self.log.append('INFO Player %s died after hand %d'
+ self._log('INFO Player %s died after hand %d'
% (p, self.hand_count))
self.players.remove(p)
- p.kill()
self.dealer = self.players.index(next_dealing_player)
def pay_players(self, winners, losers):
self.per_player_pot -= pot
for name,take in winnings.items():
if take > 0:
- self.log.append('ACTION Player %s wins: %s' % (name, take))
+ self._log('ACTION Player %s wins: %s' % (name, take))