Party hhc: fixes and refactoring
This commit is contained in:
parent
3d227a42cd
commit
dc3c721884
|
@ -21,24 +21,23 @@
|
||||||
import sys
|
import sys
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
from Exceptions import FpdbParseError
|
||||||
from HandHistoryConverter import *
|
from HandHistoryConverter import *
|
||||||
|
|
||||||
# PartyPoker HH Format
|
# PartyPoker HH Format
|
||||||
|
|
||||||
|
class PartyPokerParseError(FpdbParseError):
|
||||||
|
"Usage: raise PartyPokerParseError(<msg>[, hh=<hh>][, hid=<hid>])"
|
||||||
|
def __init__(self, msg='', hh=None, hid=None):
|
||||||
|
if hh is not None:
|
||||||
|
msg += "\n\nHand history attached below:\n" + self.wrapHh(hh)
|
||||||
|
return super(PartyPokerParseError, self).__init__(hid=hid)
|
||||||
|
#return super(PartyPokerParseError, self).__init__(msg, hid=hid)
|
||||||
|
def wrapHh(self, hh):
|
||||||
|
return ("%(DELIMETER)s\n%(HH)s\n%(DELIMETER)s") % \
|
||||||
|
{'DELIMETER': '#'*50, 'HH': hh}
|
||||||
|
|
||||||
class PartyPoker(HandHistoryConverter):
|
class PartyPoker(HandHistoryConverter):
|
||||||
class ParsingException(Exception):
|
|
||||||
"Usage: raise ParsingException(<msg>[, hh=<hh>])"
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
if len(args)==0: args=[''] + list(args)
|
|
||||||
msg, args = args[0], args[1:]
|
|
||||||
if 'hh' in kwargs:
|
|
||||||
msg += self.wrapHh(kwargs['hh'])
|
|
||||||
del kwargs['hh']
|
|
||||||
return Exception.__init__(self, msg, *args, **kwargs)
|
|
||||||
def wrapHh(self, hh):
|
|
||||||
return ("\n\nHand history attached below:\n"
|
|
||||||
"%(DELIMETER)s\n%(HH)s\n%(DELIMETER)s") % \
|
|
||||||
{'DELIMETER': '#'*50, 'HH': hh}
|
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
# Class Variables
|
# Class Variables
|
||||||
|
@ -116,6 +115,7 @@ class PartyPoker(HandHistoryConverter):
|
||||||
if mo == 10: return mo
|
if mo == 10: return mo
|
||||||
if mo == 2: return 2
|
if mo == 2: return 2
|
||||||
if mo <= 6: return 6
|
if mo <= 6: return 6
|
||||||
|
# there are 9-max tables for cash and 10-max for tournaments
|
||||||
return 9 if hand.gametype['type']=='ring' else 10
|
return 9 if hand.gametype['type']=='ring' else 10
|
||||||
|
|
||||||
def compilePlayerRegexs(self, hand):
|
def compilePlayerRegexs(self, hand):
|
||||||
|
@ -152,7 +152,7 @@ class PartyPoker(HandHistoryConverter):
|
||||||
r"\[ *(?P<CARDS>.+) *\](?P<COMBINATION>.+)\.",
|
r"\[ *(?P<CARDS>.+) *\](?P<COMBINATION>.+)\.",
|
||||||
re.MULTILINE)
|
re.MULTILINE)
|
||||||
self.re_CollectPot = re.compile(
|
self.re_CollectPot = re.compile(
|
||||||
r""""^%(PLYR)s \s+ wins \s+
|
r"""^%(PLYR)s \s+ wins \s+
|
||||||
%(CUR_SYM)s(?P<POT>[.\d]+)\s*%(CUR)s""" % subst,
|
%(CUR_SYM)s(?P<POT>[.\d]+)\s*%(CUR)s""" % subst,
|
||||||
re.MULTILINE|re.VERBOSE)
|
re.MULTILINE|re.VERBOSE)
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ class PartyPoker(HandHistoryConverter):
|
||||||
gametype dict is:
|
gametype dict is:
|
||||||
{'limitType': xxx, 'base': xxx, 'category': xxx}"""
|
{'limitType': xxx, 'base': xxx, 'category': xxx}"""
|
||||||
|
|
||||||
log.debug(self.ParsingException().wrapHh( handText ))
|
log.debug(PartyPokerParseError().wrapHh( handText ))
|
||||||
|
|
||||||
info = {}
|
info = {}
|
||||||
m = self._getGameType(handText)
|
m = self._getGameType(handText)
|
||||||
|
@ -205,20 +205,20 @@ class PartyPoker(HandHistoryConverter):
|
||||||
|
|
||||||
for expectedField in ['LIMIT', 'GAME']:
|
for expectedField in ['LIMIT', 'GAME']:
|
||||||
if mg[expectedField] is None:
|
if mg[expectedField] is None:
|
||||||
raise self.ParsingException(
|
raise PartyPokerParseError(
|
||||||
"Cannot fetch field '%s'" % expectedField,
|
"Cannot fetch field '%s'" % expectedField,
|
||||||
hh = handText)
|
hh = handText)
|
||||||
try:
|
try:
|
||||||
info['limitType'] = limits[mg['LIMIT'].strip()]
|
info['limitType'] = limits[mg['LIMIT'].strip()]
|
||||||
except:
|
except:
|
||||||
raise self.ParsingException(
|
raise PartyPokerParseError(
|
||||||
"Unknown limit '%s'" % mg['LIMIT'],
|
"Unknown limit '%s'" % mg['LIMIT'],
|
||||||
hh = handText)
|
hh = handText)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
(info['base'], info['category']) = games[mg['GAME']]
|
(info['base'], info['category']) = games[mg['GAME']]
|
||||||
except:
|
except:
|
||||||
raise self.ParsingException(
|
raise PartyPokerParseError(
|
||||||
"Unknown game type '%s'" % mg['GAME'],
|
"Unknown game type '%s'" % mg['GAME'],
|
||||||
hh = handText)
|
hh = handText)
|
||||||
|
|
||||||
|
@ -231,6 +231,7 @@ class PartyPoker(HandHistoryConverter):
|
||||||
if info['type'] == 'ring':
|
if info['type'] == 'ring':
|
||||||
info['sb'], info['bb'] = ringBlinds(mg['RINGLIMIT'])
|
info['sb'], info['bb'] = ringBlinds(mg['RINGLIMIT'])
|
||||||
# FIXME: there are only $ and play money availible for cash
|
# FIXME: there are only $ and play money availible for cash
|
||||||
|
# to be honest, party doesn't save play money hh
|
||||||
info['currency'] = currencies[mg['CURRENCY']]
|
info['currency'] = currencies[mg['CURRENCY']]
|
||||||
else:
|
else:
|
||||||
info['sb'] = clearMoneyString(mg['SB'])
|
info['sb'] = clearMoneyString(mg['SB'])
|
||||||
|
@ -243,21 +244,27 @@ class PartyPoker(HandHistoryConverter):
|
||||||
|
|
||||||
def readHandInfo(self, hand):
|
def readHandInfo(self, hand):
|
||||||
info = {}
|
info = {}
|
||||||
m = self.re_HandInfo.search(hand.handText,re.DOTALL)
|
try:
|
||||||
if m:
|
info.update(self.re_Hid.search(hand.handText).groupdict())
|
||||||
info.update(m.groupdict())
|
except:
|
||||||
else:
|
raise PartyPokerParseError("Cannot read HID for current hand", hh=hand.handText)
|
||||||
raise self.ParsingException("Cannot read Handinfo for current hand", hh=hand.handText)
|
|
||||||
m = self._getGameType(hand.handText)
|
try:
|
||||||
if m: info.update(m.groupdict())
|
info.update(self.re_HandInfo.search(hand.handText,re.DOTALL).groupdict())
|
||||||
m = self.re_Hid.search(hand.handText)
|
except:
|
||||||
if m: info.update(m.groupdict())
|
raise PartyPokerParseError("Cannot read Handinfo for current hand",
|
||||||
|
hh=hand.handText, hid = info['HID'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
info.update(self._getGameType(hand.handText).groupdict())
|
||||||
|
except:
|
||||||
|
raise PartyPokerParseError("Cannot read GameType for current hand",
|
||||||
|
hh=hand.handText, hid = info['HID'])
|
||||||
|
|
||||||
|
|
||||||
m = self.re_TotalPlayers.search(hand.handText)
|
m = self.re_TotalPlayers.search(hand.handText)
|
||||||
if m: info.update(m.groupdict())
|
if m: info.update(m.groupdict())
|
||||||
|
|
||||||
# FIXME: it's a hack cause party doesn't supply hand.maxseats info
|
|
||||||
#hand.maxseats = ???
|
|
||||||
hand.mixed = None
|
hand.mixed = None
|
||||||
|
|
||||||
log.debug("readHandInfo: %s" % info)
|
log.debug("readHandInfo: %s" % info)
|
||||||
|
@ -285,16 +292,14 @@ class PartyPoker(HandHistoryConverter):
|
||||||
if key == 'TOURNO':
|
if key == 'TOURNO':
|
||||||
hand.tourNo = info[key]
|
hand.tourNo = info[key]
|
||||||
if key == 'BUYIN':
|
if key == 'BUYIN':
|
||||||
#FIXME: it's dirty hack T_T
|
# FIXME: it's dirty hack T_T
|
||||||
|
# code below assumes that rake is equal to zero
|
||||||
cur = info[key][0] if info[key][0] not in '0123456789' else ''
|
cur = info[key][0] if info[key][0] not in '0123456789' else ''
|
||||||
hand.buyin = info[key] + '+%s0' % cur
|
hand.buyin = info[key] + '+%s0' % cur
|
||||||
#if key == 'MAXSEATS':
|
|
||||||
#hand.maxseats = int(info[key])
|
|
||||||
if key == 'LEVEL':
|
if key == 'LEVEL':
|
||||||
hand.level = info[key]
|
hand.level = info[key]
|
||||||
if key == 'PLAY' and info['PLAY'] != 'Real':
|
if key == 'PLAY' and info['PLAY'] != 'Real':
|
||||||
# TODO: play money wasn't tested
|
# if realy there's no play money hh on party
|
||||||
# hand.currency = 'play' # overrides previously set value
|
|
||||||
hand.gametype['currency'] = 'play'
|
hand.gametype['currency'] = 'play'
|
||||||
|
|
||||||
def readButton(self, hand):
|
def readButton(self, hand):
|
||||||
|
@ -313,10 +318,6 @@ class PartyPoker(HandHistoryConverter):
|
||||||
clearMoneyString(a.group('CASH')))
|
clearMoneyString(a.group('CASH')))
|
||||||
|
|
||||||
def markStreets(self, hand):
|
def markStreets(self, hand):
|
||||||
# PREFLOP = ** Dealing down cards **
|
|
||||||
# This re fails if, say, river is missing; then we don't get the ** that starts the river.
|
|
||||||
assert hand.gametype['base'] == "hold", \
|
|
||||||
"wtf! There're no %s games on party" % hand.gametype['base']
|
|
||||||
m = re.search(
|
m = re.search(
|
||||||
r"\*{2} Dealing down cards \*{2}"
|
r"\*{2} Dealing down cards \*{2}"
|
||||||
r"(?P<PREFLOP>.+?)"
|
r"(?P<PREFLOP>.+?)"
|
||||||
|
@ -337,11 +338,6 @@ class PartyPoker(HandHistoryConverter):
|
||||||
for player in m:
|
for player in m:
|
||||||
hand.addAnte(player.group('PNAME'), player.group('ANTE'))
|
hand.addAnte(player.group('PNAME'), player.group('ANTE'))
|
||||||
|
|
||||||
def readBringIn(self, hand):
|
|
||||||
m = self.re_BringIn.search(hand.handText,re.DOTALL)
|
|
||||||
if m:
|
|
||||||
hand.addBringIn(m.group('PNAME'), m.group('BRINGIN'))
|
|
||||||
|
|
||||||
def readBlinds(self, hand):
|
def readBlinds(self, hand):
|
||||||
noSmallBlind = bool(self.re_NoSmallBlind.search(hand.handText))
|
noSmallBlind = bool(self.re_NoSmallBlind.search(hand.handText))
|
||||||
if hand.gametype['type'] == 'ring':
|
if hand.gametype['type'] == 'ring':
|
||||||
|
@ -381,7 +377,7 @@ class PartyPoker(HandHistoryConverter):
|
||||||
|
|
||||||
bigBlindSeat = findFirstNonEmptySeat(smallBlindSeat + 1)
|
bigBlindSeat = findFirstNonEmptySeat(smallBlindSeat + 1)
|
||||||
blind = smartMin(hand.bb, playersMap[bigBlindSeat][1])
|
blind = smartMin(hand.bb, playersMap[bigBlindSeat][1])
|
||||||
hand.addBlind(playersMap[bigBlindSeat][0], 'small blind', blind)
|
hand.addBlind(playersMap[bigBlindSeat][0], 'big blind', blind)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -400,18 +396,39 @@ class PartyPoker(HandHistoryConverter):
|
||||||
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()
|
acts = action.groupdict()
|
||||||
if action.group('ATYPE') in ('raises','is all-In'):
|
playerName = action.group('PNAME')
|
||||||
hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') )
|
amount = clearMoneyString(action.group('BET')) if action.group('BET') else None
|
||||||
elif action.group('ATYPE') == 'calls':
|
actionType = action.group('ATYPE')
|
||||||
hand.addCall( street, action.group('PNAME'), action.group('BET') )
|
|
||||||
elif action.group('ATYPE') == 'bets':
|
if actionType == 'is all-In':
|
||||||
hand.addBet( street, action.group('PNAME'), action.group('BET') )
|
# party's allin can mean either raise or bet or call
|
||||||
elif action.group('ATYPE') == 'folds':
|
Bp = hand.lastBet[street]
|
||||||
hand.addFold( street, action.group('PNAME'))
|
if Bp == 0:
|
||||||
elif action.group('ATYPE') == 'checks':
|
actionType = 'bets'
|
||||||
hand.addCheck( street, action.group('PNAME'))
|
elif Bp < Decimal(amount):
|
||||||
|
actionType = 'raises'
|
||||||
|
else:
|
||||||
|
actionType = 'calls'
|
||||||
|
|
||||||
|
if actionType == 'raises':
|
||||||
|
if street == 'PREFLOP' and \
|
||||||
|
playerName in [item[0] for item in hand.actions['BLINDSANTES']]:
|
||||||
|
# preflop raise from blind
|
||||||
|
hand.addRaiseBy( street, playerName, amount )
|
||||||
|
else:
|
||||||
|
hand.addCallandRaise( street, playerName, amount )
|
||||||
|
elif actionType == 'calls':
|
||||||
|
hand.addCall( street, playerName, amount )
|
||||||
|
elif actionType == 'bets':
|
||||||
|
hand.addBet( street, playerName, amount )
|
||||||
|
elif actionType == 'folds':
|
||||||
|
hand.addFold( street, playerName )
|
||||||
|
elif actionType == 'checks':
|
||||||
|
hand.addCheck( street, playerName )
|
||||||
else:
|
else:
|
||||||
print "DEBUG: unimplemented readAction: '%s' '%s'" %(action.group('PNAME'),action.group('ATYPE'),)
|
raise PartyPokerParseError(
|
||||||
|
"Unimplemented readAction: '%s' '%s'" % (playerName,actionType,),
|
||||||
|
hid = hand.hid, hh = hand.handText )
|
||||||
|
|
||||||
|
|
||||||
def readShowdownActions(self, hand):
|
def readShowdownActions(self, hand):
|
||||||
|
@ -434,17 +451,17 @@ class PartyPoker(HandHistoryConverter):
|
||||||
hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked)
|
hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked)
|
||||||
|
|
||||||
def ringBlinds(ringLimit):
|
def ringBlinds(ringLimit):
|
||||||
"Returns blinds for current limit"
|
"Returns blinds for current limit in cash games"
|
||||||
ringLimit = float(clearMoneyString(ringLimit))
|
ringLimit = float(clearMoneyString(ringLimit))
|
||||||
if ringLimit == 5.: ringLimit = 4.
|
if ringLimit == 5.: ringLimit = 4.
|
||||||
return ('%.2f' % (ringLimit/200.), '%.2f' % (ringLimit/100.) )
|
return ('%.2f' % (ringLimit/200.), '%.2f' % (ringLimit/100.) )
|
||||||
|
|
||||||
def clearMoneyString(money):
|
def clearMoneyString(money):
|
||||||
"renders 'numbers' like '1 200' and '2,000'"
|
"Renders 'numbers' like '1 200' and '2,000'"
|
||||||
return money.replace(' ', '').replace(',', '')
|
return money.replace(' ', '').replace(',', '')
|
||||||
|
|
||||||
def renderCards(string):
|
def renderCards(string):
|
||||||
"splits strings like ' Js, 4d '"
|
"Splits strings like ' Js, 4d '"
|
||||||
cards = string.strip().split(' ')
|
cards = string.strip().split(' ')
|
||||||
return filter(len, map(lambda x: x.strip(' ,'), cards))
|
return filter(len, map(lambda x: x.strip(' ,'), cards))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user