Merge branch 'exp' of git://git.assembla.com/mctfpdb

This commit is contained in:
Worros 2008-12-10 09:50:42 +09:00
commit 390519c549
2 changed files with 144 additions and 106 deletions

View File

@ -70,15 +70,16 @@ class Everleaf(HandHistoryConverter):
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]+)')
self.rexx.setSplitHandRegex('\n\n\n\n') self.rexx.setSplitHandRegex('\n\n+')
self.rexx.setHandInfoRegex('.*#(?P<HID>[0-9]+)\n.*\nBlinds \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (?P<GAMETYPE>.*) - (?P<YEAR>[0-9]+)/(?P<MON>[0-9]+)/(?P<DAY>[0-9]+) - (?P<HR>[0-9]+):(?P<MIN>[0-9]+):(?P<SEC>[0-9]+)\nTable (?P<TABLE>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)') self.rexx.setHandInfoRegex('.*#(?P<HID>[0-9]+)\n.*\nBlinds \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (?P<GAMETYPE>.*) - (?P<YEAR>[0-9]+)/(?P<MON>[0-9]+)/(?P<DAY>[0-9]+) - (?P<HR>[0-9]+):(?P<MIN>[0-9]+):(?P<SEC>[0-9]+)\nTable (?P<TABLE>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)')
self.rexx.setPlayerInfoRegex('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \( \$ (?P<CASH>[.0-9]+) USD \)') 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.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.setPostBbRegex('.*\n(?P<PNAME>.*): posts big blind \[\$? (?P<BB>[.0-9]+)')
# 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.setShowdownActionRegex('.*\n(?P<PNAME>.*) shows \[ (?P<CARDS>.*) \]')
self.rexx.setCollectPotRegex('.*\n(?P<PNAME>.*) wins \$ (?P<POT>[.\d]+) USD.*')
self.rexx.compileRegexes() self.rexx.compileRegexes()
def readSupportedGames(self): def readSupportedGames(self):
@ -117,16 +118,38 @@ class Everleaf(HandHistoryConverter):
def readPlayerStacks(self, hand): def readPlayerStacks(self, hand):
m = self.rexx.player_info_re.finditer(hand.string) m = self.rexx.player_info_re.finditer(hand.string)
players = [] players = []
print "\nReading stacks - players seen:"
for a in m: for a in m:
print a.group('PNAME')
hand.addPlayer(int(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 **
m = re.search('(\*\* Dealing down cards \*\*\n)(?P<PREFLOP>.*?\n\*\*)?( Dealing Flop \*\* \[ (?P<FLOP1>\S\S), (?P<FLOP2>\S\S), (?P<FLOP3>\S\S) \])?(?P<FLOP>.*?\*\*)?( Dealing Turn \*\* \[ (?P<TURN1>\S\S) \])?(?P<TURN>.*?\*\*)?( Dealing River \*\* \[ (?P<RIVER1>\S\S) \])?(?P<RIVER>.*)', hand.string,re.DOTALL) # This re fails if, say, river is missing; then we don't get the ** that starts the river.
# for street in m.groupdict(): #m = re.search('(\*\* Dealing down cards \*\*\n)(?P<PREFLOP>.*?\n\*\*)?( Dealing Flop \*\* \[ (?P<FLOP1>\S\S), (?P<FLOP2>\S\S), (?P<FLOP3>\S\S) \])?(?P<FLOP>.*?\*\*)?( Dealing Turn \*\* \[ (?P<TURN1>\S\S) \])?(?P<TURN>.*?\*\*)?( Dealing River \*\* \[ (?P<RIVER1>\S\S) \])?(?P<RIVER>.*)', hand.string,re.DOTALL)
# print "DEBUG: Street: %s\tspan: %s" %(street, str(m.span(street)))
m = re.search(r"\*\* Dealing down cards \*\*(?P<PREFLOP>.+(?=\*\* Dealing Flop \*\*)|.+)"
r"(\*\* Dealing Flop \*\* \[ (?P<FLOP1>\S\S), (?P<FLOP2>\S\S), (?P<FLOP3>\S\S) \](?P<FLOP>.+(?=\*\* Dealing Turn \*\*)|.+))?"
r"(\*\* Dealing Turn \*\* \[ (?P<TURN1>\S\S) \](?P<TURN>.+(?=\*\* Dealing River \*\*)|.+))?"
r"(\*\* Dealing River \*\* \[ (?P<RIVER1>\S\S) \](?P<RIVER>.+))?", hand.string,re.DOTALL)
# that wasn't easy.
#m1 = re.search(r'(\*\* Dealing down cards \*\*)?(?P<PREFLOP>.*?\n\*\*)',hand.string,re.DOTALL)
#m2 = re.search(r'(\*\* Dealing Flop \*\*)?(?P<FLOP>.*\n\*\*)',hand.string,re.DOTALL)
#print hand.string
#print "m groups:\n",m.groupdict()
#print "m1 groups:\n",m1.groupdict()
#print "m2 groups:\n",m2.groupdict()
#(\*\* Dealing Flop \*\* \[ (?P<FLOP1>\S\S), (?P<FLOP2>\S\S), (?P<FLOP3>\S\S) \](?P<FLOP>.*?)?)?
#(\*\* Dealing Turn \*\* \[ (?P<TURN1>\S\S) \](?P<TURN>.*?))?
#(\*\* Dealing River \*\* \[ (?P<RIVER1>\S\S) \](?P<RIVER>.*?))?', hand.string,re.DOTALL)
#for street in m.groupdict():
#print "DEBUG: Street: %s\tspan: %s" %(street, str(m.span(street)))
hand.streets = m hand.streets = m
#sys.exit()
def readCommunityCards(self, hand): def readCommunityCards(self, hand):
# currently regex in wrong place pls fix my brain's fried # currently regex in wrong place pls fix my brain's fried
@ -184,13 +207,19 @@ class Everleaf(HandHistoryConverter):
print cards print cards
hand.addHoleCards(cards, shows.group('PNAME')) hand.addHoleCards(cards, shows.group('PNAME'))
def readCollectPot(self,hand):
m = self.rexx.collect_pot_re.search(hand.string)
if m is not None:
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): 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
if __name__ == "__main__": if __name__ == "__main__":
c = Configuration.Config() c = Configuration.Config()
e = Everleaf(c, "Speed_Kuala.txt") e = Everleaf(c, "Speed_Kuala_full.txt")
e.processFile() e.processFile()
print str(e) print str(e)

View File

@ -28,6 +28,41 @@ import operator
from xml.dom.minidom import Node from xml.dom.minidom import Node
from pokereval import PokerEval from pokereval import PokerEval
#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:
letter2name = {
'A': 'Ace',
'K': 'King',
'Q': 'Queen',
'J': 'Jack',
'T': 'Ten',
'9': 'Nine',
'8': 'Eight',
'7': 'Seven',
'6': 'Six',
'5': 'Five',
'4': 'Four',
'3': 'Trey',
'2': 'Deuce'
}
letter2names = {
'A': 'Aces',
'K': 'Kings',
'Q': 'Queens',
'J': 'Jacks',
'T': 'Tens',
'9': 'Nines',
'8': 'Eights',
'7': 'Sevens',
'6': 'Sixes',
'5': 'Fives',
'4': 'Fours',
'3': 'Treys',
'2': 'Deuces'
}
class HandHistoryConverter: class HandHistoryConverter:
eval = PokerEval() eval = PokerEval()
def __init__(self, config, file, sitename): def __init__(self, config, file, sitename):
@ -67,6 +102,7 @@ class HandHistoryConverter:
self.gametype = self.determineGameType() self.gametype = self.determineGameType()
self.hands = self.splitFileIntoHands() self.hands = self.splitFileIntoHands()
for hand in self.hands: for hand in self.hands:
print "\nInput:\n"+hand.string
self.readHandInfo(hand) self.readHandInfo(hand)
self.readPlayerStacks(hand) self.readPlayerStacks(hand)
self.markStreets(hand) self.markStreets(hand)
@ -76,17 +112,21 @@ class HandHistoryConverter:
self.readShowdownActions(hand) 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) if hand.streets.group(street) is not None:
self.readAction(hand, street)
self.readCollectPot(hand)
# finalise it (total the pot) # finalise it (total the pot)
hand.totalPot() hand.totalPot()
self.getRake(hand) self.getRake(hand)
if(hand.involved == True): hand.printHand()
#if(hand.involved == True):
#self.writeHand("output file", hand) #self.writeHand("output file", hand)
hand.printHand() #hand.printHand()
else: #else:
pass #Don't write out observed hands #pass #Don't write out observed hands
##### #####
# These functions are parse actions that may be overridden by the inheriting class # These functions are parse actions that may be overridden by the inheriting class
@ -124,6 +164,7 @@ class HandHistoryConverter:
def readBlinds(self, hand): abstract def readBlinds(self, hand): abstract
def readHeroCards(self, hand): abstract def readHeroCards(self, hand): abstract
def readAction(self, hand, street): abstract def readAction(self, hand, street): abstract
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 # 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. # so that an inheriting class can calculate it for the specific site if need be.
@ -156,6 +197,7 @@ class HandHistoryConverter:
def splitFileIntoHands(self): def splitFileIntoHands(self):
hands = [] hands = []
self.obs.strip()
list = self.rexx.split_hand_re.split(self.obs) list = self.rexx.split_hand_re.split(self.obs)
list.pop() #Last entry is empty list.pop() #Last entry is empty
for l in list: for l in list:
@ -177,66 +219,6 @@ class HandHistoryConverter:
except: except:
traceback.print_exc(file=sys.stderr) traceback.print_exc(file=sys.stderr)
def writeHand(self, file, hand):
"""Write out parsed data"""
print "DEBUG: *************************"
print "DEBUG: Start of print hand"
print "DEBUG: *************************"
print "%s Game #%s: %s ($%s/$%s) - %s" %(hand.sitename, hand.handid, "XXXXhand.gametype", hand.sb, hand.bb, hand.starttime)
print "Table '%s' %d-max Seat #%s is the button" %(hand.tablename, hand.maxseats, hand.buttonpos)
for player in hand.players:
print "Seat %s: %s ($%s)" %(player[0], player[1], player[2])
if(hand.posted[0] == "FpdbNBP"):
print "No small blind posted"
else:
print "%s: posts small blind $%s" %(hand.posted[0], hand.sb)
#May be more than 1 bb posting
print "%s: posts big blind $%s" %(hand.posted[1], hand.bb)
if(len(hand.posted) > 2):
# Need to loop on all remaining big blinds - lazy
print "XXXXXXXXX FIXME XXXXXXXX"
print "*** HOLE CARDS ***"
print "Dealt to %s [%s %s]" %(hand.hero , hand.holecards[0], hand.holecards[1])
for act in hand.actions['PREFLOP']:
self.printActionLine(act, 0)
if 'PREFLOP' in hand.actions:
for act in hand.actions['PREFLOP']:
print "PF action"
if 'FLOP' in hand.actions:
print "*** FLOP *** [%s %s %s]" %(hand.streets.group("FLOP1"), hand.streets.group("FLOP2"), hand.streets.group("FLOP3"))
for act in hand.actions['FLOP']:
self.printActionLine(act, 0)
if 'TURN' in hand.actions:
print "*** TURN *** [%s %s %s] [%s]" %(hand.streets.group("FLOP1"), hand.streets.group("FLOP2"), hand.streets.group("FLOP3"), hand.streets.group("TURN1"))
for act in hand.actions['TURN']:
self.printActionLine(act, 0)
if 'RIVER' in hand.actions:
print "*** RIVER *** [%s %s %s %s] [%s]" %(hand.streets.group("FLOP1"), hand.streets.group("FLOP2"), hand.streets.group("FLOP3"), hand.streets.group("TURN1"), hand.streets.group("RIVER1"))
for act in hand.actions['RIVER']:
self.printActionLine(act, 0)
print "*** SUMMARY ***"
print "XXXXXXXXXXXX Need sumary info XXXXXXXXXXX"
def printActionLine(self, act, pot):
if act[1] == 'folds' or act[1] == 'checks':
print "%s: %s " %(act[0], act[1])
if act[1] == 'calls':
print "%s: %s $%s" %(act[0], act[1], act[2])
if act[1] == 'raises':
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):
@ -282,6 +264,7 @@ class Hand:
self.hero = "Hiro" self.hero = "Hiro"
self.holecards = {} # dict from player names to lists of hole cards self.holecards = {} # dict from player names to lists of hole cards
self.board = {} # dict from street names to community cards self.board = {} # dict from street names to community cards
self.collected = {} # dict from player names to amounts collected
self.action = [] self.action = []
self.totalpot = None self.totalpot = None
@ -296,8 +279,7 @@ class Hand:
def addPlayer(self, seat, name, chips): def addPlayer(self, seat, name, chips):
"""seat, an int indicating the seat """seat, an int indicating the seat
name, the player name name, the player name
chips, the chips the player has at the start of the hand""" chips, the chips the player has at the start of the hand (can be None)"""
#self.players.append(name)
self.players.append([seat, name, chips]) self.players.append([seat, name, chips])
self.holecards[name] = [] self.holecards[name] = []
#self.startChips[name] = chips #self.startChips[name] = chips
@ -370,10 +352,19 @@ class Hand:
self.actions[street] += [[player, 'raises', amountBy, amountTo]] self.actions[street] += [[player, 'raises', amountBy, amountTo]]
def addBet(self, street, player=None, amount=0): def addBet(self, street, player=None, amount=0):
self.bets[street][name].append(Decimal(amount)) self.bets[street][player].append(Decimal(amount))
self.orderedBets[street].append(Decimal(amount)) self.orderedBets[street].append(Decimal(amount))
self.actions[street] += [[player, 'bets', amount]] self.actions[street] += [[player, 'bets', amount]]
def addCollectPot(self,player, pot):
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.
print "%s collected pot more than once; avoidable by reading winnings only from summary lines?"
def totalPot(self): def totalPot(self):
"""If all bets and blinds have been added, totals up the total pot size """If all bets and blinds have been added, totals up the total pot size
Known bug: doesn't take into account side pots""" Known bug: doesn't take into account side pots"""
@ -391,7 +382,7 @@ Known bug: doesn't take into account side pots"""
def printHand(self): def printHand(self):
# PokerStars format. # PokerStars format.
print "### DEBUG ###" print "### Pseudo stars format ###"
print "%s Game #%s: %s ($%s/$%s) - %s" %(self.sitename, self.handid, "XXXXhand.gametype", self.sb, self.bb, self.starttime) print "%s Game #%s: %s ($%s/$%s) - %s" %(self.sitename, self.handid, "XXXXhand.gametype", self.sb, self.bb, self.starttime)
print "Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos) print "Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos)
for player in self.players: for player in self.players:
@ -409,7 +400,8 @@ Known bug: doesn't take into account side pots"""
# 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[self.hero][0], self.holecards[self.hero][1]) if self.involved:
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']:
@ -438,21 +430,39 @@ Known bug: doesn't take into account side pots"""
print "what do they show" print "what do they show"
print "*** SUMMARY ***" print "*** SUMMARY ***"
print "Total pot $%s | Rake $%s)" % (self.totalpot, self.rake) print "Total pot $%s | Rake $%.2f)" % (self.totalpot, self.rake) # TODO side pots
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")) board = []
for s in self.board.values():
board += s
if board: # sometimes hand ends preflop without a board
print "Board [%s]" % (board)
#print self.board #print self.board
for player in self.players: for player in self.players:
if self.holecards[player[1]]: # empty list default is false if player[1] in self.collected and self.holecards[player[1]]:
hole = self.holecards[player[1]] print "Seat %d: %s showed [%s %s] and won ($%s)" % (player[0], player[1], self.holecards[player[1]][0], self.holecards[player[1]][1], self.collected[player[1]])
#print self.board.values() elif player[1] in self.collected:
board = [] print "Seat %d: %s collected ($%s)" % (player[0], player[1], self.collected[player[1]])
for s in self.board.values(): elif self.holecards[player[1]]:
board += s print "Seat %d: %s showed [%s %s]" % (player[0], player[1], self.holecards[player[1]][0], self.holecards[player[1]][1])
playerhand = self.bestHand('hi', board+hole)
print "Seat %d: %s showed %s and won/lost with %s" % (player[0], player[1], hole, playerhand)
else: else:
print "Seat %d: %s mucked or folded" % (player[0], player[1]) print "Seat %d: %s folded (or mucked..)" % (player[0], player[1])
print
# TODO:
# logic for side pots
# logic for which players get to showdown
# I'm just not sure we need to do this so heavily.. and if we do, it's probably better to use pokerlib
#if self.holecards[player[1]]: # empty list default is false
#hole = self.holecards[player[1]]
##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)
#print "Seat %d: %s showed %s" % (player[0], player[1], hole)
#else:
#print "Seat %d: %s mucked or folded" % (player[0], player[1])
def printActionLine(self, act): def printActionLine(self, act):
@ -463,10 +473,8 @@ Known bug: doesn't take into account side pots"""
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 # going to use pokereval to figure out hands at some point.
# these functions are copied from pokergame.py # 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): def bestHand(self, side, cards):
#if self.variant == "omaha" or self.variant == "omaha8": #if self.variant == "omaha" or self.variant == "omaha8":
#hand = self.serial2player[serial].hand.tolist(True) #hand = self.serial2player[serial].hand.tolist(True)
@ -477,38 +485,39 @@ Known bug: doesn't take into account side pots"""
print cards print cards
return HandHistoryConverter.eval.best('hi', cards, []) return HandHistoryConverter.eval.best('hi', cards, [])
# from pokergame.py
def bestHandValue(self, side, serial): def bestHandValue(self, side, serial):
(value, cards) = self.bestHand(side, serial) (value, cards) = self.bestHand(side, serial)
return value return value
# from pokergame.py
# got rid of the _ for internationalisation
def readableHandValueLong(self, side, value, cards): def readableHandValueLong(self, side, value, cards):
cards = self.eval.card2string(cards)
if value == "NoPair": if value == "NoPair":
if side == "low": if side == "low":
if cards[0][0] == '5': if cards[0][0] == '5':
return _("The wheel") return ("The wheel")
else: else:
return join(map(lambda card: card[0], cards), ", ") return join(map(lambda card: card[0], cards), ", ")
else: else:
return _("High card %(card)s") % { 'card' : _(letter2name[cards[0][0]]) } return ("High card %(card)s") % { 'card' : (letter2name[cards[0][0]]) }
elif value == "OnePair": elif value == "OnePair":
return _("A pair of %(card)s") % { 'card' : _(letter2names[cards[0][0]]) } + _(", %(card)s kicker") % { 'card' : _(letter2name[cards[2][0]]) } return ("A pair of %(card)s") % { 'card' : (letter2names[cards[0][0]]) } + (", %(card)s kicker") % { 'card' : (letter2name[cards[2][0]]) }
elif value == "TwoPair": 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]]) } 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": elif value == "Trips":
return _("Three of a kind %(card)s") % { 'card' : _(letter2names[cards[0][0]]) } + _(", %(card)s kicker") % { 'card' : _(letter2name[cards[3][0]]) } return ("Three of a kind %(card)s") % { 'card' : (letter2names[cards[0][0]]) } + (", %(card)s kicker") % { 'card' : (letter2name[cards[3][0]]) }
elif value == "Straight": elif value == "Straight":
return _("Straight %(card1)s to %(card2)s") % { 'card1' : _(letter2name[cards[0][0]]), 'card2' : _(letter2name[cards[4][0]]) } return ("Straight %(card1)s to %(card2)s") % { 'card1' : (letter2name[cards[0][0]]), 'card2' : (letter2name[cards[4][0]]) }
elif value == "Flush": elif value == "Flush":
return _("Flush %(card)s high") % { 'card' : _(letter2name[cards[0][0]]) } return ("Flush %(card)s high") % { 'card' : (letter2name[cards[0][0]]) }
elif value == "FlHouse": elif value == "FlHouse":
return _("%(card1)ss full of %(card2)ss") % { 'card1' : _(letter2name[cards[0][0]]), 'card2' : _(letter2name[cards[3][0]]) } return ("%(card1)ss full of %(card2)ss") % { 'card1' : (letter2name[cards[0][0]]), 'card2' : (letter2name[cards[3][0]]) }
elif value == "Quads": elif value == "Quads":
return _("Four of a kind %(card)s") % { 'card' : _(letter2names[cards[0][0]]) } + _(", %(card)s kicker") % { 'card' : _(letter2name[cards[4][0]]) } return _("Four of a kind %(card)s") % { 'card' : (letter2names[cards[0][0]]) } + (", %(card)s kicker") % { 'card' : (letter2name[cards[4][0]]) }
elif value == "StFlush": elif value == "StFlush":
if letter2name[cards[0][0]] == 'Ace': if letter2name[cards[0][0]] == 'Ace':
return _("Royal flush") return ("Royal flush")
else: else:
return _("Straight flush %(card)s high") % { 'card' : _(letter2name[cards[0][0]]) } return ("Straight flush %(card)s high") % { 'card' : (letter2name[cards[0][0]]) }
return value return value