Merge branch 'exp'
Conflicts: pyfpdb/Hand.py
This commit is contained in:
commit
fb02d9224b
|
@ -75,6 +75,7 @@ class Everleaf(HandHistoryConverter):
|
|||
self.rexx.setPlayerInfoRegex('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\s+(\$ (?P<CASH>[.0-9]+) USD|new player|All-in) \)')
|
||||
self.rexx.setPostSbRegex('.*\n(?P<PNAME>.*): posts small blind \[\$? (?P<SB>[.0-9]+)')
|
||||
self.rexx.setPostBbRegex('.*\n(?P<PNAME>.*): posts big blind \[\$? (?P<BB>[.0-9]+)')
|
||||
self.rexx.setPostBothRegex('.*\n(?P<PNAME>.*): posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)')
|
||||
# mct : what about posting small & big blinds simultaneously?
|
||||
self.rexx.setHeroCardsRegex('.*\nDealt\sto\s(?P<PNAME>.*)\s\[ (?P<HOLE1>\S\S), (?P<HOLE2>\S\S) \]')
|
||||
self.rexx.setActionStepRegex('.*\n(?P<PNAME>.*)(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[\$ (?P<BET>[.\d]+) USD\])?')
|
||||
|
@ -131,7 +132,8 @@ class Everleaf(HandHistoryConverter):
|
|||
r"(\*\* Dealing Turn \*\* \[ \S\S \](?P<TURN>.+(?=\*\* Dealing River \*\*)|.+))?"
|
||||
r"(\*\* Dealing River \*\* \[ \S\S \](?P<RIVER>.+))?", hand.string,re.DOTALL)
|
||||
|
||||
hand.streets = m
|
||||
hand.addStreets(m)
|
||||
|
||||
|
||||
def readCommunityCards(self, hand):
|
||||
# currently regex in wrong place pls fix my brain's fried
|
||||
|
@ -146,15 +148,13 @@ class Everleaf(HandHistoryConverter):
|
|||
def readBlinds(self, hand):
|
||||
try:
|
||||
m = self.rexx.small_blind_re.search(hand.string)
|
||||
hand.addBlind(m.group('PNAME'), m.group('SB'))
|
||||
#hand.posted = [m.group('PNAME')]
|
||||
except:
|
||||
hand.addBlind(None, 0)
|
||||
#hand.posted = ["FpdbNBP"]
|
||||
m = self.rexx.big_blind_re.finditer(hand.string)
|
||||
for a in m:
|
||||
hand.addBlind(a.group('PNAME'), a.group('BB'))
|
||||
#hand.posted = hand.posted + [a.group('PNAME')]
|
||||
hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB'))
|
||||
except: # no small blind
|
||||
hand.addBlind(None, None, None)
|
||||
for a in self.rexx.big_blind_re.finditer(hand.string):
|
||||
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
|
||||
for a in self.rexx.both_blinds_re.finditer(hand.string):
|
||||
hand.addBlind(a.group('PNAME'), 'small & big blinds', a.group('SBBB'))
|
||||
|
||||
def readHeroCards(self, hand):
|
||||
m = self.rexx.hero_cards_re.search(hand.string)
|
||||
|
@ -167,7 +167,6 @@ class Everleaf(HandHistoryConverter):
|
|||
|
||||
def readAction(self, hand, street):
|
||||
m = self.rexx.action_re.finditer(hand.streets.group(street))
|
||||
hand.actions[street] = []
|
||||
for action in m:
|
||||
if action.group('ATYPE') == ' raises':
|
||||
hand.addRaiseTo( street, action.group('PNAME'), action.group('BET') )
|
||||
|
@ -182,6 +181,7 @@ class Everleaf(HandHistoryConverter):
|
|||
else:
|
||||
print "DEBUG: unimplemented readAction: %s %s" %(action.group('PNAME'),action.group('ATYPE'),)
|
||||
#hand.actions[street] += [[action.group('PNAME'), action.group('ATYPE')]]
|
||||
# TODO: Everleaf does not record uncalled bets.
|
||||
|
||||
|
||||
def readShowdownActions(self, hand):
|
||||
|
@ -193,18 +193,13 @@ class Everleaf(HandHistoryConverter):
|
|||
hand.addShownCards(cards, shows.group('PNAME'))
|
||||
|
||||
def readCollectPot(self,hand):
|
||||
m = self.rexx.collect_pot_re.search(hand.string)
|
||||
if m is not None:
|
||||
for m in self.rexx.collect_pot_re.finditer(hand.string):
|
||||
if m.group('HAND') is not None:
|
||||
re_card = re.compile('(?P<CARD>[0-9tjqka][schd])') # copied from earlier
|
||||
cards = set([hand.card(card.group('CARD')) for card in re_card.finditer(m.group('HAND'))])
|
||||
hand.addShownCards(cards=None, player=m.group('PNAME'), holeandboard=cards)
|
||||
hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT'))
|
||||
else:
|
||||
print "WARNING: Unusual, no one collected; can happen if it's folded to big blind with a dead small blind."
|
||||
|
||||
def getRake(self, hand):
|
||||
hand.rake = hand.totalpot * Decimal('0.05') # probably not quite right
|
||||
|
||||
if __name__ == "__main__":
|
||||
c = Configuration.Config()
|
||||
|
|
|
@ -87,6 +87,8 @@ class Hand:
|
|||
|
||||
self.action = []
|
||||
self.totalpot = None
|
||||
self.totalcollected = None
|
||||
|
||||
self.rake = None
|
||||
|
||||
self.bets = {}
|
||||
|
@ -109,6 +111,17 @@ If a player has None chips he won't be added."""
|
|||
self.bets[street][name] = []
|
||||
|
||||
|
||||
def addStreets(self, match):
|
||||
# go through m and initialise actions to empty list for each street.
|
||||
if match is not None:
|
||||
self.streets = match
|
||||
for street in match.groupdict():
|
||||
if match.group(street) is not None:
|
||||
self.actions[street] = []
|
||||
|
||||
else:
|
||||
print "empty markStreets match" # better to raise exception and put process hand in a try block
|
||||
|
||||
def addHoleCards(self, cards, player):
|
||||
"""\
|
||||
Assigns observed holecards to a player.
|
||||
|
@ -161,11 +174,16 @@ For when a player shows cards for any reason (for showdown or out of choice).
|
|||
c = c.replace(k,v)
|
||||
return c
|
||||
|
||||
def addBlind(self, player, amount):
|
||||
def addBlind(self, player, blindtype, amount):
|
||||
# if player is None, it's a missing small blind.
|
||||
if player is not None:
|
||||
self.bets['PREFLOP'][player].append(Decimal(amount))
|
||||
self.actions['PREFLOP'] += [(player, 'posts', blindtype, amount)]
|
||||
if blindtype == 'big blind':
|
||||
self.lastBet['PREFLOP'] = Decimal(amount)
|
||||
elif blindtype == 'small & big blinds':
|
||||
# extra small blind is 'dead'
|
||||
self.lastBet['PREFLOP'] = Decimal(self.bb)
|
||||
self.posted += [player]
|
||||
|
||||
|
||||
|
@ -175,7 +193,7 @@ For when a player shows cards for any reason (for showdown or out of choice).
|
|||
if amount is not None:
|
||||
self.bets[street][player].append(Decimal(amount))
|
||||
#self.lastBet[street] = Decimal(amount)
|
||||
self.actions[street] += [[player, 'calls', amount]]
|
||||
self.actions[street] += [(player, 'calls', amount)]
|
||||
|
||||
def addRaiseTo(self, street, player, amountTo):
|
||||
"""\
|
||||
|
@ -192,21 +210,22 @@ Add a raise on [street] by [player] to [amountTo]
|
|||
self.lastBet[street] = Decimal(amountTo)
|
||||
amountBy = Decimal(amountTo) - amountToCall
|
||||
self.bets[street][player].append(amountBy+amountToCall)
|
||||
self.actions[street] += [[player, 'raises', amountBy, amountTo]]
|
||||
self.actions[street] += [(player, 'raises', amountBy, amountTo, amountToCall)]
|
||||
|
||||
def addBet(self, street, player, amount):
|
||||
self.checkPlayerExists(player)
|
||||
self.bets[street][player].append(Decimal(amount))
|
||||
self.actions[street] += [[player, 'bets', amount]]
|
||||
self.actions[street] += [(player, 'bets', amount)]
|
||||
self.lastBet[street] = Decimal(amount)
|
||||
|
||||
def addFold(self, street, player):
|
||||
self.checkPlayerExists(player)
|
||||
self.folded.add(player)
|
||||
self.actions[street] += [[player, 'folds']]
|
||||
self.actions[street] += [(player, 'folds')]
|
||||
|
||||
def addCheck(self, street, player):
|
||||
self.checkPlayerExists(player)
|
||||
self.actions[street] += [[player, 'checks']]
|
||||
self.actions[street] += [(player, 'checks')]
|
||||
|
||||
def addCollectPot(self,player, pot):
|
||||
self.checkPlayerExists(player)
|
||||
|
@ -231,6 +250,51 @@ Known bug: doesn't take into account side pots"""
|
|||
#print street, self.bets[street][player]
|
||||
self.totalpot += reduce(operator.add, self.bets[street][player], 0)
|
||||
|
||||
print "conventional totalpot:", self.totalpot
|
||||
self.totalpot = 0
|
||||
|
||||
print self.actions
|
||||
for street in self.actions:
|
||||
uncalled = 0
|
||||
calls = [0]
|
||||
for act in self.actions[street]:
|
||||
if act[1] == 'bets': # [name, 'bets', amount]
|
||||
self.totalpot += Decimal(act[2])
|
||||
uncalled = Decimal(act[2]) # only the last bet or raise can be uncalled
|
||||
calls = [0]
|
||||
print "uncalled: ", uncalled
|
||||
elif act[1] == 'raises': # [name, 'raises', amountby, amountto, amountcalled]
|
||||
print "calls %s and raises %s to %s" % (act[4],act[2],act[3])
|
||||
self.totalpot += Decimal(act[2]) + Decimal(act[4])
|
||||
calls = [0]
|
||||
uncalled = Decimal(act[2])
|
||||
print "uncalled: ", uncalled
|
||||
elif act[1] == 'calls': # [name, 'calls', amount]
|
||||
self.totalpot += Decimal(act[2])
|
||||
calls = calls + [Decimal(act[2])]
|
||||
print "calls:", calls
|
||||
if act[1] == ('posts'):
|
||||
self.totalpot += Decimal(act[3])
|
||||
uncalled = Decimal(act[3])
|
||||
if uncalled > 0 and max(calls+[0]) < uncalled:
|
||||
|
||||
print "returning some bet, calls:", calls
|
||||
print "returned: %.2f from %.2f" % ((uncalled - max(calls)), self.totalpot,)
|
||||
self.totalpot -= (uncalled - max(calls))
|
||||
print "new totalpot:", self.totalpot
|
||||
|
||||
if self.totalcollected is None:
|
||||
self.totalcollected = 0;
|
||||
for amount in self.collected.values():
|
||||
self.totalcollected += Decimal(amount)
|
||||
|
||||
# TODO: Some sites (Everleaf) don't record uncalled bets. Figure out if a bet is uncalled and subtract it from self.totalcollected.
|
||||
# remember that portions of bets may be uncalled, so:
|
||||
# bet followed by no call is an uncalled bet
|
||||
# bet x followed by call y where y < x has x-y uncalled (and second player all in)
|
||||
|
||||
|
||||
|
||||
def getGameTypeAsString(self):
|
||||
"""\
|
||||
Map the tuple self.gametype onto the pokerstars string describing it
|
||||
|
@ -309,7 +373,8 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
|||
print "what do they show"
|
||||
|
||||
print "*** SUMMARY ***"
|
||||
print "Total pot $%s | Rake $%.2f)" % (self.totalpot, self.rake) # TODO side pots
|
||||
print "Total pot $%s | Rake $%.2f" % (self.totalcollected, self.rake) # TODO: side pots
|
||||
|
||||
board = []
|
||||
for s in self.board.values():
|
||||
board += s
|
||||
|
|
|
@ -161,7 +161,8 @@ class HandHistoryConverter:
|
|||
def readPlayerStacks(self, hand): abstract
|
||||
|
||||
# Needs to return a MatchObject with group names identifying the streets into the Hand object
|
||||
# that is, pulls the chunks of preflop, flop, turn and river text into hand.streets MatchObject.
|
||||
# so groups are called by street names 'PREFLOP', 'FLOP', 'STREET2' etc
|
||||
# blinds are done seperately
|
||||
def markStreets(self, hand): abstract
|
||||
|
||||
#Needs to return a list in the format
|
||||
|
@ -173,11 +174,13 @@ class HandHistoryConverter:
|
|||
def readCollectPot(self, hand): abstract
|
||||
|
||||
# Some sites don't report the rake. This will be called at the end of the hand after the pot total has been calculated
|
||||
# so that an inheriting class can calculate it for the specific site if need be.
|
||||
def getRake(self, hand): abstract
|
||||
# an inheriting class can calculate it for the specific site if need be.
|
||||
def getRake(self, hand):
|
||||
hand.rake = hand.totalpot - hand.totalcollected # * Decimal('0.05') # probably not quite right
|
||||
|
||||
|
||||
def sanityCheck(self):
|
||||
sane = True
|
||||
sane = False
|
||||
base_w = False
|
||||
#Check if hhbase exists and is writable
|
||||
#Note: Will not try to create the base HH directory
|
||||
|
|
Loading…
Reference in New Issue
Block a user