Writes hands to stderr, miscellanous crap to stdout; usuable as cmdline
filter: ./Everleaf 'hhfile' 1>/dev/null 2>outfile Holecards are sets -- should work on Omaha hi hands also. Successfully imported Speed_Kuala_full.txt to fpdb. Added gettext. cards strings are handled a little better (one fewer regex) Testfile can be supplied as first cmd line arg.
This commit is contained in:
parent
fb02d9224b
commit
9c5d0f4598
|
@ -76,11 +76,11 @@ class Everleaf(HandHistoryConverter):
|
|||
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.setHeroCardsRegex('.*\nDealt\sto\s(?P<PNAME>.*)\s\[ (?P<CARDS>.*) \]')
|
||||
self.rexx.setActionStepRegex('.*\n(?P<PNAME>.*)(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[\$ (?P<BET>[.\d]+) USD\])?')
|
||||
self.rexx.setShowdownActionRegex('.*\n(?P<PNAME>.*) shows \[ (?P<CARDS>.*) \]')
|
||||
self.rexx.setCollectPotRegex('.*\n(?P<PNAME>.*) wins \$ (?P<POT>[.\d]+) USD(.*\[ (?P<HAND>.*) \])?')
|
||||
self.rexx.setCollectPotRegex('.*\n(?P<PNAME>.*) wins \$ (?P<POT>[.\d]+) USD(.*\[ (?P<CARDS>.*) \])?')
|
||||
self.rexx.sits_out_re = re.compile('(?P<PNAME>.*) sits out')
|
||||
self.rexx.compileRegexes()
|
||||
|
||||
def readSupportedGames(self):
|
||||
|
@ -163,7 +163,11 @@ class Everleaf(HandHistoryConverter):
|
|||
hand.involved = False
|
||||
else:
|
||||
hand.hero = m.group('PNAME')
|
||||
hand.addHoleCards([m.group('HOLE1'), m.group('HOLE2')], m.group('PNAME'))
|
||||
# "2c, qh" -> set(["2c","qc"])
|
||||
# Also works with Omaha hands.
|
||||
cards = m.group('CARDS')
|
||||
cards = set(cards.split(', '))
|
||||
hand.addHoleCards(cards, m.group('PNAME'))
|
||||
|
||||
def readAction(self, hand, street):
|
||||
m = self.rexx.action_re.finditer(hand.streets.group(street))
|
||||
|
@ -185,25 +189,31 @@ class Everleaf(HandHistoryConverter):
|
|||
|
||||
|
||||
def readShowdownActions(self, hand):
|
||||
for shows in self.rexx.showdown_action_re.finditer(hand.string):
|
||||
print shows.groups()
|
||||
re_card = re.compile('(?P<CARD>[0-9tjqka][schd])') # copied from earlier
|
||||
cards = [card.group('CARD') for card in re_card.finditer(shows.group('CARDS'))]
|
||||
print cards
|
||||
for shows in self.rexx.showdown_action_re.finditer(hand.string):
|
||||
cards = shows.group('CARDS')
|
||||
cards = set(cards.split(', '))
|
||||
#re_card = re.compile('(?P<CARD>[0-9tjqka][schd])') # copied from earlier
|
||||
#cards = set([card.group('CARD') for card in re_card.finditer(shows.group('CARDS'))])
|
||||
hand.addShownCards(cards, shows.group('PNAME'))
|
||||
|
||||
def readCollectPot(self,hand):
|
||||
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'))])
|
||||
if m.group('CARDS') is not None:
|
||||
cards = m.group('CARDS')
|
||||
cards = set(cards.split(', '))
|
||||
#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'))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
c = Configuration.Config()
|
||||
e = Everleaf(c, "regression-test-files/everleaf/Speed_Kuala_full.txt")
|
||||
if sys.argv[0] == '':
|
||||
testfile = "regression-test-files/everleaf/Speed_Kuala_full.txt"
|
||||
else:
|
||||
testfile = sys.argv[1]
|
||||
print "Converting: ", testfile
|
||||
e = Everleaf(c, testfile)
|
||||
e.processFile()
|
||||
print str(e)
|
||||
|
||||
|
|
110
pyfpdb/Hand.py
110
pyfpdb/Hand.py
|
@ -106,7 +106,7 @@ chips (string) the chips the player has at the start of the hand (can be None)
|
|||
If a player has None chips he won't be added."""
|
||||
if chips is not None:
|
||||
self.players.append([seat, name, chips])
|
||||
self.holecards[name] = []
|
||||
self.holecards[name] = set()
|
||||
for street in self.streetList:
|
||||
self.bets[street][name] = []
|
||||
|
||||
|
@ -125,29 +125,27 @@ If a player has None chips he won't be added."""
|
|||
def addHoleCards(self, cards, player):
|
||||
"""\
|
||||
Assigns observed holecards to a player.
|
||||
cards list of card bigrams e.g. ['2h','jc']
|
||||
cards set of card bigrams e.g. set(['2h','Jc'])
|
||||
player (string) name of player
|
||||
hand
|
||||
Note, will automatically uppercase the rank letter.
|
||||
"""
|
||||
try:
|
||||
self.checkPlayerExists(player)
|
||||
self.holecards[player] = set([self.card(c) for c in cards])
|
||||
cards = set([self.card(c) for c in cards])
|
||||
self.holecards[player].update(cards)
|
||||
except FpdbParseError, e:
|
||||
print "Tried to add holecards for unknown player: %s" % (player,)
|
||||
|
||||
def addShownCards(self, cards, player, holeandboard=None):
|
||||
"""\
|
||||
For when a player shows cards for any reason (for showdown or out of choice).
|
||||
Card ranks will be uppercased
|
||||
"""
|
||||
if cards is not None:
|
||||
self.shown.add(player)
|
||||
self.addHoleCards(cards,player)
|
||||
elif holeandboard is not None:
|
||||
holeandboard = set([self.card(c) for c in holeandboard])
|
||||
board = set([c for s in self.board.values() for c in s])
|
||||
#print board
|
||||
#print holeandboard
|
||||
#print holeandboard.difference(board)
|
||||
self.addHoleCards(holeandboard.difference(board),player)
|
||||
|
||||
|
||||
|
@ -232,14 +230,11 @@ Add a raise on [street] by [player] to [amountTo]
|
|||
if player not in self.collected:
|
||||
self.collected[player] = pot
|
||||
else:
|
||||
# possibly lines like "p collected $ from pot" appear during the showdown
|
||||
# but they are usually unique in the summary, so it's best to try to get them from there.
|
||||
print "%s collected pot more than once; avoidable by reading winnings only from summary lines?"
|
||||
print "[WARNING] %s collected pot more than once; avoidable by reading winnings only from summary lines?"
|
||||
|
||||
|
||||
def totalPot(self):
|
||||
"""If all bets and blinds have been added, totals up the total pot size
|
||||
Known bug: doesn't take into account side pots"""
|
||||
"""If all bets and blinds have been added, totals up the total pot size"""
|
||||
if self.totalpot is None:
|
||||
self.totalpot = 0
|
||||
|
||||
|
@ -288,10 +283,6 @@ Known bug: doesn't take into account side pots"""
|
|||
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)
|
||||
|
||||
|
||||
|
||||
|
@ -322,81 +313,89 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
|||
|
||||
return string
|
||||
|
||||
def printHand(self):
|
||||
def writeHand(self, fh=sys.__stdout__):
|
||||
# PokerStars format.
|
||||
print "\n### Pseudo stars format ###"
|
||||
print "%s Game #%s: %s ($%s/$%s) - %s" %(self.sitename, self.handid, self.getGameTypeAsString(), self.sb, self.bb, self.starttime)
|
||||
print "Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos)
|
||||
for player in self.players:
|
||||
print "Seat %s: %s ($%s)" %(player[0], player[1], player[2])
|
||||
#print "\n### Pseudo stars format ###"
|
||||
#print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %(self.sitename, self.handid, self.getGameTypeAsString(), self.sb, self.bb, self.starttime))
|
||||
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, self.starttime))
|
||||
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']])
|
||||
print players_who_act_preflop
|
||||
print [x[1] for x in self.players]
|
||||
print [x for x in self.players if x[1] in players_who_act_preflop]
|
||||
for player in [x for x in self.players if x[1] in players_who_act_preflop]:
|
||||
#Only print stacks of players who do something preflop
|
||||
print >>fh, _("Seat %s: %s ($%s)" %(player[0], player[1], player[2]))
|
||||
|
||||
if(self.posted[0] is None):
|
||||
print "No small blind posted"
|
||||
#print >>fh, _("No small blind posted") # PS doesn't say this
|
||||
pass
|
||||
else:
|
||||
print "%s: posts small blind $%s" %(self.posted[0], self.sb)
|
||||
print >>fh, _("%s: posts small blind $%s" %(self.posted[0], self.sb))
|
||||
|
||||
#May be more than 1 bb posting
|
||||
for a in self.posted[1:]:
|
||||
print "%s: posts big blind $%s" %(self.posted[1], self.bb)
|
||||
print >>fh, _("%s: posts big blind $%s" %(self.posted[1], self.bb))
|
||||
|
||||
# What about big & small blinds?
|
||||
# TODO: What about big & small blinds?
|
||||
|
||||
print "*** HOLE CARDS ***"
|
||||
print >>fh, _("*** HOLE CARDS ***")
|
||||
if self.involved:
|
||||
print "Dealt to %s [%s]" %(self.hero , " ".join(self.holecards[self.hero]))
|
||||
print >>fh, _("Dealt to %s [%s]" %(self.hero , " ".join(self.holecards[self.hero])))
|
||||
|
||||
if 'PREFLOP' in self.actions:
|
||||
for act in self.actions['PREFLOP']:
|
||||
self.printActionLine(act)
|
||||
self.printActionLine(act, fh)
|
||||
|
||||
if 'FLOP' in self.actions:
|
||||
print "*** FLOP *** [%s]" %( " ".join(self.board['Flop']))
|
||||
print >>fh, _("*** FLOP *** [%s]" %( " ".join(self.board['Flop'])))
|
||||
for act in self.actions['FLOP']:
|
||||
self.printActionLine(act)
|
||||
self.printActionLine(act, fh)
|
||||
|
||||
if 'TURN' in self.actions:
|
||||
print "*** TURN *** [%s] [%s]" %( " ".join(self.board['Flop']), " ".join(self.board['Turn']))
|
||||
print >>fh, _("*** TURN *** [%s] [%s]" %( " ".join(self.board['Flop']), " ".join(self.board['Turn'])))
|
||||
for act in self.actions['TURN']:
|
||||
self.printActionLine(act)
|
||||
self.printActionLine(act, fh)
|
||||
|
||||
if 'RIVER' in self.actions:
|
||||
print "*** RIVER *** [%s] [%s]" %(" ".join(self.board['Flop']+self.board['Turn']), " ".join(self.board['River']) )
|
||||
print >>fh, _("*** RIVER *** [%s] [%s]" %(" ".join(self.board['Flop']+self.board['Turn']), " ".join(self.board['River']) ))
|
||||
for act in self.actions['RIVER']:
|
||||
self.printActionLine(act)
|
||||
self.printActionLine(act, fh)
|
||||
|
||||
|
||||
#Some sites don't have a showdown section so we have to figure out if there should be one
|
||||
# The logic for a showdown is: at the end of river action there are at least two players in the hand
|
||||
# we probably don't need a showdown section in pseudo stars format for our filtering purposes
|
||||
if 'SHOWDOWN' in self.actions:
|
||||
print "*** SHOW DOWN ***"
|
||||
print "what do they show"
|
||||
print >>fh, _("*** SHOW DOWN ***")
|
||||
print >>fh, "DEBUG: what do they show"
|
||||
|
||||
print "*** SUMMARY ***"
|
||||
print "Total pot $%s | Rake $%.2f" % (self.totalcollected, self.rake) # TODO: side pots
|
||||
print >>fh, _("*** SUMMARY ***")
|
||||
print >>fh, _("Total pot $%s | Rake $%.2f" % (self.totalcollected, self.rake)) # TODO: side pots
|
||||
|
||||
board = []
|
||||
for s in self.board.values():
|
||||
board += s
|
||||
if board: # sometimes hand ends preflop without a board
|
||||
print "Board [%s]" % (" ".join(board))
|
||||
print >>fh, _("Board [%s]" % (" ".join(board)))
|
||||
|
||||
|
||||
for player in self.players:
|
||||
seatnum = player[0]
|
||||
name = player[1]
|
||||
if name in self.collected and self.holecards[name]:
|
||||
print "Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, " ".join(self.holecards[name]), self.collected[name])
|
||||
print >>fh, _("Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, " ".join(self.holecards[name]), self.collected[name]))
|
||||
elif name in self.collected:
|
||||
print "Seat %d: %s collected ($%s)" % (seatnum, name, self.collected[name])
|
||||
print >>fh, _("Seat %d: %s collected ($%s)" % (seatnum, name, self.collected[name]))
|
||||
elif player[1] in self.shown:
|
||||
print "Seat %d: %s showed [%s]" % (seatnum, name, " ".join(self.holecards[name]))
|
||||
print >>fh, _("Seat %d: %s showed [%s]" % (seatnum, name, " ".join(self.holecards[name])))
|
||||
elif player[1] in self.folded:
|
||||
print "Seat %d: %s folded" % (seatnum, name)
|
||||
print >>fh, _("Seat %d: %s folded" % (seatnum, name))
|
||||
else:
|
||||
print "Seat %d: %s mucked" % (seatnum, name)
|
||||
print >>fh, _("Seat %d: %s mucked" % (seatnum, name))
|
||||
|
||||
print
|
||||
print >>fh, "\n\n"
|
||||
# TODO:
|
||||
# logic for side pots
|
||||
# logic for which players get to showdown
|
||||
|
@ -411,17 +410,22 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
|||
#print "Seat %d: %s showed %s" % (player[0], player[1], hole)
|
||||
#else:
|
||||
#print "Seat %d: %s mucked or folded" % (player[0], player[1])
|
||||
|
||||
|
||||
def printHand(self):
|
||||
self.writeHand(sys.stdout)
|
||||
|
||||
def printActionLine(self, act):
|
||||
if act[1] == 'folds' or act[1] == 'checks':
|
||||
print "%s: %s " %(act[0], act[1])
|
||||
def printActionLine(self, act, fh):
|
||||
if act[1] == 'folds':
|
||||
print >>fh, _("%s: folds" %(act[0]))
|
||||
elif act[1] == 'checks':
|
||||
print >>fh, _("%s: checks" %(act[0]))
|
||||
if act[1] == 'calls':
|
||||
print "%s: %s $%s" %(act[0], act[1], act[2])
|
||||
print >>fh, _("%s: calls $%s" %(act[0], act[2]))
|
||||
if act[1] == 'bets':
|
||||
print "%s: %s $%s" %(act[0], act[1], act[2])
|
||||
print >>fh, _("%s: bets $%s" %(act[0], act[2]))
|
||||
if act[1] == 'raises':
|
||||
print "%s: %s $%s to $%s" %(act[0], act[1], act[2], act[3])
|
||||
print >>fh, _("%s: raises $%s to $%s" %(act[0], act[2], act[3]))
|
||||
|
||||
# going to use pokereval to figure out hands at some point.
|
||||
# these functions are copied from pokergame.py
|
||||
|
|
|
@ -30,6 +30,8 @@ import operator
|
|||
from xml.dom.minidom import Node
|
||||
from pokereval import PokerEval
|
||||
from time import time
|
||||
import gettext
|
||||
|
||||
#from pokerengine.pokercards import *
|
||||
# provides letter2name{}, letter2names{}, visible_card(), not_visible_card(), is_visible(), card_value(), class PokerCards
|
||||
# but it's probably not installed so here are the ones we may want:
|
||||
|
@ -65,6 +67,11 @@ letter2names = {
|
|||
'2': 'Deuces'
|
||||
}
|
||||
|
||||
import gettext
|
||||
gettext.install('myapplication')
|
||||
|
||||
|
||||
|
||||
class HandHistoryConverter:
|
||||
eval = PokerEval()
|
||||
def __init__(self, config, file, sitename):
|
||||
|
@ -124,7 +131,7 @@ class HandHistoryConverter:
|
|||
hand.totalPot()
|
||||
self.getRake(hand)
|
||||
|
||||
hand.printHand()
|
||||
hand.writeHand(sys.stderr)
|
||||
#if(hand.involved == True):
|
||||
#self.writeHand("output file", hand)
|
||||
#hand.printHand()
|
||||
|
|
Loading…
Reference in New Issue
Block a user