Merge branch 'master' into monkeyfutz
Everleaf converts hands Moved process hand logic into the hand subclass that knows what it wants, it calls back to the hhc (which knows about the format) to populate itself Conflicts: pyfpdb/EverleafToFpdb.py pyfpdb/Hand.py pyfpdb/HandHistoryConverter.py
This commit is contained in:
commit
5c26bb028d
|
@ -62,6 +62,7 @@ class Site:
|
||||||
self.aux_window = node.getAttribute("aux_window")
|
self.aux_window = node.getAttribute("aux_window")
|
||||||
self.font = node.getAttribute("font")
|
self.font = node.getAttribute("font")
|
||||||
self.font_size = node.getAttribute("font_size")
|
self.font_size = node.getAttribute("font_size")
|
||||||
|
self.use_frames = node.getAttribute("use_frames")
|
||||||
self.layout = {}
|
self.layout = {}
|
||||||
|
|
||||||
for layout_node in node.getElementsByTagName('layout'):
|
for layout_node in node.getElementsByTagName('layout'):
|
||||||
|
@ -466,6 +467,9 @@ class Config:
|
||||||
paths['bulkImport-defaultPath'] = "default"
|
paths['bulkImport-defaultPath'] = "default"
|
||||||
return paths
|
return paths
|
||||||
|
|
||||||
|
def get_frames(self, site = "PokerStars"):
|
||||||
|
return self.supported_sites[site].use_frames == "True"
|
||||||
|
|
||||||
def get_default_colors(self, site = "PokerStars"):
|
def get_default_colors(self, site = "PokerStars"):
|
||||||
colors = {}
|
colors = {}
|
||||||
if self.supported_sites[site].hudopacity == "":
|
if self.supported_sites[site].hudopacity == "":
|
||||||
|
|
|
@ -116,31 +116,30 @@ class Database:
|
||||||
row = c.fetchone()
|
row = c.fetchone()
|
||||||
return row[0]
|
return row[0]
|
||||||
|
|
||||||
# def get_cards(self, hand):
|
|
||||||
# this version is for the PTrackSv2 db
|
|
||||||
# c = self.connection.cursor()
|
|
||||||
# c.execute(self.sql.query['get_cards'], hand)
|
|
||||||
# colnames = [desc[0] for desc in c.description]
|
|
||||||
# cards = {}
|
|
||||||
# for row in c.fetchall():
|
|
||||||
# s_dict = {}
|
|
||||||
# for name, val in zip(colnames, row):
|
|
||||||
# s_dict[name] = val
|
|
||||||
# cards[s_dict['seat_number']] = s_dict
|
|
||||||
# return (cards)
|
|
||||||
|
|
||||||
def get_cards(self, hand):
|
def get_cards(self, hand):
|
||||||
# this version is for the fpdb db
|
"""Get and return the cards for each player in the hand."""
|
||||||
|
cards = {} # dict of cards, the key is the seat number example: {1: 'AcQd9hTs5d'}
|
||||||
c = self.connection.cursor()
|
c = self.connection.cursor()
|
||||||
c.execute(self.sql.query['get_cards'], hand)
|
c.execute(self.sql.query['get_cards'], hand)
|
||||||
colnames = [desc[0] for desc in c.description]
|
colnames = [desc[0] for desc in c.description]
|
||||||
cards = {}
|
|
||||||
for row in c.fetchall():
|
for row in c.fetchall():
|
||||||
s_dict = {}
|
s_dict = {}
|
||||||
for name, val in zip(colnames, row):
|
for name, val in zip(colnames, row):
|
||||||
s_dict[name] = val
|
s_dict[name] = val
|
||||||
cards[s_dict['seat_number']] = s_dict
|
cards[s_dict['seat_number']] = (self.convert_cards(s_dict))
|
||||||
return (cards)
|
return cards
|
||||||
|
|
||||||
|
def convert_cards(self, d):
|
||||||
|
ranks = ('', '', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A')
|
||||||
|
cards = ""
|
||||||
|
for i in range(1, 8):
|
||||||
|
if d['card' + str(i) + 'Value'] == None:
|
||||||
|
break
|
||||||
|
elif d['card' + str(i) + 'Value'] == 0:
|
||||||
|
cards += "xx"
|
||||||
|
else:
|
||||||
|
cards += ranks[d['card' + str(i) + 'Value']] + d['card' +str(i) + 'Suit']
|
||||||
|
return cards
|
||||||
|
|
||||||
def get_action_from_hand(self, hand_no):
|
def get_action_from_hand(self, hand_no):
|
||||||
action = [ [], [], [], [], [] ]
|
action = [ [], [], [], [], [] ]
|
||||||
|
@ -214,6 +213,7 @@ if __name__=="__main__":
|
||||||
for p in stat_dict.keys():
|
for p in stat_dict.keys():
|
||||||
print p, " ", stat_dict[p]
|
print p, " ", stat_dict[p]
|
||||||
|
|
||||||
|
print "cards =", db_connection.get_cards(73525)
|
||||||
db_connection.close_connection
|
db_connection.close_connection
|
||||||
|
|
||||||
print "press enter to continue"
|
print "press enter to continue"
|
||||||
|
|
|
@ -40,23 +40,26 @@ class Everleaf(HandHistoryConverter):
|
||||||
in_path (default '-' = sys.stdin)
|
in_path (default '-' = sys.stdin)
|
||||||
out_path (default '-' = sys.stdout)
|
out_path (default '-' = sys.stdout)
|
||||||
follow : whether to tail -f the input"""
|
follow : whether to tail -f the input"""
|
||||||
super(Everleaf, self).__init__(in_path, out_path, sitename="Everleaf", follow=follow) # Call super class init.
|
HandHistoryConverter.__init__(self, in_path, out_path, sitename="Everleaf", follow=follow)
|
||||||
logging.info("Initialising Everleaf converter class")
|
logging.info("Initialising Everleaf converter class")
|
||||||
self.filetype = "text"
|
self.filetype = "text"
|
||||||
self.codepage = "cp1252"
|
self.codepage = "cp1252"
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def compilePlayerRegexs(self):
|
def compilePlayerRegexs(self, players):
|
||||||
player_re = "(?P<PNAME>" + "|".join(map(re.escape, self.players)) + ")"
|
if not players <= self.compiledPlayers: # x <= y means 'x is subset of y'
|
||||||
logging.debug("player_re: "+ player_re)
|
# we need to recompile the player regexs.
|
||||||
self.re_PostSB = re.compile(r"^%s: posts small blind \[\$? (?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.compiledPlayers = players
|
||||||
self.re_PostBB = re.compile(r"^%s: posts big blind \[\$? (?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
|
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
||||||
self.re_PostBoth = re.compile(r"^%s: posts both blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
logging.debug("player_re: "+ player_re)
|
||||||
self.re_HeroCards = re.compile(r"^Dealt to %s \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
|
self.re_PostSB = re.compile(r"^%s: posts small blind \[\$? (?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_Action = re.compile(r"^%s(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[\$ (?P<BET>[.\d]+) (USD|EUR)\])?" % player_re, re.MULTILINE)
|
self.re_PostBB = re.compile(r"^%s: posts big blind \[\$? (?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_ShowdownAction = re.compile(r"^%s shows \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
|
self.re_PostBoth = re.compile(r"^%s: posts both blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_CollectPot = re.compile(r"^%s wins \$ (?P<POT>[.\d]+) (USD|EUR)(.*?\[ (?P<CARDS>.*?) \])?" % player_re, re.MULTILINE)
|
self.re_HeroCards = re.compile(r"^Dealt to %s \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
|
||||||
self.re_SitsOut = re.compile(r"^%s sits out" % player_re, re.MULTILINE)
|
self.re_Action = re.compile(r"^%s(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[\$ (?P<BET>[.\d]+) (USD|EUR)\])?" % player_re, re.MULTILINE)
|
||||||
|
self.re_ShowdownAction = re.compile(r"^%s shows \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
|
||||||
|
self.re_CollectPot = re.compile(r"^%s wins \$ (?P<POT>[.\d]+) (USD|EUR)(.*?\[ (?P<CARDS>.*?) \])?" % player_re, re.MULTILINE)
|
||||||
|
self.re_SitsOut = re.compile(r"^%s sits out" % player_re, re.MULTILINE)
|
||||||
|
|
||||||
def readSupportedGames(self):
|
def readSupportedGames(self):
|
||||||
return [["ring", "hold", "nl"],
|
return [["ring", "hold", "nl"],
|
||||||
|
@ -69,6 +72,13 @@ follow : whether to tail -f the input"""
|
||||||
# Blinds $0.50/$1 PL Omaha - 2008/12/07 - 21:59:48
|
# Blinds $0.50/$1 PL Omaha - 2008/12/07 - 21:59:48
|
||||||
# Blinds $0.05/$0.10 NL Hold'em - 2009/02/21 - 11:21:57
|
# Blinds $0.05/$0.10 NL Hold'em - 2009/02/21 - 11:21:57
|
||||||
# $0.25/$0.50 7 Card Stud - 2008/12/05 - 21:43:59
|
# $0.25/$0.50 7 Card Stud - 2008/12/05 - 21:43:59
|
||||||
|
|
||||||
|
# Tourney:
|
||||||
|
# Everleaf Gaming Game #75065769
|
||||||
|
# ***** Hand history for game #75065769 *****
|
||||||
|
# Blinds 10/20 NL Hold'em - 2009/02/25 - 17:30:32
|
||||||
|
# Table 2
|
||||||
|
|
||||||
structure = "" # nl, pl, cn, cp, fl
|
structure = "" # nl, pl, cn, cp, fl
|
||||||
game = ""
|
game = ""
|
||||||
|
|
||||||
|
@ -95,84 +105,89 @@ follow : whether to tail -f the input"""
|
||||||
return gametype
|
return gametype
|
||||||
|
|
||||||
def readHandInfo(self, hand):
|
def readHandInfo(self, hand):
|
||||||
m = self.re_HandInfo.search(hand.string)
|
m = self.re_HandInfo.search(hand.handText)
|
||||||
if(m == None):
|
if(m == None):
|
||||||
logging.info("Didn't match re_HandInfo")
|
logging.info("Didn't match re_HandInfo")
|
||||||
logging.info(hand.handtext)
|
logging.info(hand.handtext)
|
||||||
return None
|
return None
|
||||||
logging.debug("HID %s" % m.group('HID'))
|
logging.debug("HID %s, Table %s" % (m.group('HID'), m.group('TABLE')))
|
||||||
hand.handid = m.group('HID')
|
hand.handid = m.group('HID')
|
||||||
|
hand.tablename = m.group('TABLE')
|
||||||
hand.maxseats = 6 # assume 6-max unless we have proof it's a larger/smaller game, since everleaf doesn't give seat max info
|
hand.maxseats = 6 # assume 6-max unless we have proof it's a larger/smaller game, since everleaf doesn't give seat max info
|
||||||
|
|
||||||
# Believe Everleaf time is GMT/UTC, no transation necessary
|
# Believe Everleaf time is GMT/UTC, no transation necessary
|
||||||
# Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET]
|
# Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET]
|
||||||
# or : 2008/11/07 12:38:49 ET
|
# or : 2008/11/07 12:38:49 ET
|
||||||
# Not getting it in my HH files yet, so using
|
# Not getting it in my HH files yet, so using
|
||||||
# 2008/11/10 3:58:52 ET
|
# 2008/11/10 3:58:52 ET
|
||||||
#TODO: Do conversion from GMT to ET
|
#TODO: Do conversion from GMT to ET
|
||||||
#TODO: Need some date functions to convert to different timezones (Date::Manip for perl rocked for this)
|
#TODO: Need some date functions to convert to different timezones (Date::Manip for perl rocked for this)
|
||||||
hand.starttime = time.strptime(m.group('DATETIME'), "%Y/%m/%d - %H:%M:%S")
|
hand.starttime = time.strptime(m.group('DATETIME'), "%Y/%m/%d - %H:%M:%S")
|
||||||
return
|
return
|
||||||
#return({'HID': m.group('HID'), 'table':m.group('TABLE'), 'max_seats':6})
|
|
||||||
|
|
||||||
def readPlayerStacks(self, hand):
|
def readPlayerStacks(self, hand):
|
||||||
m = self.re_PlayerInfo.finditer(hand.string)
|
m = self.re_PlayerInfo.finditer(hand.handText)
|
||||||
for a in m:
|
for a in m:
|
||||||
seatnum = int(a.group('SEAT'))
|
seatnum = int(a.group('SEAT'))
|
||||||
hand.addPlayer(seatnum, a.group('PNAME'), a.group('CASH'))
|
hand.addPlayer(seatnum, a.group('PNAME'), a.group('CASH'))
|
||||||
if seatnum > 6:
|
if seatnum > 6:
|
||||||
hand.max_seats = 10 # everleaf currently does 2/6/10 games, so if seats > 6 are in use, it must be 10-max.
|
hand.maxseats = 10 # everleaf currently does 2/6/10 games, so if seats > 6 are in use, it must be 10-max.
|
||||||
# TODO: implement lookup list by table-name to determine maxes, then fall back to 6 default/10 here, if there's no entry in the list?
|
# TODO: implement lookup list by table-name to determine maxes, then fall back to 6 default/10 here, if there's no entry in the list?
|
||||||
|
|
||||||
|
|
||||||
def markStreets(self, hand):
|
def markStreets(self, hand):
|
||||||
# PREFLOP = ** Dealing down cards **
|
# PREFLOP = ** Dealing down cards **
|
||||||
# This re fails if, say, river is missing; then we don't get the ** that starts the river.
|
# This re fails if, say, river is missing; then we don't get the ** that starts the river.
|
||||||
#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)
|
#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.handText,re.DOTALL)
|
||||||
|
|
||||||
m = re.search(r"\*\* Dealing down cards \*\*(?P<PREFLOP>.+(?=\*\* Dealing Flop \*\*)|.+)"
|
m = re.search(r"\*\* Dealing down cards \*\*(?P<PREFLOP>.+(?=\*\* Dealing Flop \*\*)|.+)"
|
||||||
r"(\*\* Dealing Flop \*\*(?P<FLOP> \[ \S\S, \S\S, \S\S \].+(?=\*\* Dealing Turn \*\*)|.+))?"
|
r"(\*\* Dealing Flop \*\*(?P<FLOP> \[ \S\S, \S\S, \S\S \].+(?=\*\* Dealing Turn \*\*)|.+))?"
|
||||||
r"(\*\* Dealing Turn \*\*(?P<TURN> \[ \S\S \].+(?=\*\* Dealing River \*\*)|.+))?"
|
r"(\*\* Dealing Turn \*\*(?P<TURN> \[ \S\S \].+(?=\*\* Dealing River \*\*)|.+))?"
|
||||||
r"(\*\* Dealing River \*\*(?P<RIVER> \[ \S\S \].+))?", hand.string,re.DOTALL)
|
r"(\*\* Dealing River \*\*(?P<RIVER> \[ \S\S \].+))?", hand.handText,re.DOTALL)
|
||||||
|
|
||||||
hand.addStreets(m)
|
hand.addStreets(m)
|
||||||
|
|
||||||
|
|
||||||
def readCommunityCards(self, hand, street): # street has been matched by markStreets, so exists in this hand
|
def readCommunityCards(self, hand, street): # street has been matched by markStreets, so exists in this hand
|
||||||
if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP)
|
# If this has been called, street is a street which gets dealt community cards by type hand
|
||||||
m = self.re_Board.search(hand.streets.group(street))
|
# but it might be worth checking somehow.
|
||||||
hand.setCommunityCards(street, m.group('CARDS').split(', '))
|
# if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP)
|
||||||
|
m = self.re_Board.search(hand.streets[street])
|
||||||
|
cards = m.group('CARDS')
|
||||||
|
cards = [card.strip() for card in cards.split(',')]
|
||||||
|
hand.setCommunityCards(street, cards)
|
||||||
|
|
||||||
def readBlinds(self, hand):
|
def readBlinds(self, hand):
|
||||||
m = self.re_PostSB.search(hand.string)
|
m = self.re_PostSB.search(hand.handText)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB'))
|
hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB'))
|
||||||
else:
|
else:
|
||||||
logging.debug("No small blind")
|
logging.debug("No small blind")
|
||||||
hand.addBlind(None, None, None)
|
hand.addBlind(None, None, None)
|
||||||
for a in self.re_PostBB.finditer(hand.string):
|
for a in self.re_PostBB.finditer(hand.handText):
|
||||||
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
|
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
|
||||||
for a in self.re_PostBoth.finditer(hand.string):
|
for a in self.re_PostBoth.finditer(hand.handText):
|
||||||
hand.addBlind(a.group('PNAME'), 'both', a.group('SBBB'))
|
hand.addBlind(a.group('PNAME'), 'both', a.group('SBBB'))
|
||||||
|
|
||||||
def readButton(self, hand):
|
def readButton(self, hand):
|
||||||
hand.buttonpos = int(self.re_Button.search(hand.string).group('BUTTON'))
|
hand.buttonpos = int(self.re_Button.search(hand.handText).group('BUTTON'))
|
||||||
|
|
||||||
def readHeroCards(self, hand):
|
def readHeroCards(self, hand):
|
||||||
m = self.re_HeroCards.search(hand.string)
|
m = self.re_HeroCards.search(hand.handText)
|
||||||
if(m == None):
|
if m:
|
||||||
#Not involved in hand
|
|
||||||
hand.involved = False
|
|
||||||
else:
|
|
||||||
hand.hero = m.group('PNAME')
|
hand.hero = m.group('PNAME')
|
||||||
# "2c, qh" -> set(["2c","qc"])
|
# "2c, qh" -> ["2c","qc"]
|
||||||
# Also works with Omaha hands.
|
# Also works with Omaha hands.
|
||||||
cards = m.group('CARDS')
|
cards = m.group('CARDS')
|
||||||
cards = set(cards.split(', '))
|
cards = [card.strip() for card in cards.split(',')]
|
||||||
hand.addHoleCards(cards, m.group('PNAME'))
|
hand.addHoleCards(cards, m.group('PNAME'))
|
||||||
|
else:
|
||||||
|
#Not involved in hand
|
||||||
|
hand.involved = False
|
||||||
|
|
||||||
|
|
||||||
def readAction(self, hand, street):
|
def readAction(self, hand, street):
|
||||||
m = self.re_Action.finditer(hand.streets.group(street))
|
m = self.re_Action.finditer(hand.streets[street])
|
||||||
for action in m:
|
for action in m:
|
||||||
if action.group('ATYPE') == ' raises':
|
if action.group('ATYPE') == ' raises':
|
||||||
hand.addCallandRaise( street, action.group('PNAME'), action.group('BET') )
|
hand.addCallandRaise( street, action.group('PNAME'), action.group('BET') )
|
||||||
|
@ -189,20 +204,22 @@ follow : whether to tail -f the input"""
|
||||||
|
|
||||||
|
|
||||||
def readShowdownActions(self, hand):
|
def readShowdownActions(self, hand):
|
||||||
for shows in self.re_ShowdownAction.finditer(hand.string):
|
"""Reads lines where holecards are reported in a showdown"""
|
||||||
|
for shows in self.re_ShowdownAction.finditer(hand.handText):
|
||||||
cards = shows.group('CARDS')
|
cards = shows.group('CARDS')
|
||||||
cards = set(cards.split(', '))
|
cards = cards.split(', ')
|
||||||
hand.addShownCards(cards, shows.group('PNAME'))
|
hand.addShownCards(cards, shows.group('PNAME'))
|
||||||
|
|
||||||
def readCollectPot(self,hand):
|
def readCollectPot(self,hand):
|
||||||
for m in self.re_CollectPot.finditer(hand.string):
|
for m in self.re_CollectPot.finditer(hand.handText):
|
||||||
hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT'))
|
hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT'))
|
||||||
|
|
||||||
def readShownCards(self,hand):
|
def readShownCards(self,hand):
|
||||||
for m in self.re_CollectPot.finditer(hand.string):
|
"""Reads lines where hole & board cards are mixed to form a hand (summary lines)"""
|
||||||
|
for m in self.re_CollectPot.finditer(hand.handText):
|
||||||
if m.group('CARDS') is not None:
|
if m.group('CARDS') is not None:
|
||||||
cards = m.group('CARDS')
|
cards = m.group('CARDS')
|
||||||
cards = set(cards.split(', '))
|
cards = cards.split(', ')
|
||||||
hand.addShownCards(cards=None, player=m.group('PNAME'), holeandboard=cards)
|
hand.addShownCards(cards=None, player=m.group('PNAME'), holeandboard=cards)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ class FullTilt(HandHistoryConverter):
|
||||||
re_GameInfo = re.compile('- \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (Ante \$(?P<ANTE>[.0-9]+) )?- (?P<LTYPE>(No|Pot)? )?Limit (?P<GAME>(Hold\'em|Omaha|Razz))')
|
re_GameInfo = re.compile('- \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (Ante \$(?P<ANTE>[.0-9]+) )?- (?P<LTYPE>(No|Pot)? )?Limit (?P<GAME>(Hold\'em|Omaha|Razz))')
|
||||||
re_SplitHands = re.compile(r"\n\n+")
|
re_SplitHands = re.compile(r"\n\n+")
|
||||||
re_HandInfo = re.compile('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[- a-zA-Z]+) (\((?P<TABLEATTRIBUTES>.+)\) )?- \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (Ante \$(?P<ANTE>[.0-9]+) )?- (?P<GAMETYPE>[a-zA-Z\' ]+) - (?P<DATETIME>.*)')
|
re_HandInfo = re.compile('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[- a-zA-Z]+) (\((?P<TABLEATTRIBUTES>.+)\) )?- \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (Ante \$(?P<ANTE>[.0-9]+) )?- (?P<GAMETYPE>[a-zA-Z\' ]+) - (?P<DATETIME>.*)')
|
||||||
re_Button = re.compile('^The button is in seat #(?P<BUTTON>\d+)')
|
re_Button = re.compile('^The button is in seat #(?P<BUTTON>\d+)', re.MULTILINE)
|
||||||
re_PlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\$(?P<CASH>[.0-9]+)\)\n')
|
re_PlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\$(?P<CASH>[.0-9]+)\)\n')
|
||||||
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
||||||
|
|
||||||
|
@ -43,9 +43,10 @@ class FullTilt(HandHistoryConverter):
|
||||||
print "DEBUG player_re: " + player_re
|
print "DEBUG player_re: " + player_re
|
||||||
self.re_PostSB = re.compile(r"^%s posts the small blind of \$?(?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostSB = re.compile(r"^%s posts the small blind of \$?(?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_PostBB = re.compile(r"^%s posts (the big blind of )?\$?(?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostBB = re.compile(r"^%s posts (the big blind of )?\$?(?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
|
self.re_Antes = re.compile(r"^%s antes \$?(?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_BringIn = re.compile(r"^%s brings in for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_BringIn = re.compile(r"^%s brings in for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_PostBoth = re.compile(r"^%s posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostBoth = re.compile(r"^%s posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_HeroCards = re.compile(r"^Dealt to %s \[(?P<CARDS>.*)\]( \[(?P<NEWCARD>.*)\])?" % player_re, re.MULTILINE)
|
self.re_HeroCards = re.compile(r"^Dealt to %s \[(?P<CARDS>[AKQJT0-9hcsd ]+)\]( \[(?P<NEWCARD>[AKQJT0-9hcsd ]+)\])?" % player_re, re.MULTILINE)
|
||||||
self.re_Action = re.compile(r"^%s(?P<ATYPE> bets| checks| raises to| calls| folds)(\s\$(?P<BET>[.\d]+))?" % player_re, re.MULTILINE)
|
self.re_Action = re.compile(r"^%s(?P<ATYPE> bets| checks| raises to| calls| folds)(\s\$(?P<BET>[.\d]+))?" % player_re, re.MULTILINE)
|
||||||
self.re_ShowdownAction = re.compile(r"^%s shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
self.re_ShowdownAction = re.compile(r"^%s shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
||||||
self.re_CollectPot = re.compile(r"^Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(\$(?P<POT>[.\d]+)\)(, mucked| with.*)" % player_re, re.MULTILINE)
|
self.re_CollectPot = re.compile(r"^Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(\$(?P<POT>[.\d]+)\)(, mucked| with.*)" % player_re, re.MULTILINE)
|
||||||
|
@ -155,13 +156,17 @@ class FullTilt(HandHistoryConverter):
|
||||||
|
|
||||||
def readAntes(self, hand):
|
def readAntes(self, hand):
|
||||||
print "DEBUG: reading antes"
|
print "DEBUG: reading antes"
|
||||||
print "DEBUG: FIXME reading antes"
|
m = self.re_Antes.finditer(hand.string)
|
||||||
|
for player in m:
|
||||||
|
print "DEBUG: hand.addAnte(%s,%s)" %(player.group('PNAME'), player.group('ANTE'))
|
||||||
|
hand.addAnte(player.group('PNAME'), player.group('ANTE'))
|
||||||
|
|
||||||
def readBringIn(self, hand):
|
def readBringIn(self, hand):
|
||||||
print "DEBUG: reading bring in"
|
print "DEBUG: reading bring in"
|
||||||
# print hand.string
|
# print hand.string
|
||||||
m = self.re_BringIn.search(hand.string,re.DOTALL)
|
m = self.re_BringIn.search(hand.string,re.DOTALL)
|
||||||
print "DEBUG: Player bringing in: %s for %s" %(m.group('PNAME'), m.group('BRINGIN'))
|
print "DEBUG: Player bringing in: %s for %s" %(m.group('PNAME'), m.group('BRINGIN'))
|
||||||
|
hand.addBringIn(m.group('PNAME'), m.group('BRINGIN'))
|
||||||
|
|
||||||
def readButton(self, hand):
|
def readButton(self, hand):
|
||||||
hand.buttonpos = int(self.re_Button.search(hand.string).group('BUTTON'))
|
hand.buttonpos = int(self.re_Button.search(hand.string).group('BUTTON'))
|
||||||
|
@ -183,16 +188,15 @@ class FullTilt(HandHistoryConverter):
|
||||||
#Used for stud hands - borrows the HeroCards regex for now.
|
#Used for stud hands - borrows the HeroCards regex for now.
|
||||||
m = self.re_HeroCards.finditer(hand.streets.group(street))
|
m = self.re_HeroCards.finditer(hand.streets.group(street))
|
||||||
print "DEBUG: razz/stud readPlayerCards"
|
print "DEBUG: razz/stud readPlayerCards"
|
||||||
print "DEBUG: STREET: %s", street
|
print hand.streets.group(street)
|
||||||
for player in m:
|
for player in m:
|
||||||
print player.groups()
|
print player.groups()
|
||||||
#hand.hero = m.group('PNAME')
|
|
||||||
# "2c, qh" -> set(["2c","qc"])
|
|
||||||
# Also works with Omaha hands.
|
|
||||||
cards = player.group('CARDS')
|
cards = player.group('CARDS')
|
||||||
print "DEBUG: PNAME: %s CARDS: %s" %(player.group('PNAME'), player.group('CARDS'))
|
if player.group('NEWCARD') != None:
|
||||||
|
print cards
|
||||||
|
cards = cards + " " + player.group('NEWCARD')
|
||||||
cards = set(cards.split(' '))
|
cards = set(cards.split(' '))
|
||||||
# hand.addHoleCards(cards, m.group('PNAME'))
|
hand.addPlayerCards(cards, player.group('PNAME'))
|
||||||
|
|
||||||
def readAction(self, hand, street):
|
def readAction(self, hand, street):
|
||||||
m = self.re_Action.finditer(hand.streets.group(street))
|
m = self.re_Action.finditer(hand.streets.group(street))
|
||||||
|
|
|
@ -35,6 +35,20 @@ import Configuration
|
||||||
|
|
||||||
class GuiBulkImport():
|
class GuiBulkImport():
|
||||||
|
|
||||||
|
def import_dir(self):
|
||||||
|
"""imports a directory, non-recursive. todo: move this to fpdb_import so CLI can use it"""
|
||||||
|
|
||||||
|
self.path = self.inputFile
|
||||||
|
self.importer.addImportDirectory(self.path)
|
||||||
|
self.importer.setCallHud(False)
|
||||||
|
starttime = time()
|
||||||
|
if not self.importer.settings['threads'] > 1:
|
||||||
|
(stored, dups, partial, errs, ttime) = self.importer.runImport()
|
||||||
|
print 'GuiBulkImport.import_dir done: Stored: %d Duplicates: %d Partial: %d Errors: %d in %s seconds - %d/sec'\
|
||||||
|
% (stored, dups, partial, errs, ttime, stored / ttime)
|
||||||
|
else:
|
||||||
|
self.importer.RunImportThreaded()
|
||||||
|
|
||||||
def load_clicked(self, widget, data=None):
|
def load_clicked(self, widget, data=None):
|
||||||
# get the dir to import from the chooser
|
# get the dir to import from the chooser
|
||||||
self.inputFile = self.chooser.get_filename()
|
self.inputFile = self.chooser.get_filename()
|
||||||
|
@ -66,6 +80,7 @@ class GuiBulkImport():
|
||||||
self.lab_info.set_text("Import finished")
|
self.lab_info.set_text("Import finished")
|
||||||
|
|
||||||
def get_vbox(self):
|
def get_vbox(self):
|
||||||
|
"""returns the vbox of this thread"""
|
||||||
return self.vbox
|
return self.vbox
|
||||||
|
|
||||||
def __init__(self, db, settings, config):
|
def __init__(self, db, settings, config):
|
||||||
|
|
|
@ -29,6 +29,11 @@ Main for FreePokerTools HUD.
|
||||||
|
|
||||||
# Standard Library modules
|
# Standard Library modules
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
# redirect the stderr
|
||||||
|
errorfile = open('HUD-error.txt', 'w', 0)
|
||||||
|
sys.stderr = errorfile
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import thread
|
import thread
|
||||||
import time
|
import time
|
||||||
|
@ -72,7 +77,7 @@ class HUD_main(object):
|
||||||
def destroy(*args): # call back for terminating the main eventloop
|
def destroy(*args): # call back for terminating the main eventloop
|
||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
|
|
||||||
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, is_tournament, stat_dict):
|
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, is_tournament, stat_dict, cards):
|
||||||
|
|
||||||
def idle_func():
|
def idle_func():
|
||||||
|
|
||||||
|
@ -82,20 +87,21 @@ class HUD_main(object):
|
||||||
self.vb.add(newlabel)
|
self.vb.add(newlabel)
|
||||||
newlabel.show()
|
newlabel.show()
|
||||||
|
|
||||||
self.hud_dict[table_name] = Hud.Hud(self, table, max, poker_game, self.config, self.db_connection)
|
|
||||||
self.hud_dict[table_name].tablehudlabel = newlabel
|
self.hud_dict[table_name].tablehudlabel = newlabel
|
||||||
self.hud_dict[table_name].create(new_hand_id, self.config, stat_dict)
|
self.hud_dict[table_name].create(new_hand_id, self.config, stat_dict, cards)
|
||||||
for m in self.hud_dict[table_name].aux_windows:
|
for m in self.hud_dict[table_name].aux_windows:
|
||||||
m.update_data(new_hand_id, self.db_connection)
|
m.update_data(new_hand_id, self.db_connection)
|
||||||
m.update_gui(new_hand_id)
|
m.update_gui(new_hand_id)
|
||||||
self.hud_dict[table_name].update(new_hand_id, self.config, stat_dict)
|
self.hud_dict[table_name].update(new_hand_id, self.config)
|
||||||
self.hud_dict[table_name].reposition_windows()
|
self.hud_dict[table_name].reposition_windows()
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
gtk.gdk.threads_leave()
|
gtk.gdk.threads_leave()
|
||||||
|
|
||||||
|
self.hud_dict[table_name] = Hud.Hud(self, table, max, poker_game, self.config, self.db_connection)
|
||||||
gobject.idle_add(idle_func)
|
gobject.idle_add(idle_func)
|
||||||
|
|
||||||
def update_HUD(self, new_hand_id, table_name, config, stat_dict):
|
def update_HUD(self, new_hand_id, table_name, config):
|
||||||
"""Update a HUD gui from inside the non-gui read_stdin thread."""
|
"""Update a HUD gui from inside the non-gui read_stdin thread."""
|
||||||
# This is written so that only 1 thread can touch the gui--mainly
|
# This is written so that only 1 thread can touch the gui--mainly
|
||||||
# for compatibility with Windows. This method dispatches the
|
# for compatibility with Windows. This method dispatches the
|
||||||
|
@ -103,7 +109,7 @@ class HUD_main(object):
|
||||||
def idle_func():
|
def idle_func():
|
||||||
gtk.gdk.threads_enter()
|
gtk.gdk.threads_enter()
|
||||||
try:
|
try:
|
||||||
self.hud_dict[table_name].update(new_hand_id, config, stat_dict)
|
self.hud_dict[table_name].update(new_hand_id, config)
|
||||||
for m in self.hud_dict[table_name].aux_windows:
|
for m in self.hud_dict[table_name].aux_windows:
|
||||||
m.update_gui(new_hand_id)
|
m.update_gui(new_hand_id)
|
||||||
return False
|
return False
|
||||||
|
@ -145,6 +151,7 @@ class HUD_main(object):
|
||||||
try:
|
try:
|
||||||
(table_name, max, poker_game) = self.db_connection.get_table_name(new_hand_id)
|
(table_name, max, poker_game) = self.db_connection.get_table_name(new_hand_id)
|
||||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id)
|
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id)
|
||||||
|
cards = self.db_connection.get_cards(new_hand_id)
|
||||||
except:
|
except:
|
||||||
print "skipping ", new_hand_id
|
print "skipping ", new_hand_id
|
||||||
sys.stderr.write("Database error in hand %d. Skipping.\n" % int(new_hand_id))
|
sys.stderr.write("Database error in hand %d. Skipping.\n" % int(new_hand_id))
|
||||||
|
@ -163,9 +170,11 @@ class HUD_main(object):
|
||||||
|
|
||||||
# Update an existing HUD
|
# Update an existing HUD
|
||||||
if temp_key in self.hud_dict:
|
if temp_key in self.hud_dict:
|
||||||
|
self.hud_dict[temp_key].stat_dict = stat_dict
|
||||||
|
self.hud_dict[temp_key].cards = cards
|
||||||
for aw in self.hud_dict[temp_key].aux_windows:
|
for aw in self.hud_dict[temp_key].aux_windows:
|
||||||
aw.update_data(new_hand_id, self.db_connection)
|
aw.update_data(new_hand_id, self.db_connection)
|
||||||
self.update_HUD(new_hand_id, temp_key, self.config, stat_dict)
|
self.update_HUD(new_hand_id, temp_key, self.config)
|
||||||
|
|
||||||
# Or create a new HUD
|
# Or create a new HUD
|
||||||
else:
|
else:
|
||||||
|
@ -175,11 +184,12 @@ class HUD_main(object):
|
||||||
tablewindow = Tables.discover_table_by_name(self.config, table_name)
|
tablewindow = Tables.discover_table_by_name(self.config, table_name)
|
||||||
|
|
||||||
if tablewindow == None:
|
if tablewindow == None:
|
||||||
|
# If no client window is found on the screen, complain and continue
|
||||||
if is_tournament:
|
if is_tournament:
|
||||||
table_name = tour_number + " " + tab_number
|
table_name = tour_number + " " + tab_number
|
||||||
sys.stderr.write("table name "+table_name+" not found, skipping.\n")
|
sys.stderr.write("table name "+table_name+" not found, skipping.\n")
|
||||||
else:
|
else:
|
||||||
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, is_tournament, stat_dict)
|
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, is_tournament, stat_dict, cards)
|
||||||
|
|
||||||
if __name__== "__main__":
|
if __name__== "__main__":
|
||||||
sys.stderr.write("HUD_main starting\n")
|
sys.stderr.write("HUD_main starting\n")
|
||||||
|
|
326
pyfpdb/Hand.py
326
pyfpdb/Hand.py
|
@ -15,38 +15,25 @@
|
||||||
#In the "official" distribution you can find the license in
|
#In the "official" distribution you can find the license in
|
||||||
#agpl-3.0.txt in the docs folder of the package.
|
#agpl-3.0.txt in the docs folder of the package.
|
||||||
|
|
||||||
|
|
||||||
import Hand
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import xml.dom.minidom
|
|
||||||
import codecs
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
import operator
|
import operator
|
||||||
import time
|
import time
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from Exceptions import *
|
||||||
|
|
||||||
class Hand:
|
class Hand:
|
||||||
# def __init__(self, sitename, gametype, sb, bb, string):
|
|
||||||
|
|
||||||
UPS = {'a':'A', 't':'T', 'j':'J', 'q':'Q', 'k':'K', 'S':'s', 'C':'c', 'H':'h', 'D':'d'}
|
UPS = {'a':'A', 't':'T', 'j':'J', 'q':'Q', 'k':'K', 'S':'s', 'C':'c', 'H':'h', 'D':'d'}
|
||||||
def __init__(self, sitename, gametype, handtext):
|
def __init__(self, sitename, gametype, handText):
|
||||||
self.sitename = sitename
|
self.sitename = sitename
|
||||||
self.gametype = gametype
|
self.gametype = gametype
|
||||||
self.string = handtext
|
self.handText = handText
|
||||||
|
|
||||||
if gametype[1] == "hold" or self.gametype[1] == "omaha":
|
|
||||||
self.streetList = ['PREFLOP','FLOP','TURN','RIVER'] # a list of the observed street names in order
|
|
||||||
elif self.gametype[1] == "razz" or self.gametype[1] == "stud" or self.gametype[1] == "stud8":
|
|
||||||
self.streetList = ['ANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH'] # a list of the observed street names in order
|
|
||||||
|
|
||||||
self.handid = 0
|
self.handid = 0
|
||||||
self.sb = gametype[3]
|
|
||||||
self.bb = gametype[4]
|
|
||||||
self.tablename = "Slartibartfast"
|
self.tablename = "Slartibartfast"
|
||||||
self.hero = "Hiro"
|
self.hero = "Hiro"
|
||||||
self.maxseats = 10
|
self.maxseats = 10
|
||||||
|
@ -56,38 +43,26 @@ class Hand:
|
||||||
self.players = []
|
self.players = []
|
||||||
self.posted = []
|
self.posted = []
|
||||||
self.involved = True
|
self.involved = True
|
||||||
|
|
||||||
self.pot = Pot()
|
self.pot = Pot()
|
||||||
|
|
||||||
#
|
|
||||||
# Collections indexed by street names
|
# Collections indexed by street names
|
||||||
#
|
self.bets = {}
|
||||||
|
self.lastBet = {}
|
||||||
|
self.streets = {}
|
||||||
|
self.actions = {} # [['mct','bets','$10'],['mika','folds'],['carlg','raises','$20']]
|
||||||
|
for street in self.streetList:
|
||||||
|
self.streets[street] = "" # portions of the handText, filled by markStreets()
|
||||||
|
self.bets[street] = {}
|
||||||
|
self.lastBet[street] = 0
|
||||||
|
self.actions[street] = []
|
||||||
|
|
||||||
# A MatchObject using a groupnames to identify streets.
|
self.board = {} # dict from street names to community cards
|
||||||
# filled by markStreets()
|
|
||||||
self.streets = None
|
|
||||||
|
|
||||||
# dict from street names to lists of tuples, such as
|
|
||||||
# [['mct','bets','$10'],['mika','folds'],['carlg','raises','$20']]
|
|
||||||
# actually they're clearly lists but they probably should be tuples.
|
|
||||||
self.actions = {}
|
|
||||||
|
|
||||||
# dict from street names to community cards
|
|
||||||
self.board = {}
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Collections indexed by player names
|
# Collections indexed by player names
|
||||||
#
|
self.holecards = {} # dict from player names to lists of hole cards
|
||||||
|
|
||||||
# dict from player names to lists of hole cards
|
|
||||||
self.holecards = {}
|
|
||||||
|
|
||||||
self.stacks = {}
|
self.stacks = {}
|
||||||
|
self.collected = [] #list of ?
|
||||||
# dict from player names to amounts collected
|
self.collectees = {} # dict from player names to amounts collected (?)
|
||||||
self.collected = []
|
|
||||||
self.collectees = {}
|
|
||||||
|
|
||||||
# Sets of players
|
# Sets of players
|
||||||
self.shown = set()
|
self.shown = set()
|
||||||
|
@ -99,11 +74,7 @@ class Hand:
|
||||||
|
|
||||||
self.rake = None
|
self.rake = None
|
||||||
|
|
||||||
self.bets = {}
|
|
||||||
self.lastBet = {}
|
|
||||||
for street in self.streetList:
|
|
||||||
self.bets[street] = {}
|
|
||||||
self.lastBet[street] = 0
|
|
||||||
|
|
||||||
def addPlayer(self, seat, name, chips):
|
def addPlayer(self, seat, name, chips):
|
||||||
"""\
|
"""\
|
||||||
|
@ -115,7 +86,7 @@ If a player has None chips he won't be added."""
|
||||||
if chips is not None:
|
if chips is not None:
|
||||||
self.players.append([seat, name, chips])
|
self.players.append([seat, name, chips])
|
||||||
self.stacks[name] = Decimal(chips)
|
self.stacks[name] = Decimal(chips)
|
||||||
self.holecards[name] = set()
|
self.holecards[name] = []
|
||||||
self.pot.addPlayer(name)
|
self.pot.addPlayer(name)
|
||||||
for street in self.streetList:
|
for street in self.streetList:
|
||||||
self.bets[street][name] = []
|
self.bets[street][name] = []
|
||||||
|
@ -124,21 +95,34 @@ If a player has None chips he won't be added."""
|
||||||
def addStreets(self, match):
|
def addStreets(self, match):
|
||||||
# go through m and initialise actions to empty list for each street.
|
# go through m and initialise actions to empty list for each street.
|
||||||
if match is not None:
|
if match is not None:
|
||||||
self.streets = match
|
self.streets.update(match.groupdict())
|
||||||
for street in match.groupdict():
|
logging.debug(self.streets)
|
||||||
if match.group(street) is not None:
|
|
||||||
self.actions[street] = []
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logging.error("markstreets didn't match")
|
logging.error("markstreets didn't match")
|
||||||
|
|
||||||
def addHoleCards(self, cards, player):
|
def addHoleCards(self, cards, player):
|
||||||
"""\
|
"""\
|
||||||
Assigns observed holecards to a player.
|
Assigns observed holecards to a player.
|
||||||
cards set of card bigrams e.g. set(['2h','Jc'])
|
cards list of card bigrams e.g. ['2h','Jc']
|
||||||
player (string) name of player
|
player (string) name of player
|
||||||
"""
|
"""
|
||||||
#print "DEBUG: addHoleCards", cards,player
|
#print "DEBUG: addHoleCards", cards,player
|
||||||
|
try:
|
||||||
|
self.checkPlayerExists(player)
|
||||||
|
cards = set([self.card(c) for c in cards])
|
||||||
|
self.holecards[player].extend(cards)
|
||||||
|
except FpdbParseError, e:
|
||||||
|
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
|
||||||
|
def addPlayerCards(self, cards, player):
|
||||||
|
"""\
|
||||||
|
Assigns observed cards to a player.
|
||||||
|
cards list of card bigrams e.g. ['2h','Jc']
|
||||||
|
player (string) name of player
|
||||||
|
|
||||||
|
Should probably be merged with addHoleCards
|
||||||
|
"""
|
||||||
|
logging.debug("addPlayerCards %s, %s" % ( cards,player))
|
||||||
try:
|
try:
|
||||||
self.checkPlayerExists(player)
|
self.checkPlayerExists(player)
|
||||||
cards = set([self.card(c) for c in cards])
|
cards = set([self.card(c) for c in cards])
|
||||||
|
@ -185,25 +169,31 @@ Card ranks will be uppercased
|
||||||
c = c.replace(k,v)
|
c = c.replace(k,v)
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
def addAnte(self, player, ante):
|
||||||
|
if player is not None:
|
||||||
|
self.bets['ANTES'][player].append(Decimal(ante))
|
||||||
|
self.stacks[player] -= Decimal(ante)
|
||||||
|
act = (player, 'posts', "ante", ante, self.stacks[player]==0)
|
||||||
|
self.actions['ANTES'].append(act)
|
||||||
|
self.pot.addMoney(player, Decimal(ante))
|
||||||
|
|
||||||
def addBlind(self, player, blindtype, amount):
|
def addBlind(self, player, blindtype, amount):
|
||||||
# if player is None, it's a missing small blind.
|
# if player is None, it's a missing small blind.
|
||||||
# TODO:
|
|
||||||
# The situation we need to cover are:
|
# The situation we need to cover are:
|
||||||
# Player in small blind posts
|
# Player in small blind posts
|
||||||
# - this is a bet of 1 sb, as yet uncalled.
|
# - this is a bet of 1 sb, as yet uncalled.
|
||||||
# Player in the big blind posts
|
# Player in the big blind posts
|
||||||
# - this is a bet of 1 bb and is the new uncalled
|
# - this is a call of 1 sb and a raise to 1 bb
|
||||||
#
|
#
|
||||||
# If a player posts a big & small blind
|
|
||||||
# - FIXME: We dont record this for later printing yet
|
|
||||||
|
|
||||||
#print "DEBUG addBlind: %s posts %s, %s" % (player, blindtype, amount)
|
|
||||||
|
logging.debug("addBlind: %s posts %s, %s" % (player, blindtype, amount))
|
||||||
if player is not None:
|
if player is not None:
|
||||||
self.bets['PREFLOP'][player].append(Decimal(amount))
|
self.bets['PREFLOP'][player].append(Decimal(amount))
|
||||||
self.stacks[player] -= Decimal(amount)
|
self.stacks[player] -= Decimal(amount)
|
||||||
#print "DEBUG %s posts, stack %s" % (player, self.stacks[player])
|
#print "DEBUG %s posts, stack %s" % (player, self.stacks[player])
|
||||||
act = (player, 'posts', blindtype, amount, self.stacks[player]==0)
|
act = (player, 'posts', blindtype, amount, self.stacks[player]==0)
|
||||||
self.actions['PREFLOP'].append(act)
|
self.actions['BLINDSANTES'].append(act)
|
||||||
self.pot.addMoney(player, Decimal(amount))
|
self.pot.addMoney(player, Decimal(amount))
|
||||||
if blindtype == 'big blind':
|
if blindtype == 'big blind':
|
||||||
self.lastBet['PREFLOP'] = Decimal(amount)
|
self.lastBet['PREFLOP'] = Decimal(amount)
|
||||||
|
@ -214,6 +204,8 @@ Card ranks will be uppercased
|
||||||
#print "DEBUG: self.posted: %s" %(self.posted)
|
#print "DEBUG: self.posted: %s" %(self.posted)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -365,22 +357,69 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
"cp" : "Cap Pot Limit"
|
"cp" : "Cap Pot Limit"
|
||||||
}
|
}
|
||||||
|
|
||||||
logging.debug("DEBUG: self.gametype: %s" %(self.gametype))
|
logging.debug("gametype: %s" %(self.gametype))
|
||||||
string = "%s %s" %(gs[self.gametype[1]], ls[self.gametype[2]])
|
retstring = "%s %s" %(gs[self.gametype[1]], ls[self.gametype[2]])
|
||||||
|
|
||||||
return string
|
return retstring
|
||||||
|
|
||||||
def writeHand(self, fh=sys.__stdout__):
|
def writeHand(self, fh=sys.__stdout__):
|
||||||
if self.gametype[1] == "hold" or self.gametype[1] == "omaha":
|
print >>fh, "Override me"
|
||||||
self.writeHoldemHand(fh)
|
|
||||||
else:
|
|
||||||
self.writeStudHand(fh)
|
|
||||||
|
|
||||||
|
def printHand(self):
|
||||||
|
self.writeHand(sys.stdout)
|
||||||
|
|
||||||
def writeHoldemHand(self, fh=sys.__stdout__):
|
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]))
|
||||||
|
elif act[1] == 'calls':
|
||||||
|
print >>fh, _("%s: calls $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||||
|
elif act[1] == 'bets':
|
||||||
|
print >>fh, _("%s: bets $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||||
|
elif act[1] == 'raises':
|
||||||
|
print >>fh, _("%s: raises $%s to $%s%s" %(act[0], act[2], act[3], ' and is all-in' if act[5] else ''))
|
||||||
|
elif act[1] == 'posts':
|
||||||
|
if(act[2] == "small blind"):
|
||||||
|
print >>fh, _("%s: posts small blind $%s" %(act[0], act[3]))
|
||||||
|
elif(act[2] == "big blind"):
|
||||||
|
print >>fh, _("%s: posts big blind $%s" %(act[0], act[3]))
|
||||||
|
elif(act[2] == "both"):
|
||||||
|
print >>fh, _("%s: posts small & big blinds $%s" %(act[0], act[3]))
|
||||||
|
|
||||||
|
class HoldemOmahaHand(Hand):
|
||||||
|
def __init__(self, hhc, sitename, gametype, handText):
|
||||||
|
if gametype[1] not in ["hold","omaha"]:
|
||||||
|
pass # or indeed don't pass and complain instead
|
||||||
|
self.streetList = ['BLINDSANTES', 'PREFLOP','FLOP','TURN','RIVER'] # a list of the observed street names in order
|
||||||
|
self.communityStreets = ['FLOP', 'TURN', 'RIVER']
|
||||||
|
self.actionStreets = ['PREFLOP','FLOP','TURN','RIVER']
|
||||||
|
Hand.__init__(self, sitename, gametype, handText)
|
||||||
|
self.sb = gametype[3]
|
||||||
|
self.bb = gametype[4]
|
||||||
|
|
||||||
|
hhc.readHandInfo(self)
|
||||||
|
hhc.readPlayerStacks(self)
|
||||||
|
hhc.compilePlayerRegexs(players = set([player[1] for player in self.players]))
|
||||||
|
hhc.markStreets(self)
|
||||||
|
hhc.readBlinds(self)
|
||||||
|
hhc.readButton(self)
|
||||||
|
hhc.readHeroCards(self)
|
||||||
|
hhc.readShowdownActions(self)
|
||||||
|
# Read actions in street order
|
||||||
|
for street in self.communityStreets:
|
||||||
|
if self.streets[street]:
|
||||||
|
hhc.readCommunityCards(self, street)
|
||||||
|
for street in self.actionStreets:
|
||||||
|
if self.streets[street]:
|
||||||
|
hhc.readAction(self, street)
|
||||||
|
hhc.readCollectPot(self)
|
||||||
|
hhc.readShownCards(self)
|
||||||
|
self.totalPot() # finalise it (total the pot)
|
||||||
|
hhc.getRake(self)
|
||||||
|
|
||||||
|
def writeHand(self, fh=sys.__stdout__):
|
||||||
# PokerStars format.
|
# PokerStars format.
|
||||||
#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, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
|
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
|
||||||
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||||
|
|
||||||
|
@ -390,35 +429,29 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
#Only print stacks of players who do something preflop
|
#Only print stacks of players who do something preflop
|
||||||
print >>fh, _("Seat %s: %s ($%s)" %(player[0], player[1], player[2]))
|
print >>fh, _("Seat %s: %s ($%s)" %(player[0], player[1], player[2]))
|
||||||
|
|
||||||
|
if self.actions['BLINDSANTES']:
|
||||||
#May be more than 1 bb posting
|
for act in self.actions['BLINDSANTES']:
|
||||||
for a in self.posted:
|
self.printActionLine(act, fh)
|
||||||
if(a[1] == "small blind"):
|
|
||||||
print >>fh, _("%s: posts small blind $%s" %(a[0], self.sb))
|
|
||||||
if(a[1] == "big blind"):
|
|
||||||
print >>fh, _("%s: posts big blind $%s" %(a[0], self.bb))
|
|
||||||
if(a[1] == "both"):
|
|
||||||
print >>fh, _("%s: posts small & big blinds $%.2f" %(a[0], (Decimal(self.sb) + Decimal(self.bb))))
|
|
||||||
|
|
||||||
print >>fh, _("*** HOLE CARDS ***")
|
print >>fh, _("*** HOLE CARDS ***")
|
||||||
if self.involved:
|
if self.involved:
|
||||||
print >>fh, _("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:
|
if self.actions['PREFLOP']:
|
||||||
for act in self.actions['PREFLOP']:
|
for act in self.actions['PREFLOP']:
|
||||||
self.printActionLine(act, fh)
|
self.printActionLine(act, fh)
|
||||||
|
|
||||||
if 'FLOP' in self.actions:
|
if self.actions['FLOP']:
|
||||||
print >>fh, _("*** FLOP *** [%s]" %( " ".join(self.board['FLOP'])))
|
print >>fh, _("*** FLOP *** [%s]" %( " ".join(self.board['FLOP'])))
|
||||||
for act in self.actions['FLOP']:
|
for act in self.actions['FLOP']:
|
||||||
self.printActionLine(act, fh)
|
self.printActionLine(act, fh)
|
||||||
|
|
||||||
if 'TURN' in self.actions:
|
if self.actions['TURN']:
|
||||||
print >>fh, _("*** 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']:
|
for act in self.actions['TURN']:
|
||||||
self.printActionLine(act, fh)
|
self.printActionLine(act, fh)
|
||||||
|
|
||||||
if 'RIVER' in self.actions:
|
if self.actions['RIVER']:
|
||||||
print >>fh, _("*** 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']:
|
for act in self.actions['RIVER']:
|
||||||
self.printActionLine(act, fh)
|
self.printActionLine(act, fh)
|
||||||
|
@ -429,7 +462,7 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
# we probably don't need a showdown section in pseudo stars format for our filtering purposes
|
# we probably don't need a showdown section in pseudo stars format for our filtering purposes
|
||||||
if 'SHOWDOWN' in self.actions:
|
if 'SHOWDOWN' in self.actions:
|
||||||
print >>fh, _("*** SHOW DOWN ***")
|
print >>fh, _("*** SHOW DOWN ***")
|
||||||
#TODO: Complete SHOWDOWN
|
#TODO: Complete SHOWDOWN
|
||||||
|
|
||||||
# Current PS format has the lines:
|
# Current PS format has the lines:
|
||||||
# Uncalled bet ($111.25) returned to s0rrow
|
# Uncalled bet ($111.25) returned to s0rrow
|
||||||
|
@ -467,26 +500,45 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
print >>fh, _("Seat %d: %s mucked" % (seatnum, name))
|
print >>fh, _("Seat %d: %s mucked" % (seatnum, name))
|
||||||
|
|
||||||
print >>fh, "\n\n"
|
print >>fh, "\n\n"
|
||||||
# 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])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class StudHand(Hand):
|
||||||
|
def __init__(self, hhc, sitename, gametype, handText):
|
||||||
|
if gametype[1] not in ["razz","stud","stud8"]:
|
||||||
|
pass # or indeed don't pass and complain instead
|
||||||
|
self.streetList = ['ANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH'] # a list of the observed street names in order
|
||||||
|
Hand.__init__(self, sitename, gametype, handText)
|
||||||
|
|
||||||
|
hhc.readHandInfo(self)
|
||||||
|
hhc.readPlayerStacks(self)
|
||||||
|
hhc.compilePlayerRegexs(players = set([player[1] for player in self.players]))
|
||||||
|
hhc.markStreets(self)
|
||||||
|
hhc.readAntes(self)
|
||||||
|
hhc.readBringIn(self)
|
||||||
|
hhc.readShowdownActions(self)
|
||||||
|
# Read actions in street order
|
||||||
|
for street in self.streetList:
|
||||||
|
if self.streets[street]:
|
||||||
|
logging.debug(street)
|
||||||
|
logging.debug(hand.streets[street])
|
||||||
|
hhc.readPlayerCards(self, street)
|
||||||
|
hhc.readAction(self, street)
|
||||||
|
hhc.readCollectPot(self)
|
||||||
|
hhc.readShownCards(self)
|
||||||
|
self.totalPot() # finalise it (total the pot)
|
||||||
|
hhc.getRake(self)
|
||||||
|
|
||||||
|
def addBringIn(self, player, ante):
|
||||||
|
if player is not None:
|
||||||
|
self.bets['THIRD'][player].append(Decimal(ante))
|
||||||
|
self.stacks[player] -= Decimal(ante)
|
||||||
|
act = (player, 'bringin', "bringin", ante, self.stacks[player]==0)
|
||||||
|
self.actions['THIRD'].append(act)
|
||||||
|
self.pot.addMoney(player, Decimal(ante))
|
||||||
|
|
||||||
def writeStudHand(self, fh=sys.__stdout__):
|
def writeStudHand(self, fh=sys.__stdout__):
|
||||||
# PokerStars format.
|
# PokerStars format.
|
||||||
#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, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
|
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
|
||||||
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||||
|
|
||||||
|
@ -496,10 +548,16 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
#Only print stacks of players who do something preflop
|
#Only print stacks of players who do something preflop
|
||||||
print >>fh, _("Seat %s: %s ($%s)" %(player[0], player[1], player[2]))
|
print >>fh, _("Seat %s: %s ($%s)" %(player[0], player[1], player[2]))
|
||||||
|
|
||||||
|
if 'ANTES' in self.actions:
|
||||||
|
for act in self.actions['ANTES']:
|
||||||
|
print >>fh, _("%s: posts the ante $%s" %(act[0], act[3]))
|
||||||
|
|
||||||
if 'THIRD' in self.actions:
|
if 'THIRD' in self.actions:
|
||||||
print >>fh, _("*** 3RD STREET ***")
|
print >>fh, _("*** 3RD STREET ***")
|
||||||
|
for player in [x for x in self.players if x[1] in players_who_post_antes]:
|
||||||
|
print >>fh, _("Dealt to ")
|
||||||
for act in self.actions['THIRD']:
|
for act in self.actions['THIRD']:
|
||||||
|
#FIXME: Need some logic here for bringin vs completes
|
||||||
self.printActionLine(act, fh)
|
self.printActionLine(act, fh)
|
||||||
|
|
||||||
if 'FOURTH' in self.actions:
|
if 'FOURTH' in self.actions:
|
||||||
|
@ -527,7 +585,7 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
# we probably don't need a showdown section in pseudo stars format for our filtering purposes
|
# we probably don't need a showdown section in pseudo stars format for our filtering purposes
|
||||||
if 'SHOWDOWN' in self.actions:
|
if 'SHOWDOWN' in self.actions:
|
||||||
print >>fh, _("*** SHOW DOWN ***")
|
print >>fh, _("*** SHOW DOWN ***")
|
||||||
# print >>fh, "DEBUG: what do they show"
|
# TODO: print showdown lines.
|
||||||
|
|
||||||
# Current PS format has the lines:
|
# Current PS format has the lines:
|
||||||
# Uncalled bet ($111.25) returned to s0rrow
|
# Uncalled bet ($111.25) returned to s0rrow
|
||||||
|
@ -566,77 +624,10 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
print >>fh, _("Seat %d: %s mucked" % (seatnum, name))
|
print >>fh, _("Seat %d: %s mucked" % (seatnum, name))
|
||||||
|
|
||||||
print >>fh, "\n\n"
|
print >>fh, "\n\n"
|
||||||
# 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 printHand(self):
|
|
||||||
self.writeHand(sys.stdout)
|
|
||||||
|
|
||||||
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 >>fh, _("%s: calls $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
|
||||||
if act[1] == 'bets':
|
|
||||||
print >>fh, _("%s: bets $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
|
||||||
if act[1] == 'raises':
|
|
||||||
print >>fh, _("%s: raises $%s to $%s%s" %(act[0], act[2], act[3], ' and is all-in' if act[5] else ''))
|
|
||||||
|
|
||||||
# going to use pokereval to figure out hands at some point.
|
|
||||||
# these functions are copied from pokergame.py
|
|
||||||
def bestHand(self, side, cards):
|
|
||||||
return HandHistoryConverter.eval.best('hi', cards, [])
|
|
||||||
|
|
||||||
|
|
||||||
# from pokergame.py
|
|
||||||
# got rid of the _ for internationalisation
|
|
||||||
def readableHandValueLong(self, side, value, 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
|
|
||||||
|
|
||||||
|
|
||||||
class FpdbParseError(Exception): pass
|
|
||||||
|
|
||||||
class Pot(object):
|
class Pot(object):
|
||||||
|
|
||||||
|
@ -711,4 +702,3 @@ class Pot(object):
|
||||||
return _("too many pots.. no small blind and walk in bb?. self.pots: %s" %(self.pots))
|
return _("too many pots.. no small blind and walk in bb?. self.pots: %s" %(self.pots))
|
||||||
# I don't know stars format for a walk in the bb when sb doesn't post.
|
# I don't know stars format for a walk in the bb when sb doesn't post.
|
||||||
# The thing to do here is raise a Hand error like fpdb import does and file it into errors.txt
|
# The thing to do here is raise a Hand error like fpdb import does and file it into errors.txt
|
||||||
|
|
||||||
|
|
|
@ -72,13 +72,10 @@ letter2names = {
|
||||||
import gettext
|
import gettext
|
||||||
gettext.install('myapplication')
|
gettext.install('myapplication')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HandHistoryConverter(threading.Thread):
|
class HandHistoryConverter(threading.Thread):
|
||||||
# eval = PokerEval()
|
|
||||||
|
|
||||||
def __init__(self, in_path = '-', out_path = '-', sitename = None, follow=False):
|
def __init__(self, in_path = '-', out_path = '-', sitename = None, follow=False):
|
||||||
super(HandHistoryConverter, self).__init__()
|
threading.Thread.__init__(self)
|
||||||
logging.info("HandHistory init called")
|
logging.info("HandHistory init called")
|
||||||
|
|
||||||
# default filetype and codepage. Subclasses should set these properly.
|
# default filetype and codepage. Subclasses should set these properly.
|
||||||
|
@ -94,7 +91,7 @@ class HandHistoryConverter(threading.Thread):
|
||||||
self.out_fh = open(self.out_path, 'a')
|
self.out_fh = open(self.out_path, 'a')
|
||||||
self.sitename = sitename
|
self.sitename = sitename
|
||||||
self.follow = follow
|
self.follow = follow
|
||||||
self.players = set()
|
self.compiledPlayers = set()
|
||||||
self.maxseats = 10
|
self.maxseats = 10
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -145,45 +142,11 @@ class HandHistoryConverter(threading.Thread):
|
||||||
gametype = self.determineGameType(handtext)
|
gametype = self.determineGameType(handtext)
|
||||||
if gametype is None:
|
if gametype is None:
|
||||||
return
|
return
|
||||||
hand = Hand.Hand(self.sitename, gametype, handtext)
|
|
||||||
self.readHandInfo(hand)
|
|
||||||
self.readPlayerStacks(hand)
|
|
||||||
playersThisHand = set([player[1] for player in hand.players])
|
|
||||||
if playersThisHand <= self.players: # x <= y means 'x is subset of y'
|
|
||||||
# we're ok; the regex should already cover them all.
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# we need to recompile the player regexs.
|
|
||||||
self.players = playersThisHand
|
|
||||||
self.compilePlayerRegexs()
|
|
||||||
|
|
||||||
self.markStreets(hand)
|
if gametype[1] in ("hold", "omaha"):
|
||||||
# Different calls if stud or holdem like
|
hand = Hand.HoldemOmahaHand(self, self.sitename, gametype, handtext)
|
||||||
if gametype[1] == "hold" or gametype[1] == "omaha":
|
elif gametype[1] in ("razz","stud","stud8"):
|
||||||
self.readBlinds(hand)
|
hand = Hand.StudHand(self, self.sitename, gametype, handtext)
|
||||||
self.readButton(hand)
|
|
||||||
self.readHeroCards(hand) # want to generalise to draw games
|
|
||||||
elif gametype[1] == "razz" or gametype[1] == "stud" or gametype[1] == "stud8":
|
|
||||||
self.readAntes(hand)
|
|
||||||
self.readBringIn(hand)
|
|
||||||
|
|
||||||
self.readShowdownActions(hand)
|
|
||||||
|
|
||||||
# Read actions in street order
|
|
||||||
for street in hand.streetList: # go through them in order
|
|
||||||
#logging.debug(street)
|
|
||||||
if hand.streets.group(street) is not None:
|
|
||||||
if gametype[1] == "hold" or gametype[1] == "omaha":
|
|
||||||
self.readCommunityCards(hand, street) # read community cards
|
|
||||||
elif gametype[1] == "razz" or gametype[1] == "stud" or gametype[1] == "stud8":
|
|
||||||
self.readPlayerCards(hand, street)
|
|
||||||
|
|
||||||
self.readAction(hand, street)
|
|
||||||
|
|
||||||
self.readCollectPot(hand)
|
|
||||||
self.readShownCards(hand)
|
|
||||||
hand.totalPot() # finalise it (total the pot)
|
|
||||||
self.getRake(hand)
|
|
||||||
|
|
||||||
hand.writeHand(self.out_fh)
|
hand.writeHand(self.out_fh)
|
||||||
|
|
||||||
|
@ -207,7 +170,7 @@ class HandHistoryConverter(threading.Thread):
|
||||||
self.hands = self.splitFileIntoHands()
|
self.hands = self.splitFileIntoHands()
|
||||||
outfile = open(self.ofile, 'w')
|
outfile = open(self.ofile, 'w')
|
||||||
for hand in self.hands:
|
for hand in self.hands:
|
||||||
#print "\nDEBUG: Input:\n"+hand.string
|
#print "\nDEBUG: Input:\n"+hand.handText
|
||||||
self.readHandInfo(hand)
|
self.readHandInfo(hand)
|
||||||
|
|
||||||
self.readPlayerStacks(hand)
|
self.readPlayerStacks(hand)
|
||||||
|
@ -264,7 +227,6 @@ class HandHistoryConverter(threading.Thread):
|
||||||
endtime = time.time()
|
endtime = time.time()
|
||||||
print "Processed %d hands in %.3f seconds" % (len(self.hands), endtime - starttime)
|
print "Processed %d hands in %.3f seconds" % (len(self.hands), endtime - starttime)
|
||||||
|
|
||||||
#####
|
|
||||||
# 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
|
||||||
# This function should return a list of lists looking like:
|
# This function should return a list of lists looking like:
|
||||||
# return [["ring", "hold", "nl"], ["tour", "hold", "nl"]]
|
# return [["ring", "hold", "nl"], ["tour", "hold", "nl"]]
|
||||||
|
@ -279,13 +241,13 @@ class HandHistoryConverter(threading.Thread):
|
||||||
def determineGameType(self): abstract
|
def determineGameType(self): abstract
|
||||||
|
|
||||||
# Read any of:
|
# Read any of:
|
||||||
# HID HandID
|
# HID HandID
|
||||||
# TABLE Table name
|
# TABLE Table name
|
||||||
# SB small blind
|
# SB small blind
|
||||||
# BB big blind
|
# BB big blind
|
||||||
# GAMETYPE gametype
|
# GAMETYPE gametype
|
||||||
# YEAR MON DAY HR MIN SEC datetime
|
# YEAR MON DAY HR MIN SEC datetime
|
||||||
# BUTTON button seat number
|
# BUTTON button seat number
|
||||||
def readHandInfo(self, hand): abstract
|
def readHandInfo(self, hand): abstract
|
||||||
|
|
||||||
# Needs to return a list of lists in the format
|
# Needs to return a list of lists in the format
|
||||||
|
@ -355,7 +317,7 @@ class HandHistoryConverter(threading.Thread):
|
||||||
list = self.re_SplitHands.split(self.obs)
|
list = self.re_SplitHands.split(self.obs)
|
||||||
list.pop() #Last entry is empty
|
list.pop() #Last entry is empty
|
||||||
for l in list:
|
for l in list:
|
||||||
# print "'" + l + "'"
|
# print "'" + l + "'"
|
||||||
hands = hands + [Hand.Hand(self.sitename, self.gametype, l)]
|
hands = hands + [Hand.Hand(self.sitename, self.gametype, l)]
|
||||||
return hands
|
return hands
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ import HUD_main
|
||||||
class Hud:
|
class Hud:
|
||||||
|
|
||||||
def __init__(self, parent, table, max, poker_game, config, db_connection):
|
def __init__(self, parent, table, max, poker_game, config, db_connection):
|
||||||
|
# __init__ is (now) intended to be called from the stdin thread, so it
|
||||||
|
# cannot touch the gui
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.table = table
|
self.table = table
|
||||||
self.config = config
|
self.config = config
|
||||||
|
@ -57,26 +59,28 @@ class Hud:
|
||||||
self.deleted = False
|
self.deleted = False
|
||||||
self.stacked = True
|
self.stacked = True
|
||||||
self.site = table.site
|
self.site = table.site
|
||||||
self.colors = config.get_default_colors(self.table.site)
|
self.mw_created = False
|
||||||
|
|
||||||
self.stat_windows = {}
|
self.stat_windows = {}
|
||||||
self.popup_windows = {}
|
self.popup_windows = {}
|
||||||
self.aux_windows = []
|
self.aux_windows = []
|
||||||
|
|
||||||
(font, font_size) = config.get_default_font(self.table.site)
|
(font, font_size) = config.get_default_font(self.table.site)
|
||||||
|
self.colors = config.get_default_colors(self.table.site)
|
||||||
|
|
||||||
if font == None:
|
if font == None:
|
||||||
font = "Sans"
|
font = "Sans"
|
||||||
if font_size == None:
|
if font_size == None:
|
||||||
font_size = "8"
|
font_size = "8"
|
||||||
|
|
||||||
self.font = pango.FontDescription(font + " " + font_size)
|
self.font = pango.FontDescription(font + " " + font_size)
|
||||||
|
|
||||||
# do we need to add some sort of condition here for dealing with a request for a font that doesn't exist?
|
# do we need to add some sort of condition here for dealing with a request for a font that doesn't exist?
|
||||||
|
|
||||||
|
def create_mw(self):
|
||||||
|
|
||||||
# Set up a main window for this this instance of the HUD
|
# Set up a main window for this this instance of the HUD
|
||||||
self.main_window = gtk.Window()
|
self.main_window = gtk.Window()
|
||||||
self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC)
|
self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC)
|
||||||
self.main_window.set_title(table.name + " FPDBHUD")
|
self.main_window.set_title(self.table.name + " FPDBHUD")
|
||||||
self.main_window.destroyhandler = self.main_window.connect("destroy", self.kill_hud)
|
self.main_window.destroyhandler = self.main_window.connect("destroy", self.kill_hud)
|
||||||
self.main_window.set_decorated(False)
|
self.main_window.set_decorated(False)
|
||||||
self.main_window.set_opacity(self.colors["hudopacity"])
|
self.main_window.set_opacity(self.colors["hudopacity"])
|
||||||
|
@ -123,6 +127,7 @@ class Hud:
|
||||||
self.ebox.connect_object("button-press-event", self.on_button_press, self.menu)
|
self.ebox.connect_object("button-press-event", self.on_button_press, self.menu)
|
||||||
|
|
||||||
self.main_window.show_all()
|
self.main_window.show_all()
|
||||||
|
self.mw_created = True
|
||||||
|
|
||||||
# TODO: fold all uses of this type of 'topify' code into a single function, if the differences between the versions don't
|
# TODO: fold all uses of this type of 'topify' code into a single function, if the differences between the versions don't
|
||||||
# create adverse effects?
|
# create adverse effects?
|
||||||
|
@ -228,13 +233,17 @@ class Hud:
|
||||||
return self.stat_dict[key]['seat']
|
return self.stat_dict[key]['seat']
|
||||||
sys.stderr.write("Error finding actual seat.\n")
|
sys.stderr.write("Error finding actual seat.\n")
|
||||||
|
|
||||||
def create(self, hand, config, stat_dict):
|
def create(self, hand, config, stat_dict, cards):
|
||||||
# update this hud, to the stats and players as of "hand"
|
# update this hud, to the stats and players as of "hand"
|
||||||
# hand is the hand id of the most recent hand played at this table
|
# hand is the hand id of the most recent hand played at this table
|
||||||
#
|
#
|
||||||
# this method also manages the creating and destruction of stat
|
# this method also manages the creating and destruction of stat
|
||||||
# windows via calls to the Stat_Window class
|
# windows via calls to the Stat_Window class
|
||||||
|
if not self.mw_created:
|
||||||
|
self.create_mw()
|
||||||
|
|
||||||
self.stat_dict = stat_dict
|
self.stat_dict = stat_dict
|
||||||
|
self.cards = cards
|
||||||
sys.stderr.write("------------------------------------------------------------\nCreating hud from hand %s\n" % hand)
|
sys.stderr.write("------------------------------------------------------------\nCreating hud from hand %s\n" % hand)
|
||||||
adj = self.adj_seats(hand, config)
|
adj = self.adj_seats(hand, config)
|
||||||
sys.stderr.write("adj = %s\n" % adj)
|
sys.stderr.write("adj = %s\n" % adj)
|
||||||
|
@ -274,37 +283,35 @@ class Hud:
|
||||||
if os.name == "nt":
|
if os.name == "nt":
|
||||||
gobject.timeout_add(500, self.update_table_position)
|
gobject.timeout_add(500, self.update_table_position)
|
||||||
|
|
||||||
def update(self, hand, config, stat_dict):
|
def update(self, hand, config):
|
||||||
self.hand = hand # this is the last hand, so it is available later
|
self.hand = hand # this is the last hand, so it is available later
|
||||||
self.stat_dict = stat_dict # so this is available for popups, etc
|
|
||||||
self.update_table_position()
|
self.update_table_position()
|
||||||
self.stat_dict = stat_dict
|
|
||||||
|
|
||||||
for s in stat_dict:
|
for s in self.stat_dict:
|
||||||
try:
|
try:
|
||||||
self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id']
|
self.stat_windows[self.stat_dict[s]['seat']].player_id = self.stat_dict[s]['player_id']
|
||||||
except: # omg, we have more seats than stat windows .. damn poker sites with incorrect max seating info .. let's force 10 here
|
except: # omg, we have more seats than stat windows .. damn poker sites with incorrect max seating info .. let's force 10 here
|
||||||
self.max = 10
|
self.max = 10
|
||||||
self.create(hand, config)
|
self.create(hand, config, self.stat_dict, self.cards)
|
||||||
self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id']
|
self.stat_windows[self.stat_dict[s]['seat']].player_id = self.stat_dict[s]['player_id']
|
||||||
|
|
||||||
for r in range(0, config.supported_games[self.poker_game].rows):
|
for r in range(0, config.supported_games[self.poker_game].rows):
|
||||||
for c in range(0, config.supported_games[self.poker_game].cols):
|
for c in range(0, config.supported_games[self.poker_game].cols):
|
||||||
this_stat = config.supported_games[self.poker_game].stats[self.stats[r][c]]
|
this_stat = config.supported_games[self.poker_game].stats[self.stats[r][c]]
|
||||||
number = Stats.do_stat(stat_dict, player = stat_dict[s]['player_id'], stat = self.stats[r][c])
|
number = Stats.do_stat(self.stat_dict, player = self.stat_dict[s]['player_id'], stat = self.stats[r][c])
|
||||||
statstring = this_stat.hudprefix + str(number[1]) + this_stat.hudsuffix
|
statstring = this_stat.hudprefix + str(number[1]) + this_stat.hudsuffix
|
||||||
|
|
||||||
if this_stat.hudcolor != "":
|
if this_stat.hudcolor != "":
|
||||||
self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
|
self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
|
||||||
self.stat_windows[stat_dict[s]['seat']].label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.hudcolor))
|
self.stat_windows[stat_dict[s]['seat']].label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.hudcolor))
|
||||||
|
|
||||||
self.stat_windows[stat_dict[s]['seat']].label[r][c].set_text(statstring)
|
self.stat_windows[self.stat_dict[s]['seat']].label[r][c].set_text(statstring)
|
||||||
if statstring != "xxx": # is there a way to tell if this particular stat window is visible already, or no?
|
if statstring != "xxx": # is there a way to tell if this particular stat window is visible already, or no?
|
||||||
self.stat_windows[stat_dict[s]['seat']].window.show_all()
|
self.stat_windows[self.stat_dict[s]['seat']].window.show_all()
|
||||||
# self.reposition_windows()
|
# self.reposition_windows()
|
||||||
tip = stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \
|
tip = self.stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \
|
||||||
number[3] + ", " + number[4]
|
number[3] + ", " + number[4]
|
||||||
Stats.do_tip(self.stat_windows[stat_dict[s]['seat']].e_box[r][c], tip)
|
Stats.do_tip(self.stat_windows[self.stat_dict[s]['seat']].e_box[r][c], tip)
|
||||||
|
|
||||||
def topify_window(self, window):
|
def topify_window(self, window):
|
||||||
"""Set the specified gtk window to stayontop in MS Windows."""
|
"""Set the specified gtk window to stayontop in MS Windows."""
|
||||||
|
@ -365,6 +372,7 @@ class Stat_Window:
|
||||||
self.y = y + table.y # x and y are the location relative to table.x & y
|
self.y = y + table.y # x and y are the location relative to table.x & y
|
||||||
self.player_id = player_id # looks like this isn't used ;)
|
self.player_id = player_id # looks like this isn't used ;)
|
||||||
self.sb_click = 0 # used to figure out button clicks
|
self.sb_click = 0 # used to figure out button clicks
|
||||||
|
self.useframes = parent.config.get_frames(parent.site)
|
||||||
|
|
||||||
self.window = gtk.Window()
|
self.window = gtk.Window()
|
||||||
self.window.set_decorated(0)
|
self.window.set_decorated(0)
|
||||||
|
@ -382,23 +390,28 @@ class Stat_Window:
|
||||||
self.frame = []
|
self.frame = []
|
||||||
self.label = []
|
self.label = []
|
||||||
for r in range(self.game.rows):
|
for r in range(self.game.rows):
|
||||||
self.frame.append([])
|
if self.useframes:
|
||||||
|
self.frame.append([])
|
||||||
self.e_box.append([])
|
self.e_box.append([])
|
||||||
self.label.append([])
|
self.label.append([])
|
||||||
for c in range(self.game.cols):
|
for c in range(self.game.cols):
|
||||||
self.frame[r].append( gtk.Frame() )
|
if self.useframes:
|
||||||
|
self.frame[r].append( gtk.Frame() )
|
||||||
self.e_box[r].append( gtk.EventBox() )
|
self.e_box[r].append( gtk.EventBox() )
|
||||||
|
|
||||||
self.e_box[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
self.e_box[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
||||||
self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, parent.foregroundcolor)
|
self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, parent.foregroundcolor)
|
||||||
|
|
||||||
Stats.do_tip(self.e_box[r][c], 'stuff')
|
Stats.do_tip(self.e_box[r][c], 'stuff')
|
||||||
# self.grid.attach(self.e_box[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0)
|
if self.useframes:
|
||||||
self.grid.attach(self.frame[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0)
|
self.grid.attach(self.frame[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0)
|
||||||
self.frame[r][c].add(self.e_box[r][c])
|
self.frame[r][c].add(self.e_box[r][c])
|
||||||
|
else:
|
||||||
|
self.grid.attach(self.e_box[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0)
|
||||||
self.label[r].append( gtk.Label('xxx') )
|
self.label[r].append( gtk.Label('xxx') )
|
||||||
|
|
||||||
self.frame[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
if self.useframes:
|
||||||
|
self.frame[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
||||||
self.label[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
self.label[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
||||||
self.label[r][c].modify_fg(gtk.STATE_NORMAL, parent.foregroundcolor)
|
self.label[r][c].modify_fg(gtk.STATE_NORMAL, parent.foregroundcolor)
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ class Stud_list:
|
||||||
winners = winners + player
|
winners = winners + player
|
||||||
pot_dec = "%.2f" % (float(pot)/100)
|
pot_dec = "%.2f" % (float(pot)/100)
|
||||||
|
|
||||||
hero_cards = self.get_hero_cards(self.parent.hero, self.parent.mucked_cards.cards)
|
hero_cards = self.get_hero_cards(self.parent.hero, self.parent.hud.cards)
|
||||||
self.info_row = ((new_hand_id, hero_cards, pot_dec, winners), )
|
self.info_row = ((new_hand_id, hero_cards, pot_dec, winners), )
|
||||||
|
|
||||||
def get_hero_cards(self, hero, cards):
|
def get_hero_cards(self, hero, cards):
|
||||||
|
@ -163,11 +163,10 @@ class Stud_list:
|
||||||
if hero == '':
|
if hero == '':
|
||||||
return "xxxxxx"
|
return "xxxxxx"
|
||||||
else:
|
else:
|
||||||
for k in cards.keys():
|
# find the hero's seat from the stat_dict
|
||||||
if cards[k]['screen_name'] == hero:
|
for stat in self.parent.hud.stat_dict.itervalues():
|
||||||
return trans[cards[k]['card1Value']] + cards[k]['card1Suit'] \
|
if stat['screen_name'] == hero:
|
||||||
+ trans[cards[k]['card2Value']] + cards[k]['card2Suit'] \
|
return self.parent.hud.cards[stat['seat']][0:6]
|
||||||
+ trans[cards[k]['card3Value']] + cards[k]['card3Suit']
|
|
||||||
return "xxxxxx"
|
return "xxxxxx"
|
||||||
|
|
||||||
def update_gui(self, new_hand_id):
|
def update_gui(self, new_hand_id):
|
||||||
|
@ -225,25 +224,7 @@ class Stud_cards:
|
||||||
|
|
||||||
self.container.add(self.grid)
|
self.container.add(self.grid)
|
||||||
|
|
||||||
def translate_cards(self, old_cards):
|
|
||||||
ranks = ('', '', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A')
|
|
||||||
|
|
||||||
for c in old_cards.keys():
|
|
||||||
for i in range(1, 8):
|
|
||||||
rank = 'card' + str(i) + 'Value'
|
|
||||||
suit = 'card' + str(i) + 'Suit'
|
|
||||||
key = 'hole_card_' + str(i)
|
|
||||||
if old_cards[c][rank] == 0:
|
|
||||||
old_cards[c][key] = 'xx'
|
|
||||||
else:
|
|
||||||
old_cards[c][key] = ranks[old_cards[c][rank]] + old_cards[c][suit]
|
|
||||||
return old_cards
|
|
||||||
|
|
||||||
def update_data(self, new_hand_id, db_connection):
|
def update_data(self, new_hand_id, db_connection):
|
||||||
# db_connection = Database.Database(self.config, 'fpdb', '')
|
|
||||||
cards = db_connection.get_cards(new_hand_id)
|
|
||||||
self.cards = self.translate_cards(cards)
|
|
||||||
|
|
||||||
self.tips = []
|
self.tips = []
|
||||||
action = db_connection.get_action_from_hand(new_hand_id)
|
action = db_connection.get_action_from_hand(new_hand_id)
|
||||||
for street in action:
|
for street in action:
|
||||||
|
@ -261,13 +242,13 @@ class Stud_cards:
|
||||||
|
|
||||||
def update_gui(self, new_hand_id):
|
def update_gui(self, new_hand_id):
|
||||||
self.clear()
|
self.clear()
|
||||||
for c in self.cards.keys():
|
for c, cards in self.parent.hud.cards.iteritems():
|
||||||
self.grid_contents[(1, self.cards[c]['seat_number'] - 1)].set_text(self.cards[c]['screen_name'])
|
self.grid_contents[(1, c - 1)].set_text(self.get_screen_name(c))
|
||||||
for i in ((0, 'hole_card_1'), (1, 'hole_card_2'), (2, 'hole_card_3'), (3, 'hole_card_4'),
|
for i in ((0, cards[0:2]), (1, cards[2:4]), (2, cards[4:6]), (3, cards[6:8]),
|
||||||
(4, 'hole_card_5'), (5, 'hole_card_6'), (6, 'hole_card_7')):
|
(4, cards[8:10]), (5, cards[10:12]), (6, cards[12:14])):
|
||||||
if not self.cards[c][i[1]] == "xx":
|
if not i[1] == "xx":
|
||||||
self.seen_cards[(i[0], self.cards[c]['seat_number'] - 1)]. \
|
self.seen_cards[(i[0], c - 1)]. \
|
||||||
set_from_pixbuf(self.card_images[self.split_cards(self.cards[c][i[1]])])
|
set_from_pixbuf(self.card_images[self.split_cards(i[1])])
|
||||||
## action in tool tips for 3rd street cards
|
## action in tool tips for 3rd street cards
|
||||||
for c in (0, 1, 2):
|
for c in (0, 1, 2):
|
||||||
for r in range(0, self.rows):
|
for r in range(0, self.rows):
|
||||||
|
@ -279,6 +260,13 @@ class Stud_cards:
|
||||||
for r in range(0, self.rows):
|
for r in range(0, self.rows):
|
||||||
self.eb[(round_to_col[round], r)].set_tooltip_text(self.tips[round])
|
self.eb[(round_to_col[round], r)].set_tooltip_text(self.tips[round])
|
||||||
|
|
||||||
|
def get_screen_name(self, seat_no):
|
||||||
|
"""Gets and returns the screen name from stat_dict, given seat number."""
|
||||||
|
for k in self.parent.hud.stat_dict.keys():
|
||||||
|
if self.parent.hud.stat_dict[k]['seat'] == seat_no:
|
||||||
|
return self.parent.hud.stat_dict[k]['screen_name']
|
||||||
|
return "No Name"
|
||||||
|
|
||||||
def split_cards(self, card):
|
def split_cards(self, card):
|
||||||
return (card[0], card[1].upper())
|
return (card[0], card[1].upper())
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,13 @@ def do_stat(stat_dict, player = 24, stat = 'vpip'):
|
||||||
###########################################
|
###########################################
|
||||||
# functions that return individual stats
|
# functions that return individual stats
|
||||||
|
|
||||||
|
def totalprofit(stat_dict, player):
|
||||||
|
""" Total Profit."""
|
||||||
|
if stat_dict[player]['net'] != 0:
|
||||||
|
stat = float(stat_dict[player]['net']) / 100
|
||||||
|
return (stat, '$%.2f' % stat, 'tp=$%.2f' % stat, 'totalprofit=$%.2f' % stat, str(stat), 'Total Profit')
|
||||||
|
return ('0', '$0.00', 'tp=0', 'totalprofit=0', '0', 'Total Profit')
|
||||||
|
|
||||||
def playername(stat_dict, player):
|
def playername(stat_dict, player):
|
||||||
""" Player Name."""
|
""" Player Name."""
|
||||||
return (stat_dict[player]['screen_name'],
|
return (stat_dict[player]['screen_name'],
|
||||||
|
|
|
@ -390,9 +390,9 @@ if __name__=="__main__":
|
||||||
print discover_table_by_name(c, "Ringe")
|
print discover_table_by_name(c, "Ringe")
|
||||||
# print discover_tournament_table(c, "118942908", "3")
|
# print discover_tournament_table(c, "118942908", "3")
|
||||||
|
|
||||||
# tables = discover(c)
|
tables = discover(c)
|
||||||
# for t in tables.keys():
|
for t in tables.keys():
|
||||||
# print tables[t]
|
print tables[t]
|
||||||
|
|
||||||
print "press enter to continue"
|
print "press enter to continue"
|
||||||
sys.stdin.readline()
|
sys.stdin.readline()
|
||||||
|
|
|
@ -61,6 +61,7 @@ class Importer:
|
||||||
self.filelist = {}
|
self.filelist = {}
|
||||||
self.dirlist = {}
|
self.dirlist = {}
|
||||||
self.addToDirList = {}
|
self.addToDirList = {}
|
||||||
|
self.removeFromFileList = {} # to remove deleted files
|
||||||
self.monitor = False
|
self.monitor = False
|
||||||
self.updated = {} #Time last import was run {file:mtime}
|
self.updated = {} #Time last import was run {file:mtime}
|
||||||
self.lines = None
|
self.lines = None
|
||||||
|
@ -210,7 +211,12 @@ class Importer:
|
||||||
for dir in self.addToDirList:
|
for dir in self.addToDirList:
|
||||||
self.addImportDirectory(dir, True, self.addToDirList[dir][0], self.addToDirList[dir][1])
|
self.addImportDirectory(dir, True, self.addToDirList[dir][0], self.addToDirList[dir][1])
|
||||||
|
|
||||||
|
for file in self.removeFromFileList:
|
||||||
|
if file in self.filelist:
|
||||||
|
del self.filelist[file]
|
||||||
|
|
||||||
self.addToDirList = {}
|
self.addToDirList = {}
|
||||||
|
self.removeFromFileList = {}
|
||||||
|
|
||||||
# This is now an internal function that should not be called directly.
|
# This is now an internal function that should not be called directly.
|
||||||
def import_file_dict(self, file, site, filter):
|
def import_file_dict(self, file, site, filter):
|
||||||
|
@ -266,9 +272,15 @@ class Importer:
|
||||||
if (file=="stdin"):
|
if (file=="stdin"):
|
||||||
inputFile=sys.stdin
|
inputFile=sys.stdin
|
||||||
else:
|
else:
|
||||||
inputFile=open(file, "rU")
|
if os.path.exists(file):
|
||||||
try: loc = self.pos_in_file[file]
|
inputFile = open(file, "rU")
|
||||||
except: pass
|
else:
|
||||||
|
self.removeFromFileList[file] = True
|
||||||
|
return (0, 0, 0, 1, 0)
|
||||||
|
try:
|
||||||
|
loc = self.pos_in_file[file]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
# Read input file into class and close file
|
# Read input file into class and close file
|
||||||
inputFile.seek(loc)
|
inputFile.seek(loc)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user