Merge branch 'master' of git://git.assembla.com/free_poker_tools
This commit is contained in:
commit
7683334e36
328
pyfpdb/Hand.py
328
pyfpdb/Hand.py
|
@ -15,6 +15,8 @@
|
||||||
#In the "official" distribution you can find the license in
|
#In the "official" distribution you can find the license in
|
||||||
#agpl-3.0.txt in the docs folder of the package.
|
#agpl-3.0.txt in the docs folder of the package.
|
||||||
|
|
||||||
|
# TODO: get writehand() encoding correct
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
@ -31,8 +33,15 @@ import DerivedStats
|
||||||
import Card
|
import Card
|
||||||
|
|
||||||
class Hand:
|
class Hand:
|
||||||
|
|
||||||
|
###############################################################3
|
||||||
|
# Class Variables
|
||||||
UPS = {'a':'A', 't':'T', 'j':'J', 'q':'Q', 'k':'K', 'S':'s', 'C':'c', 'H':'h', 'D':'d'}
|
UPS = {'a':'A', 't':'T', 'j':'J', 'q':'Q', 'k':'K', 'S':'s', 'C':'c', 'H':'h', 'D':'d'}
|
||||||
LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'}
|
LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'}
|
||||||
|
SYMBOL = {'USD': '$', 'EUR': u'E', 'T$': '', 'play': ''}
|
||||||
|
MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE'}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, sitename, gametype, handText, builtFrom = "HHC"):
|
def __init__(self, sitename, gametype, handText, builtFrom = "HHC"):
|
||||||
self.sitename = sitename
|
self.sitename = sitename
|
||||||
self.stats = DerivedStats.DerivedStats(self)
|
self.stats = DerivedStats.DerivedStats(self)
|
||||||
|
@ -45,6 +54,10 @@ class Hand:
|
||||||
self.maxseats = 10
|
self.maxseats = 10
|
||||||
self.counted_seats = 0
|
self.counted_seats = 0
|
||||||
self.buttonpos = 0
|
self.buttonpos = 0
|
||||||
|
self.tourNo = None
|
||||||
|
self.buyin = None
|
||||||
|
self.level = None
|
||||||
|
self.mixed = None
|
||||||
self.seating = []
|
self.seating = []
|
||||||
self.players = []
|
self.players = []
|
||||||
self.posted = []
|
self.posted = []
|
||||||
|
@ -56,17 +69,19 @@ class Hand:
|
||||||
self.actions = {} # [['mct','bets','$10'],['mika','folds'],['carlg','raises','$20']]
|
self.actions = {} # [['mct','bets','$10'],['mika','folds'],['carlg','raises','$20']]
|
||||||
self.board = {} # dict from street names to community cards
|
self.board = {} # dict from street names to community cards
|
||||||
self.holecards = {}
|
self.holecards = {}
|
||||||
|
self.discards = {}
|
||||||
for street in self.allStreets:
|
for street in self.allStreets:
|
||||||
self.streets[street] = "" # portions of the handText, filled by markStreets()
|
self.streets[street] = "" # portions of the handText, filled by markStreets()
|
||||||
|
self.actions[street] = []
|
||||||
|
for street in self.actionStreets:
|
||||||
self.bets[street] = {}
|
self.bets[street] = {}
|
||||||
self.lastBet[street] = 0
|
self.lastBet[street] = 0
|
||||||
self.actions[street] = []
|
|
||||||
self.board[street] = []
|
self.board[street] = []
|
||||||
|
for street in self.holeStreets:
|
||||||
self.holecards[street] = {} # dict from player names to holecards
|
self.holecards[street] = {} # dict from player names to holecards
|
||||||
|
self.discards[street] = {} # dict from player names to dicts by street ... of tuples ... of discarded holecards
|
||||||
# Collections indexed by player names
|
# Collections indexed by player names
|
||||||
# self.holecards = {} # dict from player names to dicts by street ... of tuples ... of holecards
|
# self.holecards = {} # dict from player names to dicts by street ... of tuples ... of holecards
|
||||||
self.discards = {} # dict from player names to dicts by street ... of tuples ... of discarded holecards
|
|
||||||
self.stacks = {}
|
self.stacks = {}
|
||||||
self.collected = [] #list of ?
|
self.collected = [] #list of ?
|
||||||
self.collectees = {} # dict from player names to amounts collected (?)
|
self.collectees = {} # dict from player names to amounts collected (?)
|
||||||
|
@ -93,6 +108,10 @@ class Hand:
|
||||||
("TABLE NAME", self.tablename),
|
("TABLE NAME", self.tablename),
|
||||||
("HERO", self.hero),
|
("HERO", self.hero),
|
||||||
("MAXSEATS", self.maxseats),
|
("MAXSEATS", self.maxseats),
|
||||||
|
("TOURNAMENT NO", self.tourNo),
|
||||||
|
("BUYIN", self.buyin),
|
||||||
|
("LEVEL", self.level),
|
||||||
|
("MIXED", self.mixed),
|
||||||
("LASTBET", self.lastBet),
|
("LASTBET", self.lastBet),
|
||||||
("ACTION STREETS", self.actionStreets),
|
("ACTION STREETS", self.actionStreets),
|
||||||
("STREETS", self.streets),
|
("STREETS", self.streets),
|
||||||
|
@ -130,6 +149,28 @@ class Hand:
|
||||||
str = str + "\n%s =\n" % name + pprint.pformat(struct, 4)
|
str = str + "\n%s =\n" % name + pprint.pformat(struct, 4)
|
||||||
return str
|
return str
|
||||||
|
|
||||||
|
def addHoleCards(self, street, player, open=[], closed=[], shown=False, mucked=False, dealt=False):
|
||||||
|
"""\
|
||||||
|
Assigns observed holecards to a player.
|
||||||
|
cards list of card bigrams e.g. ['2h','Jc']
|
||||||
|
player (string) name of player
|
||||||
|
shown whether they were revealed at showdown
|
||||||
|
mucked whether they were mucked at showdown
|
||||||
|
dealt whether they were seen in a 'dealt to' line
|
||||||
|
"""
|
||||||
|
# logging.debug("addHoleCards %s %s" % (open + closed, player))
|
||||||
|
try:
|
||||||
|
self.checkPlayerExists(player)
|
||||||
|
except FpdbParseError, e:
|
||||||
|
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
return
|
||||||
|
|
||||||
|
if dealt: self.dealt.add(player)
|
||||||
|
if shown: self.shown.add(player)
|
||||||
|
if mucked: self.mucked.add(player)
|
||||||
|
|
||||||
|
self.holecards[street][player] = [open, closed]
|
||||||
|
|
||||||
def insert(self, db):
|
def insert(self, db):
|
||||||
""" Function to insert Hand into database
|
""" Function to insert Hand into database
|
||||||
Should not commit, and do minimal selects. Callers may want to cache commits
|
Should not commit, and do minimal selects. Callers may want to cache commits
|
||||||
|
@ -221,10 +262,10 @@ If a player has None chips he won't be added."""
|
||||||
self.players.append([seat, name, chips])
|
self.players.append([seat, name, chips])
|
||||||
self.stacks[name] = Decimal(chips)
|
self.stacks[name] = Decimal(chips)
|
||||||
self.pot.addPlayer(name)
|
self.pot.addPlayer(name)
|
||||||
for street in self.allStreets:
|
for street in self.actionStreets:
|
||||||
self.bets[street][name] = []
|
self.bets[street][name] = []
|
||||||
#self.holecards[name] = {} # dict from street names.
|
#self.holecards[name] = {} # dict from street names.
|
||||||
self.discards[name] = {} # dict from street names.
|
#self.discards[name] = {} # dict from street names.
|
||||||
|
|
||||||
|
|
||||||
def addStreets(self, match):
|
def addStreets(self, match):
|
||||||
|
@ -446,7 +487,7 @@ Card ranks will be uppercased
|
||||||
Map the tuple self.gametype onto the pokerstars string describing it
|
Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
"""
|
"""
|
||||||
# currently it appears to be something like ["ring", "hold", "nl", sb, bb]:
|
# currently it appears to be something like ["ring", "hold", "nl", sb, bb]:
|
||||||
gs = {"holdem" : "Hold'em",
|
gs = {"holdem" : "Hold'em",
|
||||||
"omahahi" : "Omaha",
|
"omahahi" : "Omaha",
|
||||||
"omahahilo" : "Omaha Hi/Lo",
|
"omahahilo" : "Omaha Hi/Lo",
|
||||||
"razz" : "Razz",
|
"razz" : "Razz",
|
||||||
|
@ -466,7 +507,6 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
|
|
||||||
logging.debug("gametype: %s" %(self.gametype))
|
logging.debug("gametype: %s" %(self.gametype))
|
||||||
retstring = "%s %s" %(gs[self.gametype['category']], ls[self.gametype['limitType']])
|
retstring = "%s %s" %(gs[self.gametype['category']], ls[self.gametype['limitType']])
|
||||||
|
|
||||||
return retstring
|
return retstring
|
||||||
|
|
||||||
|
|
||||||
|
@ -503,6 +543,33 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
elif act[1] == 'stands pat':
|
elif act[1] == 'stands pat':
|
||||||
return ("%s: stands pat" %(act[0]))
|
return ("%s: stands pat" %(act[0]))
|
||||||
|
|
||||||
|
def getStakesAsString(self):
|
||||||
|
retstring = "%s%s/%s%s" % (self.SYMBOL[self.gametype['currency']], self.sb, self.SYMBOL[self.gametype['currency']], self.bb)
|
||||||
|
return retstring
|
||||||
|
|
||||||
|
def writeGameLine(self):
|
||||||
|
# print >>fh, ("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
||||||
|
game_string = "PokerStars Game #%s: " % self.handid
|
||||||
|
if self.tourNo != None:
|
||||||
|
game_string = game_string + "Tournament #%s, %s %s - Level %s (%s) - " % (self.tourNo,
|
||||||
|
self.buyin, self.getGameTypeAsString(), self.level, self.getStakesAsString())
|
||||||
|
elif self.mixed != None:
|
||||||
|
game_string = game_string + " %s (%s, %s) - " % (self.MS[self.mixed],
|
||||||
|
self.getGameTypeAsString(), self.getStakesAsString())
|
||||||
|
else:
|
||||||
|
game_string = game_string + " %s (%s) - " % (self.getGameTypeAsString(), self.getStakesAsString())
|
||||||
|
game_string = game_string + datetime.datetime.strftime(self.starttime,'%Y/%m/%d %H:%M:%S ET')
|
||||||
|
return game_string
|
||||||
|
|
||||||
|
|
||||||
|
def writeTableLine(self):
|
||||||
|
table_string = "Table \'%s\' %s-max" % (self.tablename, self.maxseats)
|
||||||
|
if self.gametype['currency'] == 'play':
|
||||||
|
table_string = table_string + " (Play Money)"
|
||||||
|
if self.buttonpos != None:
|
||||||
|
table_string = table_string + " Seat #%s is the button" % self.buttonpos
|
||||||
|
return table_string
|
||||||
|
|
||||||
|
|
||||||
class HoldemOmahaHand(Hand):
|
class HoldemOmahaHand(Hand):
|
||||||
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC", handid=None):
|
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC", handid=None):
|
||||||
|
@ -550,35 +617,13 @@ class HoldemOmahaHand(Hand):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def addHoleCards(self, cards, player, shown, mucked, dealt=False):
|
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
||||||
"""\
|
if player == self.hero: # we have hero's cards just update shown/mucked
|
||||||
Assigns observed holecards to a player.
|
if shown: self.shown.add(player)
|
||||||
cards list of card bigrams e.g. ['2h','Jc']
|
if mucked: self.mucked.add(player)
|
||||||
player (string) name of player
|
|
||||||
shown whether they were revealed at showdown
|
|
||||||
mucked whether they were mucked at showdown
|
|
||||||
dealt whether they were seen in a 'dealt to' line
|
|
||||||
"""
|
|
||||||
logging.debug("addHoleCards %s %s" % (cards, player))
|
|
||||||
try:
|
|
||||||
self.checkPlayerExists(player)
|
|
||||||
except FpdbParseError, e:
|
|
||||||
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
|
||||||
return
|
|
||||||
|
|
||||||
cardset = set((self.card(c) for c in cards))
|
|
||||||
if len(cardset) == 0:
|
|
||||||
return
|
|
||||||
if dealt:
|
|
||||||
self.dealt.add(player)
|
|
||||||
if shown:
|
|
||||||
self.shown.add(player)
|
|
||||||
if mucked:
|
|
||||||
self.mucked.add(player)
|
|
||||||
if player in self.holecards['PREFLOP']:
|
|
||||||
self.holecards['PREFLOP'][player].update(cardset)
|
|
||||||
else:
|
else:
|
||||||
self.holecards['PREFLOP'][player] = cardset
|
self.addHoleCards('PREFLOP', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
|
||||||
|
|
||||||
|
|
||||||
def writeHTMLHand(self, fh=sys.__stdout__):
|
def writeHTMLHand(self, fh=sys.__stdout__):
|
||||||
from nevow import tags as T
|
from nevow import tags as T
|
||||||
|
@ -677,8 +722,11 @@ dealt whether they were seen in a 'dealt to' line
|
||||||
|
|
||||||
def writeHand(self, fh=sys.__stdout__):
|
def writeHand(self, fh=sys.__stdout__):
|
||||||
# PokerStars format.
|
# PokerStars format.
|
||||||
print >>fh, ("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
# print >>fh, ("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
||||||
print >>fh, ("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
print >>fh, self.writeGameLine()
|
||||||
|
print >>fh, self.writeTableLine()
|
||||||
|
|
||||||
|
# print >>fh, ("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||||
|
|
||||||
players_who_act_preflop = set(([x[0] for x in self.actions['PREFLOP']]+[x[0] for x in self.actions['BLINDSANTES']]))
|
players_who_act_preflop = set(([x[0] for x in self.actions['PREFLOP']]+[x[0] for x in self.actions['BLINDSANTES']]))
|
||||||
logging.debug(self.actions['PREFLOP'])
|
logging.debug(self.actions['PREFLOP'])
|
||||||
|
@ -692,10 +740,10 @@ dealt whether they were seen in a 'dealt to' line
|
||||||
|
|
||||||
print >>fh, ("*** HOLE CARDS ***")
|
print >>fh, ("*** HOLE CARDS ***")
|
||||||
for player in self.dealt:
|
for player in self.dealt:
|
||||||
print >>fh, ("Dealt to %s [%s]" %(player, " ".join(self.holecards['PREFLOP'][player])))
|
print >>fh, ("Dealt to %s [%s]" %(player, " ".join(self.holecards['PREFLOP'][player][1])))
|
||||||
if self.hero == "":
|
if self.hero == "":
|
||||||
for player in self.shown.difference(self.dealt):
|
for player in self.shown.difference(self.dealt):
|
||||||
print >>fh, ("Dealt to %s [%s]" %(player, " ".join(self.holecards['PREFLOP'][player])))
|
print >>fh, ("Dealt to %s [%s]" %(player, " ".join(self.holecards['PREFLOP'][player][1])))
|
||||||
|
|
||||||
if self.actions['PREFLOP']:
|
if self.actions['PREFLOP']:
|
||||||
for act in self.actions['PREFLOP']:
|
for act in self.actions['PREFLOP']:
|
||||||
|
@ -734,7 +782,7 @@ dealt whether they were seen in a 'dealt to' line
|
||||||
elif self.gametype['category'] in ('holdem'):
|
elif self.gametype['category'] in ('holdem'):
|
||||||
numOfHoleCardsNeeded = 2
|
numOfHoleCardsNeeded = 2
|
||||||
if len(self.holecards['PREFLOP'][name]) == numOfHoleCardsNeeded:
|
if len(self.holecards['PREFLOP'][name]) == numOfHoleCardsNeeded:
|
||||||
print >>fh, ("%s shows [%s] (a hand...)" % (name, " ".join(self.holecards['PREFLOP'][name])))
|
print >>fh, ("%s shows [%s] (a hand...)" % (name, " ".join(self.holecards['PREFLOP'][name][1])))
|
||||||
|
|
||||||
# Current PS format has the lines:
|
# Current PS format has the lines:
|
||||||
# Uncalled bet ($111.25) returned to s0rrow
|
# Uncalled bet ($111.25) returned to s0rrow
|
||||||
|
@ -761,7 +809,7 @@ dealt whether they were seen in a 'dealt to' line
|
||||||
seatnum = player[0]
|
seatnum = player[0]
|
||||||
name = player[1]
|
name = player[1]
|
||||||
if name in self.collectees and name in self.shown:
|
if name in self.collectees and name in self.shown:
|
||||||
print >>fh, ("Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, " ".join(self.holecards['PREFLOP'][name]), self.collectees[name]))
|
print >>fh, ("Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, " ".join(self.holecards['PREFLOP'][name][1]), self.collectees[name]))
|
||||||
elif name in self.collectees:
|
elif name in self.collectees:
|
||||||
print >>fh, ("Seat %d: %s collected ($%s)" % (seatnum, name, self.collectees[name]))
|
print >>fh, ("Seat %d: %s collected ($%s)" % (seatnum, name, self.collectees[name]))
|
||||||
#~ elif name in self.shown:
|
#~ elif name in self.shown:
|
||||||
|
@ -770,9 +818,9 @@ dealt whether they were seen in a 'dealt to' line
|
||||||
print >>fh, ("Seat %d: %s folded" % (seatnum, name))
|
print >>fh, ("Seat %d: %s folded" % (seatnum, name))
|
||||||
else:
|
else:
|
||||||
if name in self.shown:
|
if name in self.shown:
|
||||||
print >>fh, ("Seat %d: %s showed [%s] and lost with..." % (seatnum, name, " ".join(self.holecards['PREFLOP'][name])))
|
print >>fh, ("Seat %d: %s showed [%s] and lost with..." % (seatnum, name, " ".join(self.holecards['PREFLOP'][name][1])))
|
||||||
elif name in self.mucked:
|
elif name in self.mucked:
|
||||||
print >>fh, ("Seat %d: %s mucked [%s] " % (seatnum, name, " ".join(self.holecards['PREFLOP'][name])))
|
print >>fh, ("Seat %d: %s mucked [%s] " % (seatnum, name, " ".join(self.holecards['PREFLOP'][name][1])))
|
||||||
else:
|
else:
|
||||||
print >>fh, ("Seat %d: %s mucked" % (seatnum, name))
|
print >>fh, ("Seat %d: %s mucked" % (seatnum, name))
|
||||||
|
|
||||||
|
@ -783,8 +831,10 @@ class DrawHand(Hand):
|
||||||
if gametype['base'] != 'draw':
|
if gametype['base'] != 'draw':
|
||||||
pass # or indeed don't pass and complain instead
|
pass # or indeed don't pass and complain instead
|
||||||
self.streetList = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.streetList = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
|
self.allStreets = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
self.holeStreets = ['DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.holeStreets = ['DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
self.actionStreets = ['PREDEAL', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.actionStreets = ['PREDEAL', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
|
self.communityStreets = []
|
||||||
Hand.__init__(self, sitename, gametype, handText)
|
Hand.__init__(self, sitename, gametype, handText)
|
||||||
self.sb = gametype['sb']
|
self.sb = gametype['sb']
|
||||||
self.bb = gametype['bb']
|
self.bb = gametype['bb']
|
||||||
|
@ -796,12 +846,13 @@ class DrawHand(Hand):
|
||||||
hhc.markStreets(self)
|
hhc.markStreets(self)
|
||||||
hhc.readBlinds(self)
|
hhc.readBlinds(self)
|
||||||
hhc.readButton(self)
|
hhc.readButton(self)
|
||||||
|
hhc.readHeroCards(self)
|
||||||
hhc.readShowdownActions(self)
|
hhc.readShowdownActions(self)
|
||||||
# Read actions in street order
|
# Read actions in street order
|
||||||
for street in self.streetList:
|
for street in self.streetList:
|
||||||
if self.streets[street]:
|
if self.streets[street]:
|
||||||
# hhc.readCommunityCards(self, street)
|
# hhc.readCommunityCards(self, street)
|
||||||
hhc.readDrawCards(self, street)
|
# hhc.readDrawCards(self, street)
|
||||||
hhc.readAction(self, street)
|
hhc.readAction(self, street)
|
||||||
hhc.readCollectPot(self)
|
hhc.readCollectPot(self)
|
||||||
hhc.readShownCards(self)
|
hhc.readShownCards(self)
|
||||||
|
@ -837,25 +888,33 @@ class DrawHand(Hand):
|
||||||
#print "DEBUG: self.posted: %s" %(self.posted)
|
#print "DEBUG: self.posted: %s" %(self.posted)
|
||||||
|
|
||||||
|
|
||||||
|
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
||||||
|
if player == self.hero: # we have hero's cards just update shown/mucked
|
||||||
|
if shown: self.shown.add(player)
|
||||||
|
if mucked: self.mucked.add(player)
|
||||||
|
else:
|
||||||
|
# TODO: Probably better to find the last street with action and add the hole cards to that street
|
||||||
|
self.addHoleCards('DRAWTHREE', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
|
||||||
|
|
||||||
def addDrawHoleCards(self, newcards, oldcards, player, street, shown=False):
|
|
||||||
"""\
|
# def addDrawHoleCards(self, newcards, oldcards, player, street, shown=False):
|
||||||
Assigns observed holecards to a player.
|
# """\
|
||||||
cards list of card bigrams e.g. ['2h','Jc']
|
#Assigns observed holecards to a player.
|
||||||
player (string) name of player
|
#cards list of card bigrams e.g. ['2h','Jc']
|
||||||
"""
|
#player (string) name of player
|
||||||
try:
|
#"""
|
||||||
self.checkPlayerExists(player)
|
# try:
|
||||||
# if shown and len(cardset) > 0:
|
# self.checkPlayerExists(player)
|
||||||
# self.shown.add(player)
|
## if shown and len(cardset) > 0:
|
||||||
self.holecards[player][street] = (newcards,oldcards)
|
## self.shown.add(player)
|
||||||
except FpdbParseError, e:
|
# self.holecards[street][player] = (newcards,oldcards)
|
||||||
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
# except FpdbParseError, e:
|
||||||
|
# print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
|
||||||
|
|
||||||
def discardDrawHoleCards(self, cards, player, street):
|
def discardDrawHoleCards(self, cards, player, street):
|
||||||
logging.debug("discardDrawHoleCards '%s' '%s' '%s'" % (cards, player, street))
|
logging.debug("discardDrawHoleCards '%s' '%s' '%s'" % (cards, player, street))
|
||||||
self.discards[player][street] = set([cards])
|
self.discards[street][player] = set([cards])
|
||||||
|
|
||||||
|
|
||||||
def addDiscard(self, street, player, num, cards):
|
def addDiscard(self, street, player, num, cards):
|
||||||
|
@ -868,12 +927,12 @@ player (string) name of player
|
||||||
self.actions[street].append(act)
|
self.actions[street].append(act)
|
||||||
|
|
||||||
|
|
||||||
def addShownCards(self, cards, player, holeandboard=None):
|
# def addShownCards(self, cards, player, holeandboard=None, shown=False, mucked=False):
|
||||||
"""\
|
# """\
|
||||||
For when a player shows cards for any reason (for showdown or out of choice).
|
#For when a player shows cards for any reason (for showdown or out of choice).
|
||||||
Card ranks will be uppercased
|
#Card ranks will be uppercased
|
||||||
"""
|
#"""
|
||||||
logging.debug("addShownCards %s hole=%s all=%s" % (player, cards, holeandboard))
|
# logging.debug("addShownCards %s hole=%s all=%s" % (player, cards, holeandboard))
|
||||||
# if cards is not None:
|
# if cards is not None:
|
||||||
# self.shown.add(player)
|
# self.shown.add(player)
|
||||||
# self.addHoleCards(cards,player)
|
# self.addHoleCards(cards,player)
|
||||||
|
@ -883,10 +942,39 @@ Card ranks will be uppercased
|
||||||
# self.addHoleCards(holeandboard.difference(board),player,shown=True)
|
# self.addHoleCards(holeandboard.difference(board),player,shown=True)
|
||||||
|
|
||||||
|
|
||||||
|
# def addHoleCards(self, cards, player, shown, mucked, dealt=False):
|
||||||
|
# """\
|
||||||
|
#Assigns observed holecards to a player.
|
||||||
|
#cards list of card bigrams e.g. ['2h','Jc']
|
||||||
|
#player (string) name of player
|
||||||
|
#shown whether they were revealed at showdown
|
||||||
|
#mucked whether they were mucked at showdown
|
||||||
|
#dealt whether they were seen in a 'dealt to' line
|
||||||
|
#"""
|
||||||
|
## I think this only gets called for shown cards.
|
||||||
|
# logging.debug("addHoleCards %s %s" % (cards, player))
|
||||||
|
# try:
|
||||||
|
# self.checkPlayerExists(player)
|
||||||
|
# except FpdbParseError, e:
|
||||||
|
# print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# if dealt:
|
||||||
|
# self.dealt.add(player)
|
||||||
|
# if shown:
|
||||||
|
# self.shown.add(player)
|
||||||
|
# if mucked:
|
||||||
|
# self.mucked.add(player)
|
||||||
|
# if player != self.hero: #skip hero, we know his cards
|
||||||
|
# print "player, cards =", player, cards
|
||||||
|
# self.holecards[self.holeStreets[-1]][player] = (cards, set([]))
|
||||||
|
|
||||||
def writeHand(self, fh=sys.__stdout__):
|
def writeHand(self, fh=sys.__stdout__):
|
||||||
# PokerStars format.
|
# PokerStars format.
|
||||||
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d %H:%M:%S ET', self.starttime)))
|
# print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d %H:%M:%S ET', self.starttime)))
|
||||||
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
print >>fh, self.writeGameLine()
|
||||||
|
# print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||||
|
print >>fh, self.writeTableLine()
|
||||||
|
|
||||||
players_who_act_ondeal = set(([x[0] for x in self.actions['DEAL']]+[x[0] for x in self.actions['BLINDSANTES']]))
|
players_who_act_ondeal = set(([x[0] for x in self.actions['DEAL']]+[x[0] for x in self.actions['BLINDSANTES']]))
|
||||||
|
|
||||||
|
@ -912,8 +1000,8 @@ Card ranks will be uppercased
|
||||||
for act in self.actions['DRAWONE']:
|
for act in self.actions['DRAWONE']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act)
|
||||||
if act[0] == self.hero and act[1] == 'discards':
|
if act[0] == self.hero and act[1] == 'discards':
|
||||||
(nc,oc) = self.holecards[act[0]]['DRAWONE']
|
(nc,oc) = self.holecards['DRAWONE'][act[0]]
|
||||||
dc = self.discards[act[0]]['DRAWONE']
|
dc = self.discards['DRAWONE'][act[0]]
|
||||||
kc = oc - dc
|
kc = oc - dc
|
||||||
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
||||||
|
|
||||||
|
@ -922,8 +1010,8 @@ Card ranks will be uppercased
|
||||||
for act in self.actions['DRAWTWO']:
|
for act in self.actions['DRAWTWO']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act)
|
||||||
if act[0] == self.hero and act[1] == 'discards':
|
if act[0] == self.hero and act[1] == 'discards':
|
||||||
(nc,oc) = self.holecards[act[0]]['DRAWTWO']
|
(nc,oc) = self.holecards['DRAWTWO'][act[0]]
|
||||||
dc = self.discards[act[0]]['DRAWTWO']
|
dc = self.discards['DRAWTWO'][act[0]]
|
||||||
kc = oc - dc
|
kc = oc - dc
|
||||||
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
||||||
|
|
||||||
|
@ -932,8 +1020,8 @@ Card ranks will be uppercased
|
||||||
for act in self.actions['DRAWTHREE']:
|
for act in self.actions['DRAWTHREE']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act)
|
||||||
if act[0] == self.hero and act[1] == 'discards':
|
if act[0] == self.hero and act[1] == 'discards':
|
||||||
(nc,oc) = self.holecards[act[0]]['DRAWTHREE']
|
(nc,oc) = self.holecards['DRAWTHREE'][act[0]]
|
||||||
dc = self.discards[act[0]]['DRAWTHREE']
|
dc = self.discards['DRAWTHREE'][act[0]]
|
||||||
kc = oc - dc
|
kc = oc - dc
|
||||||
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
||||||
|
|
||||||
|
@ -983,13 +1071,14 @@ class StudHand(Hand):
|
||||||
hhc.markStreets(self)
|
hhc.markStreets(self)
|
||||||
hhc.readAntes(self)
|
hhc.readAntes(self)
|
||||||
hhc.readBringIn(self)
|
hhc.readBringIn(self)
|
||||||
|
hhc.readHeroCards(self)
|
||||||
#hhc.readShowdownActions(self) # not done yet
|
#hhc.readShowdownActions(self) # not done yet
|
||||||
# Read actions in street order
|
# Read actions in street order
|
||||||
for street in self.streetList:
|
for street in self.streetList:
|
||||||
if self.streets[street]:
|
if self.streets[street]:
|
||||||
logging.debug(street)
|
logging.debug(street)
|
||||||
logging.debug(self.streets[street])
|
logging.debug(self.streets[street])
|
||||||
hhc.readStudPlayerCards(self, street)
|
# hhc.readStudPlayerCards(self, street)
|
||||||
hhc.readAction(self, street)
|
hhc.readAction(self, street)
|
||||||
hhc.readCollectPot(self)
|
hhc.readCollectPot(self)
|
||||||
hhc.readShownCards(self) # not done yet
|
hhc.readShownCards(self) # not done yet
|
||||||
|
@ -998,6 +1087,19 @@ class StudHand(Hand):
|
||||||
elif builtFrom == "DB":
|
elif builtFrom == "DB":
|
||||||
self.select("dummy") # Will need a handId
|
self.select("dummy") # Will need a handId
|
||||||
|
|
||||||
|
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
||||||
|
if player == self.hero: # we have hero's cards just update shown/mucked
|
||||||
|
if shown: self.shown.add(player)
|
||||||
|
if mucked: self.mucked.add(player)
|
||||||
|
else:
|
||||||
|
# self.addHoleCards('PREFLOP', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
|
||||||
|
self.addHoleCards('THIRD', player, open=[cards[2]], closed=cards[0:2], shown=shown, mucked=mucked)
|
||||||
|
self.addHoleCards('FOURTH', player, open=[cards[3]], closed=[], shown=shown, mucked=mucked)
|
||||||
|
self.addHoleCards('FIFTH', player, open=[cards[4]], closed=[], shown=shown, mucked=mucked)
|
||||||
|
self.addHoleCards('SIXTH', player, open=[cards[5]], closed=[], shown=shown, mucked=mucked)
|
||||||
|
self.addHoleCards('SEVENTH', player, open=[], closed=[cards[6]], shown=shown, mucked=mucked)
|
||||||
|
|
||||||
|
|
||||||
def addPlayerCards(self, player, street, open=[], closed=[]):
|
def addPlayerCards(self, player, street, open=[], closed=[]):
|
||||||
"""\
|
"""\
|
||||||
Assigns observed cards to a player.
|
Assigns observed cards to a player.
|
||||||
|
@ -1015,42 +1117,41 @@ closed likewise, but known only to player
|
||||||
except FpdbParseError, e:
|
except FpdbParseError, e:
|
||||||
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
|
||||||
def addHoleCards(self, cards, player, shown, mucked, dealt=False):
|
# def addHoleCards(self, cards, player, shown, mucked, dealt=False):
|
||||||
"""\
|
# """\
|
||||||
Assigns observed holecards to a player.
|
#Assigns observed holecards to a player.
|
||||||
cards list of card bigrams e.g. ['2h','Jc']
|
#cards list of card bigrams e.g. ['2h','Jc']
|
||||||
player (string) name of player
|
#player (string) name of player
|
||||||
shown whether they were revealed at showdown
|
#shown whether they were revealed at showdown
|
||||||
mucked whether they were mucked at showdown
|
#mucked whether they were mucked at showdown
|
||||||
dealt whether they were seen in a 'dealt to' line
|
#dealt whether they were seen in a 'dealt to' line
|
||||||
"""
|
#"""
|
||||||
|
##
|
||||||
|
## For stud games we just need to do the routine setting of shown/mucked/etc
|
||||||
|
## and then update the cards 'THIRD' and 'SEVENTH'
|
||||||
|
# logging.debug("addHoleCards %s %s" % (cards, player))
|
||||||
|
# try:
|
||||||
|
# self.checkPlayerExists(player)
|
||||||
|
# except FpdbParseError, e:
|
||||||
|
# print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
# return
|
||||||
#
|
#
|
||||||
# For stud games we just need to do the routine setting of shown/mucked/etc
|
# if dealt:
|
||||||
# and then update the cards 'THIRD' and 'SEVENTH'
|
# self.dealt.add(player)
|
||||||
logging.debug("addHoleCards %s %s" % (cards, player))
|
# if shown:
|
||||||
try:
|
# self.shown.add(player)
|
||||||
self.checkPlayerExists(player)
|
# if mucked:
|
||||||
except FpdbParseError, e:
|
# self.mucked.add(player)
|
||||||
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
# if player == self.hero:
|
||||||
return
|
# if len(cards) > 2:
|
||||||
|
# self.holecards['THIRD'][player] = ([cards[0:3]], [])
|
||||||
if dealt:
|
# if len(cards) > 6:
|
||||||
self.dealt.add(player)
|
# self.holecards['SEVENTH'][player] = ([cards[6]], [])
|
||||||
if shown:
|
# else:
|
||||||
self.shown.add(player)
|
# if len(cards) > 2:
|
||||||
if mucked:
|
# self.holecards['THIRD'][player] = ([cards[0]], cards[1:3])
|
||||||
self.mucked.add(player)
|
# if len(cards) > 6:
|
||||||
if player == self.hero:
|
# self.holecards['SEVENTH'][player] = ([], [cards[6]])
|
||||||
if len(cards) > 2:
|
|
||||||
self.holecards['THIRD'][player] = ([cards[0:3]], [])
|
|
||||||
if len(cards) > 6:
|
|
||||||
self.holecards['SEVENTH'][player] = ([cards[6]], [])
|
|
||||||
else:
|
|
||||||
if len(cards) > 2:
|
|
||||||
self.holecards['THIRD'][player] = ([cards[0]], cards[1:3])
|
|
||||||
if len(cards) > 6:
|
|
||||||
self.holecards['SEVENTH'][player] = ([], [cards[6]])
|
|
||||||
|
|
||||||
# TODO: def addComplete(self, player, amount):
|
# TODO: def addComplete(self, player, amount):
|
||||||
def addComplete(self, street, player, amountTo):
|
def addComplete(self, street, player, amountTo):
|
||||||
# assert street=='THIRD'
|
# assert street=='THIRD'
|
||||||
|
@ -1087,8 +1188,15 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
def writeHand(self, fh=sys.__stdout__):
|
def writeHand(self, fh=sys.__stdout__):
|
||||||
# PokerStars format.
|
# PokerStars format.
|
||||||
# print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
|
# print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
|
||||||
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
|
||||||
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
# TODO:
|
||||||
|
# Hole cards are not currently correctly written. Currently the down cards for non-heros
|
||||||
|
# are shown in the "dealt to" lines. They should be hidden in those lines. I tried to fix
|
||||||
|
# but mind got boggled, will try again.
|
||||||
|
# print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
||||||
|
print >>fh, self.writeGameLine()
|
||||||
|
print >>fh, self.writeTableLine()
|
||||||
|
# print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||||
|
|
||||||
players_who_post_antes = set([x[0] for x in self.actions['ANTES']])
|
players_who_post_antes = set([x[0] for x in self.actions['ANTES']])
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
|
# TODO: straighten out discards for draw games
|
||||||
import sys
|
import sys
|
||||||
from HandHistoryConverter import *
|
from HandHistoryConverter import *
|
||||||
|
|
||||||
|
@ -25,16 +26,35 @@ from HandHistoryConverter import *
|
||||||
|
|
||||||
class PokerStars(HandHistoryConverter):
|
class PokerStars(HandHistoryConverter):
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# Class Variables
|
||||||
|
|
||||||
# Static regexes
|
# Static regexes
|
||||||
re_GameInfo = re.compile("PokerStars Game #(?P<HID>[0-9]+):\s+(?P<MIXED>HORSE|8\-Game|HOSE)? \(?(?P<GAME>Hold\'em|Razz|7 Card Stud|7 Card Stud Hi/Lo|Omaha|Omaha Hi/Lo|Badugi) (?P<LIMIT>No Limit|Limit|Pot Limit),? \(?(?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)\) - (?P<DATETIME>.*$)", re.MULTILINE)
|
re_GameInfo = re.compile("""PokerStars\sGame\s\#(?P<HID>[0-9]+):\s+
|
||||||
|
(Tournament\s\#(?P<TOURNO>\d+),\s(?P<BUYIN>[\$\+\d\.]+)\s)?
|
||||||
|
(?P<MIXED>HORSE|8\-Game|HOSE)?\s?\(?
|
||||||
|
(?P<GAME>Hold\'em|Razz|7\sCard Stud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball)\s
|
||||||
|
(?P<LIMIT>No\sLimit|Limit|Pot\sLimit),?\s
|
||||||
|
(-\sLevel\s(?P<LEVEL>[IVXLC]+)\s)?\(?
|
||||||
|
(?P<CURRENCY>\$|)?
|
||||||
|
(?P<SB>[.0-9]+)/\$?
|
||||||
|
(?P<BB>[.0-9]+)\)\s-\s
|
||||||
|
(?P<DATETIME>.*$)""",
|
||||||
|
re.MULTILINE|re.VERBOSE)
|
||||||
re_SplitHands = re.compile('\n\n+')
|
re_SplitHands = re.compile('\n\n+')
|
||||||
re_TailSplitHands = re.compile('(\n\n\n+)')
|
re_TailSplitHands = re.compile('(\n\n\n+)')
|
||||||
re_HandInfo = re.compile("^Table \'(?P<TABLE>[- a-zA-Z]+)\'(?P<TABLEATTRIBUTES>.+?$)?", re.MULTILINE)
|
re_HandInfo = re.compile("""^Table\s\'(?P<TABLE>[-\ a-zA-Z\d]+)\'\s
|
||||||
|
((?P<MAX>\d+)-max\s)?
|
||||||
|
(?P<PLAY>\(Play\sMoney\)\s)?
|
||||||
|
(Seat\s\#(?P<BUTTON>\d+)\sis\sthe\sbutton)?""",
|
||||||
|
re.MULTILINE|re.VERBOSE)
|
||||||
re_Button = re.compile('Seat #(?P<BUTTON>\d+) is the button', re.MULTILINE)
|
re_Button = re.compile('Seat #(?P<BUTTON>\d+) is the button', re.MULTILINE)
|
||||||
re_PlayerInfo = re.compile('^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\$?(?P<CASH>[.0-9]+) in chips\)', re.MULTILINE)
|
re_PlayerInfo = re.compile('^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\$?(?P<CASH>[.0-9]+) in chips\)', re.MULTILINE)
|
||||||
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
||||||
# self.re_setHandInfoRegex('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[ a-zA-Z]+) - \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) - (?P<GAMETYPE>.*) - (?P<HR>[0-9]+):(?P<MIN>[0-9]+) ET - (?P<YEAR>[0-9]+)/(?P<MON>[0-9]+)/(?P<DAY>[0-9]+)Table (?P<TABLE>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)')
|
# self.re_setHandInfoRegex('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[ a-zA-Z]+) - \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) - (?P<GAMETYPE>.*) - (?P<HR>[0-9]+):(?P<MIN>[0-9]+) ET - (?P<YEAR>[0-9]+)/(?P<MON>[0-9]+)/(?P<DAY>[0-9]+)Table (?P<TABLE>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)')
|
||||||
|
|
||||||
|
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'}
|
||||||
|
|
||||||
def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True):
|
def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True):
|
||||||
"""\
|
"""\
|
||||||
in_path (default '-' = sys.stdin)
|
in_path (default '-' = sys.stdin)
|
||||||
|
@ -53,6 +73,9 @@ follow : whether to tail -f the input"""
|
||||||
players = set([player[1] for player in hand.players])
|
players = set([player[1] for player in hand.players])
|
||||||
if not players <= self.compiledPlayers: # x <= y means 'x is subset of y'
|
if not players <= self.compiledPlayers: # x <= y means 'x is subset of y'
|
||||||
# we need to recompile the player regexs.
|
# we need to recompile the player regexs.
|
||||||
|
# TODO: should probably rename re_HeroCards and corresponding method,
|
||||||
|
# since they are used to find all cards on lines starting with "Dealt to:"
|
||||||
|
# They still identify the hero.
|
||||||
self.compiledPlayers = players
|
self.compiledPlayers = players
|
||||||
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
||||||
logging.debug("player_re: " + player_re)
|
logging.debug("player_re: " + player_re)
|
||||||
|
@ -62,9 +85,12 @@ follow : whether to tail -f the input"""
|
||||||
self.re_BringIn = re.compile(r"^%s: brings[- ]in( low|) for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_BringIn = re.compile(r"^%s: brings[- ]in( low|) for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_PostBoth = re.compile(r"^%s: posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostBoth = re.compile(r"^%s: posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_HeroCards = re.compile(r"^Dealt to %s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % player_re, re.MULTILINE)
|
self.re_HeroCards = re.compile(r"^Dealt to %s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % player_re, re.MULTILINE)
|
||||||
self.re_Action = re.compile(r"^%s:(?P<ATYPE> bets| checks| raises| calls| folds| discards| stands pat)( \$(?P<BET>[.\d]+))?( to \$(?P<BETTO>[.\d]+))?( (?P<NODISCARDED>\d) cards?( \[(?P<DISCARDED>.+?)\])?)?" % player_re, re.MULTILINE)
|
self.re_Action = re.compile(r"""^%s:(?P<ATYPE>\sbets|\schecks|\sraises|\scalls|\sfolds|\sdiscards|\sstands\spat)
|
||||||
|
(\s\$?(?P<BET>[.\d]+))?(\sto\s\$?(?P<BETTO>[.\d]+))? # the number discarded goes in <BET>
|
||||||
|
(\scards?(\s\[(?P<DISCARDED>.+?)\])?)?"""
|
||||||
|
% player_re, re.MULTILINE|re.VERBOSE)
|
||||||
self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
||||||
self.re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(\$(?P<POT>[.\d]+)\)(, mucked| with.*|)" % player_re, re.MULTILINE)
|
self.re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(\$?(?P<POT>[.\d]+)\)(, mucked| with.*|)" % player_re, re.MULTILINE)
|
||||||
self.re_sitsOut = re.compile("^%s sits out" % player_re, re.MULTILINE)
|
self.re_sitsOut = re.compile("^%s sits out" % player_re, re.MULTILINE)
|
||||||
self.re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %s (\(.*\) )?(?P<SHOWED>showed|mucked) \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE)
|
self.re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %s (\(.*\) )?(?P<SHOWED>showed|mucked) \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE)
|
||||||
|
|
||||||
|
@ -72,33 +98,46 @@ follow : whether to tail -f the input"""
|
||||||
return [["ring", "hold", "nl"],
|
return [["ring", "hold", "nl"],
|
||||||
["ring", "hold", "pl"],
|
["ring", "hold", "pl"],
|
||||||
["ring", "hold", "fl"],
|
["ring", "hold", "fl"],
|
||||||
|
|
||||||
["ring", "stud", "fl"],
|
["ring", "stud", "fl"],
|
||||||
#["ring", "draw", "fl"],
|
|
||||||
["ring", "omaha", "pl"]
|
["ring", "draw", "fl"],
|
||||||
|
|
||||||
|
["tour", "hold", "nl"],
|
||||||
|
["tour", "hold", "pl"],
|
||||||
|
["tour", "hold", "fl"],
|
||||||
|
|
||||||
|
["tour", "stud", "fl"],
|
||||||
]
|
]
|
||||||
|
|
||||||
def determineGameType(self, handText):
|
def determineGameType(self, handText):
|
||||||
info = {'type':'ring'}
|
# inspect the handText and return the gametype dict
|
||||||
|
# gametype dict is:
|
||||||
|
# {'limitType': xxx, 'base': xxx, 'category': xxx}
|
||||||
|
|
||||||
|
info = {}
|
||||||
m = self.re_GameInfo.search(handText)
|
m = self.re_GameInfo.search(handText)
|
||||||
if not m:
|
if not m:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
mg = m.groupdict()
|
mg = m.groupdict()
|
||||||
|
# translations from captured groups to fpdb info strings
|
||||||
# translations from captured groups to our info strings
|
|
||||||
limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl' }
|
limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl' }
|
||||||
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'}
|
games = { # base, category
|
||||||
games = { # base, category
|
"Hold'em" : ('hold','holdem'),
|
||||||
"Hold'em" : ('hold','holdem'),
|
'Omaha' : ('hold','omahahi'),
|
||||||
'Omaha' : ('hold','omahahi'),
|
'Omaha Hi/Lo' : ('hold','omahahilo'),
|
||||||
'Omaha Hi/Lo' : ('hold','omahahilo'),
|
'Razz' : ('stud','razz'),
|
||||||
'Razz' : ('stud','razz'),
|
'7 Card Stud' : ('stud','studhi'),
|
||||||
'7 Card Stud' : ('stud','studhi'),
|
'7 Card Stud Hi/Lo' : ('stud','studhilo'),
|
||||||
'7 Card Stud Hi/Lo' : ('stud','studhilo'),
|
'Badugi' : ('draw','badugi'),
|
||||||
'Badugi' : ('draw','badugi')
|
'Triple Draw 2-7 Lowball' : ('draw','27_3draw'),
|
||||||
}
|
}
|
||||||
currencies = { u'€':'EUR', '$':'USD', '':'T$' }
|
currencies = { u'€':'EUR', '$':'USD', '':'T$' }
|
||||||
|
# I don't think this is doing what we think. mg will always have all
|
||||||
|
# the expected keys, but the ones that didn't match in the regex will
|
||||||
|
# have a value of None. It is OK if it throws an exception when it
|
||||||
|
# runs across an unknown game or limit or whatever.
|
||||||
if 'LIMIT' in mg:
|
if 'LIMIT' in mg:
|
||||||
info['limitType'] = limits[mg['LIMIT']]
|
info['limitType'] = limits[mg['LIMIT']]
|
||||||
if 'GAME' in mg:
|
if 'GAME' in mg:
|
||||||
|
@ -109,10 +148,13 @@ follow : whether to tail -f the input"""
|
||||||
info['bb'] = mg['BB']
|
info['bb'] = mg['BB']
|
||||||
if 'CURRENCY' in mg:
|
if 'CURRENCY' in mg:
|
||||||
info['currency'] = currencies[mg['CURRENCY']]
|
info['currency'] = currencies[mg['CURRENCY']]
|
||||||
if 'MIXED' in mg and mg['MIXED'] != None:
|
|
||||||
info['mixedType'] = mixes[mg['MIXED']]
|
if 'TOURNO' in mg and mg['TOURNO'] == None:
|
||||||
|
info['type'] = 'ring'
|
||||||
|
else:
|
||||||
|
info['type'] = 'tour'
|
||||||
|
|
||||||
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
|
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
|
||||||
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,14 +163,13 @@ follow : whether to tail -f the input"""
|
||||||
m = self.re_HandInfo.search(hand.handText,re.DOTALL)
|
m = self.re_HandInfo.search(hand.handText,re.DOTALL)
|
||||||
if m:
|
if m:
|
||||||
info.update(m.groupdict())
|
info.update(m.groupdict())
|
||||||
# TODO: Be less lazy and parse maxseats from the HandInfo regex
|
# hand.maxseats = int(m2.group(1))
|
||||||
if m.group('TABLEATTRIBUTES'):
|
else:
|
||||||
m2 = re.search("\s*(\d+)-max", m.group('TABLEATTRIBUTES'))
|
pass # throw an exception here, eh?
|
||||||
hand.maxseats = int(m2.group(1))
|
|
||||||
m = self.re_GameInfo.search(hand.handText)
|
m = self.re_GameInfo.search(hand.handText)
|
||||||
if m: info.update(m.groupdict())
|
if m: info.update(m.groupdict())
|
||||||
m = self.re_Button.search(hand.handText)
|
# m = self.re_Button.search(hand.handText)
|
||||||
if m: info.update(m.groupdict())
|
# if m: info.update(m.groupdict())
|
||||||
# TODO : I rather like the idea of just having this dict as hand.info
|
# TODO : I rather like the idea of just having this dict as hand.info
|
||||||
logging.debug("readHandInfo: %s" % info)
|
logging.debug("readHandInfo: %s" % info)
|
||||||
for key in info:
|
for key in info:
|
||||||
|
@ -145,7 +186,23 @@ follow : whether to tail -f the input"""
|
||||||
hand.tablename = info[key]
|
hand.tablename = info[key]
|
||||||
if key == 'BUTTON':
|
if key == 'BUTTON':
|
||||||
hand.buttonpos = info[key]
|
hand.buttonpos = info[key]
|
||||||
|
if key == 'MAX':
|
||||||
|
hand.maxseats = int(info[key])
|
||||||
|
|
||||||
|
if key == 'MIXED':
|
||||||
|
if info[key] == None: hand.mixed = None
|
||||||
|
else: hand.mixed = self.mixes[info[key]]
|
||||||
|
|
||||||
|
if key == 'TOURNO':
|
||||||
|
hand.tourNo = info[key]
|
||||||
|
if key == 'BUYIN':
|
||||||
|
hand.buyin = info[key]
|
||||||
|
if key == 'LEVEL':
|
||||||
|
hand.level = info[key]
|
||||||
|
if key == 'PLAY' and info['PLAY'] != None:
|
||||||
|
# hand.currency = 'play' # overrides previously set value
|
||||||
|
hand.gametype['currency'] = 'play'
|
||||||
|
|
||||||
def readButton(self, hand):
|
def readButton(self, hand):
|
||||||
m = self.re_Button.search(hand.handText)
|
m = self.re_Button.search(hand.handText)
|
||||||
if m:
|
if m:
|
||||||
|
@ -213,78 +270,115 @@ follow : whether to tail -f the input"""
|
||||||
for a in self.re_PostBoth.finditer(hand.handText):
|
for a in self.re_PostBoth.finditer(hand.handText):
|
||||||
hand.addBlind(a.group('PNAME'), 'both', a.group('SBBB'))
|
hand.addBlind(a.group('PNAME'), 'both', a.group('SBBB'))
|
||||||
|
|
||||||
|
# def readHeroCards(self, hand):
|
||||||
|
# m = self.re_HeroCards.search(hand.handText)
|
||||||
|
# if(m == None):
|
||||||
|
# #Not involved in hand
|
||||||
|
# hand.involved = False
|
||||||
|
# else:
|
||||||
|
# hand.hero = m.group('PNAME')
|
||||||
|
# # "2c, qh" -> set(["2c","qc"])
|
||||||
|
# # Also works with Omaha hands.
|
||||||
|
# cards = m.group('NEWCARDS')
|
||||||
|
# cards = set(cards.split(' '))
|
||||||
|
# hand.addHoleCards(cards, m.group('PNAME'), shown=False, mucked=False, dealt=True)
|
||||||
|
|
||||||
def readHeroCards(self, hand):
|
def readHeroCards(self, hand):
|
||||||
m = self.re_HeroCards.search(hand.handText)
|
# streets PREFLOP, PREDRAW, and THIRD are special cases beacause
|
||||||
if(m == None):
|
# we need to grab hero's cards
|
||||||
#Not involved in hand
|
for street in ('PREFLOP', 'DEAL'):
|
||||||
hand.involved = False
|
if street in hand.streets.keys():
|
||||||
else:
|
m = self.re_HeroCards.finditer(hand.streets[street])
|
||||||
hand.hero = m.group('PNAME')
|
for found in m:
|
||||||
# "2c, qh" -> set(["2c","qc"])
|
# if m == None:
|
||||||
# Also works with Omaha hands.
|
# hand.involved = False
|
||||||
cards = m.group('NEWCARDS')
|
# else:
|
||||||
cards = set(cards.split(' '))
|
hand.hero = found.group('PNAME')
|
||||||
hand.addHoleCards(cards, m.group('PNAME'), shown=False, mucked=False, dealt=True)
|
newcards = found.group('NEWCARDS').split(' ')
|
||||||
|
hand.addHoleCards(street, hand.hero, closed=newcards, shown=False, mucked=False, dealt=True)
|
||||||
|
|
||||||
def readDrawCards(self, hand, street):
|
for street, text in hand.streets.iteritems():
|
||||||
logging.debug("readDrawCards")
|
if street in ('PREFLOP', 'DEAL'): continue # already done these
|
||||||
m = self.re_HeroCards.finditer(hand.streets[street])
|
m = self.re_HeroCards.finditer(hand.streets[street])
|
||||||
if m == None:
|
for found in m:
|
||||||
hand.involved = False
|
player = found.group('PNAME')
|
||||||
else:
|
if found.group('NEWCARDS') == None:
|
||||||
for player in m:
|
newcards = []
|
||||||
hand.hero = player.group('PNAME') # Only really need to do this once
|
|
||||||
newcards = player.group('NEWCARDS')
|
|
||||||
oldcards = player.group('OLDCARDS')
|
|
||||||
if newcards == None:
|
|
||||||
newcards = set()
|
|
||||||
else:
|
else:
|
||||||
newcards = set(newcards.split(' '))
|
newcards = found.group('NEWCARDS').split(' ')
|
||||||
if oldcards == None:
|
if found.group('OLDCARDS') == None:
|
||||||
oldcards = set()
|
oldcards = []
|
||||||
else:
|
else:
|
||||||
oldcards = set(oldcards.split(' '))
|
oldcards = found.group('OLDCARDS').split(' ')
|
||||||
hand.addDrawHoleCards(newcards, oldcards, player.group('PNAME'), street)
|
|
||||||
|
if street == 'THIRD' and len(newcards) == 3: # hero in stud game
|
||||||
|
hand.hero = player
|
||||||
|
hand.dealt.add(player) # need this for stud??
|
||||||
|
hand.addHoleCards(street, player, closed=newcards[0:2], open=[newcards[2]], shown=False, mucked=False, dealt=False)
|
||||||
|
else:
|
||||||
|
hand.addHoleCards(street, player, open=newcards, closed=oldcards, shown=False, mucked=False, dealt=False)
|
||||||
|
|
||||||
|
|
||||||
|
# def readDrawCards(self, hand, street):
|
||||||
|
# logging.debug("readDrawCards")
|
||||||
|
# m = self.re_HeroCards.finditer(hand.streets[street])
|
||||||
|
# if m == None:
|
||||||
|
# hand.involved = False
|
||||||
|
# else:
|
||||||
|
# for player in m:
|
||||||
|
# hand.hero = player.group('PNAME') # Only really need to do this once
|
||||||
|
# newcards = player.group('NEWCARDS')
|
||||||
|
# oldcards = player.group('OLDCARDS')
|
||||||
|
# if newcards == None:
|
||||||
|
# newcards = set()
|
||||||
|
# else:
|
||||||
|
# newcards = set(newcards.split(' '))
|
||||||
|
# if oldcards == None:
|
||||||
|
# oldcards = set()
|
||||||
|
# else:
|
||||||
|
# oldcards = set(oldcards.split(' '))
|
||||||
|
# hand.addDrawHoleCards(newcards, oldcards, player.group('PNAME'), street)
|
||||||
|
|
||||||
|
|
||||||
def readStudPlayerCards(self, hand, street):
|
# def readStudPlayerCards(self, hand, street):
|
||||||
# See comments of reference implementation in FullTiltToFpdb.py
|
# # See comments of reference implementation in FullTiltToFpdb.py
|
||||||
logging.debug("readStudPlayerCards")
|
# logging.debug("readStudPlayerCards")
|
||||||
m = self.re_HeroCards.finditer(hand.streets[street])
|
# m = self.re_HeroCards.finditer(hand.streets[street])
|
||||||
for player in m:
|
# for player in m:
|
||||||
#~ logging.debug(player.groupdict())
|
# #~ logging.debug(player.groupdict())
|
||||||
(pname, oldcards, newcards) = (player.group('PNAME'), player.group('OLDCARDS'), player.group('NEWCARDS'))
|
# (pname, oldcards, newcards) = (player.group('PNAME'), player.group('OLDCARDS'), player.group('NEWCARDS'))
|
||||||
if oldcards:
|
# if oldcards:
|
||||||
oldcards = [c.strip() for c in oldcards.split(' ')]
|
# oldcards = [c.strip() for c in oldcards.split(' ')]
|
||||||
if newcards:
|
# if newcards:
|
||||||
newcards = [c.strip() for c in newcards.split(' ')]
|
# newcards = [c.strip() for c in newcards.split(' ')]
|
||||||
if street=='ANTES':
|
# if street=='ANTES':
|
||||||
return
|
# return
|
||||||
elif street=='THIRD':
|
# elif street=='THIRD':
|
||||||
# we'll have observed hero holecards in CARDS and thirdstreet open cards in 'NEWCARDS'
|
# # we'll have observed hero holecards in CARDS and thirdstreet open cards in 'NEWCARDS'
|
||||||
# hero: [xx][o]
|
# # hero: [xx][o]
|
||||||
# others: [o]
|
# # others: [o]
|
||||||
hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = oldcards, open = newcards)
|
# hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = oldcards, open = newcards)
|
||||||
elif street in ('FOURTH', 'FIFTH', 'SIXTH'):
|
# elif street in ('FOURTH', 'FIFTH', 'SIXTH'):
|
||||||
# 4th:
|
# # 4th:
|
||||||
# hero: [xxo] [o]
|
# # hero: [xxo] [o]
|
||||||
# others: [o] [o]
|
# # others: [o] [o]
|
||||||
# 5th:
|
# # 5th:
|
||||||
# hero: [xxoo] [o]
|
# # hero: [xxoo] [o]
|
||||||
# others: [oo] [o]
|
# # others: [oo] [o]
|
||||||
# 6th:
|
# # 6th:
|
||||||
# hero: [xxooo] [o]
|
# # hero: [xxooo] [o]
|
||||||
# others: [ooo] [o]
|
# # others: [ooo] [o]
|
||||||
hand.addPlayerCards(player = player.group('PNAME'), street = street, open = newcards)
|
# hand.addPlayerCards(player = player.group('PNAME'), street = street, open = newcards)
|
||||||
# we may additionally want to check the earlier streets tally with what we have but lets trust it for now.
|
# # we may additionally want to check the earlier streets tally with what we have but lets trust it for now.
|
||||||
elif street=='SEVENTH' and newcards:
|
# elif street=='SEVENTH' and newcards:
|
||||||
# hero: [xxoooo] [x]
|
# # hero: [xxoooo] [x]
|
||||||
# others: not reported.
|
# # others: not reported.
|
||||||
hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = newcards)
|
# hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = newcards)
|
||||||
|
|
||||||
def readAction(self, hand, street):
|
def readAction(self, hand, street):
|
||||||
m = self.re_Action.finditer(hand.streets[street])
|
m = self.re_Action.finditer(hand.streets[street])
|
||||||
for action in m:
|
for action in m:
|
||||||
|
acts = action.groupdict()
|
||||||
if action.group('ATYPE') == ' raises':
|
if action.group('ATYPE') == ' raises':
|
||||||
hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') )
|
hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') )
|
||||||
elif action.group('ATYPE') == ' calls':
|
elif action.group('ATYPE') == ' calls':
|
||||||
|
@ -296,7 +390,7 @@ follow : whether to tail -f the input"""
|
||||||
elif action.group('ATYPE') == ' checks':
|
elif action.group('ATYPE') == ' checks':
|
||||||
hand.addCheck( street, action.group('PNAME'))
|
hand.addCheck( street, action.group('PNAME'))
|
||||||
elif action.group('ATYPE') == ' discards':
|
elif action.group('ATYPE') == ' discards':
|
||||||
hand.addDiscard(street, action.group('PNAME'), action.group('NODISCARDED'), action.group('DISCARDED'))
|
hand.addDiscard(street, action.group('PNAME'), action.group('BET'), action.group('DISCARDED'))
|
||||||
elif action.group('ATYPE') == ' stands pat':
|
elif action.group('ATYPE') == ' stands pat':
|
||||||
hand.addStandsPat( street, action.group('PNAME'))
|
hand.addStandsPat( street, action.group('PNAME'))
|
||||||
else:
|
else:
|
||||||
|
@ -304,9 +398,9 @@ follow : whether to tail -f the input"""
|
||||||
|
|
||||||
|
|
||||||
def readShowdownActions(self, hand):
|
def readShowdownActions(self, hand):
|
||||||
|
# TODO: pick up mucks also
|
||||||
for shows in self.re_ShowdownAction.finditer(hand.handText):
|
for shows in self.re_ShowdownAction.finditer(hand.handText):
|
||||||
cards = shows.group('CARDS')
|
cards = shows.group('CARDS').split(' ')
|
||||||
cards = set(cards.split(' '))
|
|
||||||
hand.addShownCards(cards, shows.group('PNAME'))
|
hand.addShownCards(cards, shows.group('PNAME'))
|
||||||
|
|
||||||
def readCollectPot(self,hand):
|
def readCollectPot(self,hand):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user