getting somewhere, very messy, using pokereval, not sure if this is right direction, comments please
This commit is contained in:
parent
72addde510
commit
4f44eff3da
|
@ -66,7 +66,7 @@ from HandHistoryConverter import *
|
||||||
class Everleaf(HandHistoryConverter):
|
class Everleaf(HandHistoryConverter):
|
||||||
def __init__(self, config, file):
|
def __init__(self, config, file):
|
||||||
print "Initialising Everleaf converter class"
|
print "Initialising Everleaf converter class"
|
||||||
HandHistoryConverter.__init__(self, config, file, "Everleaf") # Call super class init.
|
HandHistoryConverter.__init__(self, config, file, sitename="Everleaf") # Call super class init.
|
||||||
self.sitename = "Everleaf"
|
self.sitename = "Everleaf"
|
||||||
self.setFileType("text")
|
self.setFileType("text")
|
||||||
self.rexx.setGameInfoRegex('.*Blinds \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)')
|
self.rexx.setGameInfoRegex('.*Blinds \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)')
|
||||||
|
@ -78,6 +78,7 @@ class Everleaf(HandHistoryConverter):
|
||||||
# mct : what about posting small & big blinds simultaneously?
|
# 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<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\])?')
|
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.compileRegexes()
|
self.rexx.compileRegexes()
|
||||||
|
|
||||||
def readSupportedGames(self):
|
def readSupportedGames(self):
|
||||||
|
@ -118,8 +119,7 @@ class Everleaf(HandHistoryConverter):
|
||||||
players = []
|
players = []
|
||||||
|
|
||||||
for a in m:
|
for a in m:
|
||||||
hand.addPlayer(a.group('SEAT'), a.group('PNAME'), a.group('CASH'))
|
hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH'))
|
||||||
|
|
||||||
|
|
||||||
def markStreets(self, hand):
|
def markStreets(self, hand):
|
||||||
# PREFLOP = ** Dealing down cards **
|
# PREFLOP = ** Dealing down cards **
|
||||||
|
@ -128,6 +128,17 @@ class Everleaf(HandHistoryConverter):
|
||||||
# print "DEBUG: Street: %s\tspan: %s" %(street, str(m.span(street)))
|
# print "DEBUG: Street: %s\tspan: %s" %(street, str(m.span(street)))
|
||||||
hand.streets = m
|
hand.streets = m
|
||||||
|
|
||||||
|
def readCommunityCards(self, hand):
|
||||||
|
# currently regex in wrong place pls fix my brain's fried
|
||||||
|
# what a mess!
|
||||||
|
re_board = re.compile('\*\* Dealing (?P<STREET>.*) \*\* \[ (?P<CARDS>.*) \]')
|
||||||
|
m = re_board.finditer(hand.string)
|
||||||
|
for street in m:
|
||||||
|
#print street.groups()
|
||||||
|
re_card = re.compile('(?P<CARD>[0-9tjqka][schd])') # look that's weird, hole cards have a capital rank but board cards are lower case?
|
||||||
|
cardsmatch = re_card.finditer(street.group('CARDS'))
|
||||||
|
hand.setCommunityCards(street.group('STREET'), [card.group('CARD') for card in cardsmatch])
|
||||||
|
|
||||||
def readBlinds(self, hand):
|
def readBlinds(self, hand):
|
||||||
try:
|
try:
|
||||||
m = self.rexx.small_blind_re.search(hand.string)
|
m = self.rexx.small_blind_re.search(hand.string)
|
||||||
|
@ -148,7 +159,7 @@ class Everleaf(HandHistoryConverter):
|
||||||
hand.involved = False
|
hand.involved = False
|
||||||
else:
|
else:
|
||||||
hand.hero = m.group('PNAME')
|
hand.hero = m.group('PNAME')
|
||||||
hand.addHoleCards(m.group('HOLE1'), m.group('HOLE2'))
|
hand.addHoleCards([m.group('HOLE1'), m.group('HOLE2')], m.group('PNAME'))
|
||||||
|
|
||||||
def readAction(self, hand, street):
|
def readAction(self, hand, street):
|
||||||
m = self.rexx.action_re.finditer(hand.streets.group(street))
|
m = self.rexx.action_re.finditer(hand.streets.group(street))
|
||||||
|
@ -161,10 +172,19 @@ class Everleaf(HandHistoryConverter):
|
||||||
elif action.group('ATYPE') == 'bets':
|
elif action.group('ATYPE') == 'bets':
|
||||||
hand.addBet( street, action.group('PNAME'), action.group('BET') )
|
hand.addBet( street, action.group('PNAME'), action.group('BET') )
|
||||||
else:
|
else:
|
||||||
print "DEBUG: unimplemented readAction: %s %s" %(action.group('PNAME'),action.group('ATYPE'),)
|
#print "DEBUG: unimplemented readAction: %s %s" %(action.group('PNAME'),action.group('ATYPE'),)
|
||||||
hand.actions[street] += [[action.group('PNAME'), action.group('ATYPE')]]
|
hand.actions[street] += [[action.group('PNAME'), action.group('ATYPE')]]
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
hand.addHoleCards(cards, shows.group('PNAME'))
|
||||||
|
|
||||||
|
|
||||||
def getRake(self, hand):
|
def getRake(self, hand):
|
||||||
hand.rake = hand.totalpot * Decimal('0.05') # probably not quite right
|
hand.rake = hand.totalpot * Decimal('0.05') # probably not quite right
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,13 @@ import xml.dom.minidom
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
import operator
|
import operator
|
||||||
from xml.dom.minidom import Node
|
from xml.dom.minidom import Node
|
||||||
|
from pokereval import PokerEval
|
||||||
|
|
||||||
class HandHistoryConverter:
|
class HandHistoryConverter:
|
||||||
|
eval = PokerEval()
|
||||||
def __init__(self, config, file, sitename):
|
def __init__(self, config, file, sitename):
|
||||||
print "HandHistory init called"
|
print "HandHistory init called"
|
||||||
|
|
||||||
self.c = config
|
self.c = config
|
||||||
self.sitename = sitename
|
self.sitename = sitename
|
||||||
self.obs = "" # One big string
|
self.obs = "" # One big string
|
||||||
|
@ -68,8 +71,9 @@ class HandHistoryConverter:
|
||||||
self.readPlayerStacks(hand)
|
self.readPlayerStacks(hand)
|
||||||
self.markStreets(hand)
|
self.markStreets(hand)
|
||||||
self.readBlinds(hand)
|
self.readBlinds(hand)
|
||||||
self.readHeroCards(hand)
|
self.readHeroCards(hand) # want to generalise to draw games
|
||||||
|
self.readCommunityCards(hand) # read community cards
|
||||||
|
self.readShowdownActions(hand)
|
||||||
# Read action (Note: no guarantee this is in hand order.
|
# Read action (Note: no guarantee this is in hand order.
|
||||||
for street in hand.streets.groupdict():
|
for street in hand.streets.groupdict():
|
||||||
self.readAction(hand, street)
|
self.readAction(hand, street)
|
||||||
|
@ -198,10 +202,7 @@ class HandHistoryConverter:
|
||||||
|
|
||||||
print "*** HOLE CARDS ***"
|
print "*** HOLE CARDS ***"
|
||||||
print "Dealt to %s [%s %s]" %(hand.hero , hand.holecards[0], hand.holecards[1])
|
print "Dealt to %s [%s %s]" %(hand.hero , hand.holecards[0], hand.holecards[1])
|
||||||
#
|
|
||||||
## ACTION STUFF
|
|
||||||
# This is no limit only at the moment
|
|
||||||
|
|
||||||
for act in hand.actions['PREFLOP']:
|
for act in hand.actions['PREFLOP']:
|
||||||
self.printActionLine(act, 0)
|
self.printActionLine(act, 0)
|
||||||
|
|
||||||
|
@ -226,10 +227,6 @@ class HandHistoryConverter:
|
||||||
|
|
||||||
print "*** SUMMARY ***"
|
print "*** SUMMARY ***"
|
||||||
print "XXXXXXXXXXXX Need sumary info XXXXXXXXXXX"
|
print "XXXXXXXXXXXX Need sumary info XXXXXXXXXXX"
|
||||||
# print "Total pot $%s | Rake $%s)" %(hand.totalpot $" + hand.rake)
|
|
||||||
# print "Board [" + boardcards + "]"
|
|
||||||
#
|
|
||||||
# SUMMARY STUFF
|
|
||||||
|
|
||||||
|
|
||||||
def printActionLine(self, act, pot):
|
def printActionLine(self, act, pot):
|
||||||
|
@ -239,7 +236,7 @@ class HandHistoryConverter:
|
||||||
print "%s: %s $%s" %(act[0], act[1], act[2])
|
print "%s: %s $%s" %(act[0], act[1], act[2])
|
||||||
if act[1] == 'raises':
|
if act[1] == 'raises':
|
||||||
print "%s: %s $%s to XXXpottotalXXX" %(act[0], act[1], act[2])
|
print "%s: %s $%s to XXXpottotalXXX" %(act[0], act[1], act[2])
|
||||||
|
|
||||||
|
|
||||||
#takes a poker float (including , for thousand seperator and converts it to an int
|
#takes a poker float (including , for thousand seperator and converts it to an int
|
||||||
def float2int (self, string):
|
def float2int (self, string):
|
||||||
|
@ -261,13 +258,13 @@ class Hand:
|
||||||
# def __init__(self, sitename, gametype, sb, bb, string):
|
# def __init__(self, sitename, gametype, sb, bb, string):
|
||||||
|
|
||||||
UPS = {'a':'A', 't':'T', 'j':'J', 'q':'Q', 'k':'K'}
|
UPS = {'a':'A', 't':'T', 'j':'J', 'q':'Q', 'k':'K'}
|
||||||
STREETS = ['BLINDS','PREFLOP','FLOP','TURN','RIVER']
|
|
||||||
def __init__(self, sitename, gametype, string):
|
def __init__(self, sitename, gametype, string):
|
||||||
self.sitename = sitename
|
self.sitename = sitename
|
||||||
self.gametype = gametype
|
self.gametype = gametype
|
||||||
self.string = string
|
self.string = string
|
||||||
|
|
||||||
self.streets = None # A MatchObject using a groupnames to identify streets.
|
self.streets = None # A MatchObject using a groupnames to identify streets.
|
||||||
|
self.streetList = ['BLINDS','PREFLOP','FLOP','TURN','RIVER'] # a list of the observed street names in order
|
||||||
self.actions = {}
|
self.actions = {}
|
||||||
|
|
||||||
self.handid = 0
|
self.handid = 0
|
||||||
|
@ -281,15 +278,18 @@ class Hand:
|
||||||
self.players = []
|
self.players = []
|
||||||
self.posted = []
|
self.posted = []
|
||||||
self.involved = True
|
self.involved = True
|
||||||
|
|
||||||
self.hero = "Hiro"
|
self.hero = "Hiro"
|
||||||
self.holecards = "Xx Xx"
|
self.holecards = {} # dict from player names to lists of hole cards
|
||||||
|
self.board = {} # dict from street names to community cards
|
||||||
|
|
||||||
self.action = []
|
self.action = []
|
||||||
self.totalpot = None
|
self.totalpot = None
|
||||||
self.rake = None
|
self.rake = None
|
||||||
|
|
||||||
self.bets = {}
|
self.bets = {}
|
||||||
self.lastBet = {}
|
self.lastBet = {}
|
||||||
for street in self.STREETS:
|
for street in self.streetList:
|
||||||
self.bets[street] = {}
|
self.bets[street] = {}
|
||||||
self.lastBet[street] = 0
|
self.lastBet[street] = 0
|
||||||
|
|
||||||
|
@ -299,20 +299,36 @@ class Hand:
|
||||||
chips, the chips the player has at the start of the hand"""
|
chips, the chips the player has at the start of the hand"""
|
||||||
#self.players.append(name)
|
#self.players.append(name)
|
||||||
self.players.append([seat, name, chips])
|
self.players.append([seat, name, chips])
|
||||||
|
self.holecards[name] = []
|
||||||
#self.startChips[name] = chips
|
#self.startChips[name] = chips
|
||||||
#self.endChips[name] = chips
|
#self.endChips[name] = chips
|
||||||
#self.winners[name] = 0
|
#self.winners[name] = 0
|
||||||
for street in self.STREETS:
|
for street in self.streetList:
|
||||||
self.bets[street][name] = []
|
self.bets[street][name] = []
|
||||||
|
|
||||||
|
|
||||||
def addHoleCards(self,h1,h2,seat=None): # generalise to add hole cards for a specific seat or player
|
def addHoleCards(self, cards, player=None): # generalise to add hole cards for a specific seat or player
|
||||||
self.holecards = [self.card(h1), self.card(h2)]
|
for c in cards:
|
||||||
|
self.holecards[player].append(self.card(c))
|
||||||
|
|
||||||
|
|
||||||
|
def discardHoleCards(self, cards, player=None):
|
||||||
|
if seat is None:
|
||||||
|
#raise something
|
||||||
|
pass
|
||||||
|
for card in cards:
|
||||||
|
try:
|
||||||
|
self.holecards[player].remove(card)
|
||||||
|
except ValueError:
|
||||||
|
print "tried to discard a card player apparently didn't have"
|
||||||
|
|
||||||
|
def setCommunityCards(self, street, cards):
|
||||||
|
self.board[street] = [self.card(c) for c in cards]
|
||||||
|
print self.board[street]
|
||||||
|
|
||||||
def card(self,c):
|
def card(self,c):
|
||||||
"""upper case the ranks but not suits, 'atjqk' => 'ATJQK'"""
|
"""upper case the ranks but not suits, 'atjqk' => 'ATJQK'"""
|
||||||
# don't know how to make this 'static'
|
# don't know how to make this 'static'
|
||||||
for k,v in self.UPS.items():
|
for k,v in self.UPS.items():
|
||||||
c = c.replace(k,v)
|
c = c.replace(k,v)
|
||||||
return c
|
return c
|
||||||
|
@ -325,6 +341,13 @@ class Hand:
|
||||||
self.posted += [player]
|
self.posted += [player]
|
||||||
|
|
||||||
|
|
||||||
|
#def addFold(self, street, player=None):
|
||||||
|
## Called when a player folds.
|
||||||
|
#self.bets[street][player].append(None)
|
||||||
|
|
||||||
|
#def addCheck(self, street, player=None):
|
||||||
|
#self.bets[street][player].append(0)
|
||||||
|
|
||||||
def addCall(self, street, player=None, amount=None):
|
def addCall(self, street, player=None, amount=None):
|
||||||
# Potentially calculate the amount of the call if not supplied
|
# Potentially calculate the amount of the call if not supplied
|
||||||
# corner cases include if player would be all in
|
# corner cases include if player would be all in
|
||||||
|
@ -352,15 +375,16 @@ class Hand:
|
||||||
self.actions[street] += [[player, 'bets', amount]]
|
self.actions[street] += [[player, 'bets', amount]]
|
||||||
|
|
||||||
def totalPot(self):
|
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 self.totalpot is None:
|
if self.totalpot is None:
|
||||||
self.totalpot = 0
|
self.totalpot = 0
|
||||||
|
|
||||||
# player names:
|
# player names:
|
||||||
# print [x[1] for x in self.players]
|
# print [x[1] for x in self.players]
|
||||||
for player in [x[1] for x in self.players]:
|
for player in [x[1] for x in self.players]:
|
||||||
for street in self.STREETS:
|
for street in self.streetList:
|
||||||
print street, self.bets[street][player]
|
#print street, self.bets[street][player]
|
||||||
self.totalpot += reduce(operator.add, self.bets[street][player], 0)
|
self.totalpot += reduce(operator.add, self.bets[street][player], 0)
|
||||||
|
|
||||||
|
|
||||||
|
@ -385,7 +409,7 @@ class Hand:
|
||||||
# What about big & small blinds?
|
# What about big & small blinds?
|
||||||
|
|
||||||
print "*** HOLE CARDS ***"
|
print "*** HOLE CARDS ***"
|
||||||
print "Dealt to %s [%s %s]" %(self.hero , self.holecards[0], self.holecards[1])
|
print "Dealt to %s [%s %s]" %(self.hero , self.holecards[self.hero][0], self.holecards[self.hero][1])
|
||||||
|
|
||||||
if 'PREFLOP' in self.actions:
|
if 'PREFLOP' in self.actions:
|
||||||
for act in self.actions['PREFLOP']:
|
for act in self.actions['PREFLOP']:
|
||||||
|
@ -416,6 +440,19 @@ class Hand:
|
||||||
print "*** SUMMARY ***"
|
print "*** SUMMARY ***"
|
||||||
print "Total pot $%s | Rake $%s)" % (self.totalpot, self.rake)
|
print "Total pot $%s | Rake $%s)" % (self.totalpot, self.rake)
|
||||||
print "Board [%s %s %s %s %s]" % (self.streets.group("FLOP1"), self.streets.group("FLOP2"), self.streets.group("FLOP3"), self.streets.group("TURN1"), self.streets.group("RIVER1"))
|
print "Board [%s %s %s %s %s]" % (self.streets.group("FLOP1"), self.streets.group("FLOP2"), self.streets.group("FLOP3"), self.streets.group("TURN1"), self.streets.group("RIVER1"))
|
||||||
|
|
||||||
|
#print self.board
|
||||||
|
for player in self.players:
|
||||||
|
if self.holecards[player[1]]: # empty list default is false
|
||||||
|
hole = self.holecards[player[1]]
|
||||||
|
#print self.board.values()
|
||||||
|
board = []
|
||||||
|
for s in self.board.values():
|
||||||
|
board += s
|
||||||
|
playerhand = self.bestHand('hi', board+hole)
|
||||||
|
print "Seat %d: %s showed %s and won/lost with %s" % (player[0], player[1], hole, playerhand)
|
||||||
|
else:
|
||||||
|
print "Seat %d: %s mucked or folded" % (player[0], player[1])
|
||||||
|
|
||||||
|
|
||||||
def printActionLine(self, act):
|
def printActionLine(self, act):
|
||||||
|
@ -424,4 +461,54 @@ class Hand:
|
||||||
if act[1] == 'calls':
|
if act[1] == 'calls':
|
||||||
print "%s: %s $%s" %(act[0], act[1], act[2])
|
print "%s: %s $%s" %(act[0], act[1], act[2])
|
||||||
if act[1] == 'raises':
|
if act[1] == 'raises':
|
||||||
print "%s: %s $%s to $%s" %(act[0], act[1], act[2], act[3])
|
print "%s: %s $%s to $%s" %(act[0], act[1], act[2], act[3])
|
||||||
|
|
||||||
|
# going to use pokereval to figure out hands
|
||||||
|
# these functions are copied from pokergame.py
|
||||||
|
# im thinking perhaps its best to use all the functionality of pokergame instead
|
||||||
|
# of reinventing the wheel
|
||||||
|
def bestHand(self, side, cards):
|
||||||
|
#if self.variant == "omaha" or self.variant == "omaha8":
|
||||||
|
#hand = self.serial2player[serial].hand.tolist(True)
|
||||||
|
#board = self.board.tolist(True)
|
||||||
|
#else:
|
||||||
|
#hand = hand.tolist(True) + board.tolist(True)
|
||||||
|
#board = []
|
||||||
|
print cards
|
||||||
|
return HandHistoryConverter.eval.best('hi', cards, [])
|
||||||
|
|
||||||
|
def bestHandValue(self, side, serial):
|
||||||
|
(value, cards) = self.bestHand(side, serial)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def readableHandValueLong(self, side, value, cards):
|
||||||
|
cards = self.eval.card2string(cards)
|
||||||
|
if value == "NoPair":
|
||||||
|
if side == "low":
|
||||||
|
if cards[0][0] == '5':
|
||||||
|
return _("The wheel")
|
||||||
|
else:
|
||||||
|
return join(map(lambda card: card[0], cards), ", ")
|
||||||
|
else:
|
||||||
|
return _("High card %(card)s") % { 'card' : _(letter2name[cards[0][0]]) }
|
||||||
|
elif value == "OnePair":
|
||||||
|
return _("A pair of %(card)s") % { 'card' : _(letter2names[cards[0][0]]) } + _(", %(card)s kicker") % { 'card' : _(letter2name[cards[2][0]]) }
|
||||||
|
elif value == "TwoPair":
|
||||||
|
return _("Two pairs %(card1)s and %(card2)s") % { 'card1' : _(letter2names[cards[0][0]]), 'card2' : _(letter2names[cards[2][0]]) } + _(", %(card)s kicker") % { 'card' : _(letter2name[cards[4][0]]) }
|
||||||
|
elif value == "Trips":
|
||||||
|
return _("Three of a kind %(card)s") % { 'card' : _(letter2names[cards[0][0]]) } + _(", %(card)s kicker") % { 'card' : _(letter2name[cards[3][0]]) }
|
||||||
|
elif value == "Straight":
|
||||||
|
return _("Straight %(card1)s to %(card2)s") % { 'card1' : _(letter2name[cards[0][0]]), 'card2' : _(letter2name[cards[4][0]]) }
|
||||||
|
elif value == "Flush":
|
||||||
|
return _("Flush %(card)s high") % { 'card' : _(letter2name[cards[0][0]]) }
|
||||||
|
elif value == "FlHouse":
|
||||||
|
return _("%(card1)ss full of %(card2)ss") % { 'card1' : _(letter2name[cards[0][0]]), 'card2' : _(letter2name[cards[3][0]]) }
|
||||||
|
elif value == "Quads":
|
||||||
|
return _("Four of a kind %(card)s") % { 'card' : _(letter2names[cards[0][0]]) } + _(", %(card)s kicker") % { 'card' : _(letter2name[cards[4][0]]) }
|
||||||
|
elif value == "StFlush":
|
||||||
|
if letter2name[cards[0][0]] == 'Ace':
|
||||||
|
return _("Royal flush")
|
||||||
|
else:
|
||||||
|
return _("Straight flush %(card)s high") % { 'card' : _(letter2name[cards[0][0]]) }
|
||||||
|
return value
|
Loading…
Reference in New Issue
Block a user