From a71be6ddd39da7ad3d9b8a7a93d6c42b68208a32 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 26 Feb 2009 00:45:46 +0900 Subject: [PATCH 01/20] Add stud/razz ante for FullTilt converter --- pyfpdb/FulltiltToFpdb.py | 8 ++++++-- pyfpdb/Hand.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index d6410048..d46db318 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -43,6 +43,7 @@ class FullTilt(HandHistoryConverter): print "DEBUG player_re: " + player_re self.re_PostSB = re.compile(r"^%s posts the small blind of \$?(?P[.0-9]+)" % player_re, re.MULTILINE) self.re_PostBB = re.compile(r"^%s posts (the big blind of )?\$?(?P[.0-9]+)" % player_re, re.MULTILINE) + self.re_Antes = re.compile(r"^%s antes \$?(?P[.0-9]+)" % player_re, re.MULTILINE) self.re_BringIn = re.compile(r"^%s brings in for \$?(?P[.0-9]+)" % player_re, re.MULTILINE) self.re_PostBoth = re.compile(r"^%s posts small \& big blinds \[\$? (?P[.0-9]+)" % player_re, re.MULTILINE) self.re_HeroCards = re.compile(r"^Dealt to %s \[(?P.*)\]( \[(?P.*)\])?" % player_re, re.MULTILINE) @@ -155,7 +156,10 @@ class FullTilt(HandHistoryConverter): def readAntes(self, hand): 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): print "DEBUG: reading bring in" @@ -184,13 +188,13 @@ class FullTilt(HandHistoryConverter): m = self.re_HeroCards.finditer(hand.streets.group(street)) print "DEBUG: razz/stud readPlayerCards" print "DEBUG: STREET: %s", street + print hand.streets.group(street) for player in m: print player.groups() #hand.hero = m.group('PNAME') # "2c, qh" -> set(["2c","qc"]) # Also works with Omaha hands. cards = player.group('CARDS') - print "DEBUG: PNAME: %s CARDS: %s" %(player.group('PNAME'), player.group('CARDS')) cards = set(cards.split(' ')) # hand.addHoleCards(cards, m.group('PNAME')) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 0c08aa79..847d5f34 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -185,6 +185,14 @@ Card ranks will be uppercased c = c.replace(k,v) 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): # if player is None, it's a missing small blind. # TODO: @@ -496,6 +504,11 @@ Map the tuple self.gametype onto the pokerstars string describing it #Only print stacks of players who do something preflop print >>fh, _("Seat %s: %s ($%s)" %(player[0], player[1], player[2])) + if 'ANTES' in self.actions: + for act in self.actions['ANTES']: + print act + print >>fh, _("%s: posts the ante $%s" %(act[0], act[3])) + if 'THIRD' in self.actions: print >>fh, _("*** 3RD STREET ***") From 354a67c0e4a2f1b10826b2e9d956ed9a2b2839a0 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 26 Feb 2009 01:23:46 +0900 Subject: [PATCH 02/20] Some bringin code for stud/razz --- pyfpdb/FulltiltToFpdb.py | 1 + pyfpdb/Hand.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index d46db318..1ad2c330 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -166,6 +166,7 @@ class FullTilt(HandHistoryConverter): # print hand.string m = self.re_BringIn.search(hand.string,re.DOTALL) 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): hand.buttonpos = int(self.re_Button.search(hand.string).group('BUTTON')) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 847d5f34..861808ab 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -221,6 +221,14 @@ Card ranks will be uppercased self.posted = self.posted + [[player,blindtype]] #print "DEBUG: self.posted: %s" %(self.posted) + 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 addCall(self, street, player=None, amount=None): # Potentially calculate the amount of the call if not supplied @@ -513,6 +521,7 @@ Map the tuple self.gametype onto the pokerstars string describing it if 'THIRD' in self.actions: print >>fh, _("*** 3RD STREET ***") for act in self.actions['THIRD']: + #FIXME: Need some logic here for bringin vs completes self.printActionLine(act, fh) if 'FOURTH' in self.actions: From 440602198f81cc09d9ecb5ee4c44858057e81545 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 26 Feb 2009 01:48:41 +0900 Subject: [PATCH 03/20] Fix(?) HeroCards regex for stud --- pyfpdb/FulltiltToFpdb.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 1ad2c330..a2420251 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -46,7 +46,7 @@ class FullTilt(HandHistoryConverter): self.re_Antes = re.compile(r"^%s antes \$?(?P[.0-9]+)" % player_re, re.MULTILINE) self.re_BringIn = re.compile(r"^%s brings in for \$?(?P[.0-9]+)" % player_re, re.MULTILINE) self.re_PostBoth = re.compile(r"^%s posts small \& big blinds \[\$? (?P[.0-9]+)" % player_re, re.MULTILINE) - self.re_HeroCards = re.compile(r"^Dealt to %s \[(?P.*)\]( \[(?P.*)\])?" % player_re, re.MULTILINE) + self.re_HeroCards = re.compile(r"^Dealt to %s \[(?P[AKQJT0-9hcsd ]+)\]( \[(?P[AKQJT0-9hcsd ]+)\])?" % player_re, re.MULTILINE) self.re_Action = re.compile(r"^%s(?P bets| checks| raises to| calls| folds)(\s\$(?P[.\d]+))?" % player_re, re.MULTILINE) self.re_ShowdownAction = re.compile(r"^%s shows \[(?P.*)\]" % player_re, re.MULTILINE) self.re_CollectPot = re.compile(r"^Seat (?P[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(\$(?P[.\d]+)\)(, mucked| with.*)" % player_re, re.MULTILINE) @@ -188,7 +188,6 @@ class FullTilt(HandHistoryConverter): #Used for stud hands - borrows the HeroCards regex for now. m = self.re_HeroCards.finditer(hand.streets.group(street)) print "DEBUG: razz/stud readPlayerCards" - print "DEBUG: STREET: %s", street print hand.streets.group(street) for player in m: print player.groups() From 3c9f5537ea155fa81ffaa421dabffbd10abd690e Mon Sep 17 00:00:00 2001 From: eblade Date: Wed, 25 Feb 2009 12:40:39 -0500 Subject: [PATCH 04/20] import should stop erroring out and crashing if a file it wanted to read has been deleted --- pyfpdb/fpdb_import.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index aeb1e027..ca9167e8 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -235,8 +235,9 @@ class Importer: if (file=="stdin"): inputFile=sys.stdin else: - inputFile=open(file, "rU") - try: loc = self.pos_in_file[file] + try: + inputFile=open(file, "rU") + loc = self.pos_in_file[file] except: pass # Read input file into class and close file From 7ebf27c07e2716d81d978597b546be021829674f Mon Sep 17 00:00:00 2001 From: eblade Date: Wed, 25 Feb 2009 15:25:58 -0500 Subject: [PATCH 05/20] add site config option "use_frames", set to "True" to get frames --- pyfpdb/Configuration.py | 4 ++++ pyfpdb/EverleafToFpdb.py | 7 +++++++ pyfpdb/Hud.py | 20 +++++++++++++------- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index a9a884a7..fb182f4b 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -62,6 +62,7 @@ class Site: self.aux_window = node.getAttribute("aux_window") self.font = node.getAttribute("font") self.font_size = node.getAttribute("font_size") + self.use_frames = node.getAttribute("use_frames") self.layout = {} for layout_node in node.getElementsByTagName('layout'): @@ -465,6 +466,9 @@ class Config: paths['hud-defaultPath'] = "default" paths['bulkImport-defaultPath'] = "default" return paths + + def get_frames(self, site = "PokerStars"): + return self.supported_sites[site].use_frames == "True" def get_default_colors(self, site = "PokerStars"): colors = {} diff --git a/pyfpdb/EverleafToFpdb.py b/pyfpdb/EverleafToFpdb.py index 33ae0cd3..a97e2bde 100755 --- a/pyfpdb/EverleafToFpdb.py +++ b/pyfpdb/EverleafToFpdb.py @@ -65,6 +65,13 @@ class Everleaf(HandHistoryConverter): # 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 # $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 game = "" diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 17497d90..f77b7318 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -285,7 +285,7 @@ class Hud: self.stat_windows[stat_dict[s]['seat']].player_id = 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 self.max = 10 - self.create(hand, config) + self.create(hand, config, stat_dict) self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id'] for r in range(0, config.supported_games[self.poker_game].rows): @@ -365,6 +365,7 @@ class Stat_Window: 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.sb_click = 0 # used to figure out button clicks + self.useframes = parent.config.get_frames(parent.site) self.window = gtk.Window() self.window.set_decorated(0) @@ -382,23 +383,28 @@ class Stat_Window: self.frame = [] self.label = [] for r in range(self.game.rows): - self.frame.append([]) + if self.useframes: + self.frame.append([]) self.e_box.append([]) self.label.append([]) 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][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor) self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, parent.foregroundcolor) 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) - 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]) + if self.useframes: + 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]) + 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.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_fg(gtk.STATE_NORMAL, parent.foregroundcolor) From 560cb1a543b481415764b88448210b7d5b0562ac Mon Sep 17 00:00:00 2001 From: eblade Date: Wed, 25 Feb 2009 22:44:03 -0500 Subject: [PATCH 06/20] fpdb_import runUpdated() will now remove files that were found to be newly missing on it's most recent pass from it's list of files to check --- pyfpdb/fpdb_import.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index ca9167e8..aa40b218 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -61,6 +61,7 @@ class Importer: self.filelist = {} self.dirlist = {} self.addToDirList = {} + self.removeFromFileList = {} # to remove deleted files self.monitor = False self.updated = {} #Time last import was run {file:mtime} self.lines = None @@ -187,8 +188,12 @@ class Importer: for dir in self.addToDirList: self.addImportDirectory(dir, True, self.addToDirList[dir][0], self.addToDirList[dir][1]) + + for file in self.removeFromFileList: + del self.filelist[file] self.addToDirList = {} + self.removeFromFileList = {} # This is now an internal function that should not be called directly. def import_file_dict(self, file, site, filter): @@ -235,10 +240,15 @@ class Importer: if (file=="stdin"): inputFile=sys.stdin else: + if os.path.exists(file): + inputFile = open(file, "rU") + else: + self.removeFromFileList['file'] = True + return try: - inputFile=open(file, "rU") loc = self.pos_in_file[file] - except: pass + except: + pass # Read input file into class and close file inputFile.seek(loc) From 9066cf9fc6ad9330730970be976f086194a68992 Mon Sep 17 00:00:00 2001 From: eblade Date: Wed, 25 Feb 2009 22:47:22 -0500 Subject: [PATCH 07/20] return appropriate tuple from import_fpdb_file on file error --- pyfpdb/fpdb_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index aa40b218..16435b06 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -244,7 +244,7 @@ class Importer: inputFile = open(file, "rU") else: self.removeFromFileList['file'] = True - return + return (0, 0, 0, 1, 0) try: loc = self.pos_in_file[file] except: From c7541d9f14d9a7f2fc007b168a24791da715dc05 Mon Sep 17 00:00:00 2001 From: eblade Date: Wed, 25 Feb 2009 23:17:36 -0500 Subject: [PATCH 08/20] return appropriate tuple from import_fpdb_file on file error --- pyfpdb/fpdb_import.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index aa40b218..980b1bae 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -190,7 +190,8 @@ class Importer: self.addImportDirectory(dir, True, self.addToDirList[dir][0], self.addToDirList[dir][1]) for file in self.removeFromFileList: - del self.filelist[file] + if file in self.filelist: + del self.filelist[file] self.addToDirList = {} self.removeFromFileList = {} @@ -243,8 +244,8 @@ class Importer: if os.path.exists(file): inputFile = open(file, "rU") else: - self.removeFromFileList['file'] = True - return + self.removeFromFileList[file] = True + return (0, 0, 0, 1, 0) try: loc = self.pos_in_file[file] except: From 333cbdbf6d5eae77a690b94f14eddda9f1858882 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 25 Feb 2009 23:35:15 -0500 Subject: [PATCH 09/20] Speed and reliability changes (+cleanup) to aux window interface. --- pyfpdb/Database.py | 34 +++++++++++++++---------------- pyfpdb/HUD_main.py | 18 ++++++++++------- pyfpdb/Hud.py | 25 +++++++++++------------ pyfpdb/Mucked.py | 50 ++++++++++++++++++---------------------------- 4 files changed, 59 insertions(+), 68 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index edf99cf0..7b376944 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -116,31 +116,30 @@ class Database: row = c.fetchone() 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): -# 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.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) + cards[s_dict['seat_number']] = (self.convert_cards(s_dict)) + 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): action = [ [], [], [], [], [] ] @@ -214,6 +213,7 @@ if __name__=="__main__": for p in stat_dict.keys(): print p, " ", stat_dict[p] + print "cards =", db_connection.get_cards(73525) db_connection.close_connection print "press enter to continue" diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index a8b800d1..6c31b0e8 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -72,7 +72,7 @@ class HUD_main(object): def destroy(*args): # call back for terminating the main eventloop 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(): @@ -84,18 +84,18 @@ class HUD_main(object): 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].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: m.update_data(new_hand_id, self.db_connection) 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() return False finally: gtk.gdk.threads_leave() 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.""" # This is written so that only 1 thread can touch the gui--mainly # for compatibility with Windows. This method dispatches the @@ -103,7 +103,7 @@ class HUD_main(object): def idle_func(): gtk.gdk.threads_enter() 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: m.update_gui(new_hand_id) return False @@ -145,6 +145,7 @@ class HUD_main(object): try: (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) + cards = self.db_connection.get_cards(new_hand_id) except: print "skipping ", new_hand_id sys.stderr.write("Database error in hand %d. Skipping.\n" % int(new_hand_id)) @@ -163,9 +164,11 @@ class HUD_main(object): # Update an existing HUD 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: 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 else: @@ -175,11 +178,12 @@ class HUD_main(object): tablewindow = Tables.discover_table_by_name(self.config, table_name) if tablewindow == None: +# If no client window is found on the screen, complain and continue if is_tournament: table_name = tour_number + " " + tab_number sys.stderr.write("table name "+table_name+" not found, skipping.\n") 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__": sys.stderr.write("HUD_main starting\n") diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 17497d90..12df03af 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -228,13 +228,14 @@ class Hud: return self.stat_dict[key]['seat'] 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" # hand is the hand id of the most recent hand played at this table # # this method also manages the creating and destruction of stat # windows via calls to the Stat_Window class self.stat_dict = stat_dict + self.cards = cards sys.stderr.write("------------------------------------------------------------\nCreating hud from hand %s\n" % hand) adj = self.adj_seats(hand, config) sys.stderr.write("adj = %s\n" % adj) @@ -274,37 +275,35 @@ class Hud: if os.name == "nt": 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.stat_dict = stat_dict # so this is available for popups, etc self.update_table_position() - self.stat_dict = stat_dict - for s in stat_dict: + for s in self.stat_dict: 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 self.max = 10 - self.create(hand, config) - self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id'] + self.create(hand, config, self.stat_dict, self.cards) + 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 c in range(0, config.supported_games[self.poker_game].cols): 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 if this_stat.hudcolor != "": 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].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? - self.stat_windows[stat_dict[s]['seat']].window.show_all() + self.stat_windows[self.stat_dict[s]['seat']].window.show_all() # 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] - 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): """Set the specified gtk window to stayontop in MS Windows.""" diff --git a/pyfpdb/Mucked.py b/pyfpdb/Mucked.py index 07021c7e..1e550edc 100755 --- a/pyfpdb/Mucked.py +++ b/pyfpdb/Mucked.py @@ -154,7 +154,7 @@ class Stud_list: winners = winners + player 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), ) def get_hero_cards(self, hero, cards): @@ -163,11 +163,10 @@ class Stud_list: if hero == '': return "xxxxxx" else: - for k in cards.keys(): - if cards[k]['screen_name'] == hero: - return trans[cards[k]['card1Value']] + cards[k]['card1Suit'] \ - + trans[cards[k]['card2Value']] + cards[k]['card2Suit'] \ - + trans[cards[k]['card3Value']] + cards[k]['card3Suit'] +# find the hero's seat from the stat_dict + for stat in self.parent.hud.stat_dict.itervalues(): + if stat['screen_name'] == hero: + return self.parent.hud.cards[stat['seat']][0:6] return "xxxxxx" def update_gui(self, new_hand_id): @@ -225,25 +224,7 @@ class Stud_cards: 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): -# db_connection = Database.Database(self.config, 'fpdb', '') - cards = db_connection.get_cards(new_hand_id) - self.cards = self.translate_cards(cards) - self.tips = [] action = db_connection.get_action_from_hand(new_hand_id) for street in action: @@ -261,13 +242,13 @@ class Stud_cards: def update_gui(self, new_hand_id): self.clear() - for c in self.cards.keys(): - self.grid_contents[(1, self.cards[c]['seat_number'] - 1)].set_text(self.cards[c]['screen_name']) - for i in ((0, 'hole_card_1'), (1, 'hole_card_2'), (2, 'hole_card_3'), (3, 'hole_card_4'), - (4, 'hole_card_5'), (5, 'hole_card_6'), (6, 'hole_card_7')): - if not self.cards[c][i[1]] == "xx": - self.seen_cards[(i[0], self.cards[c]['seat_number'] - 1)]. \ - set_from_pixbuf(self.card_images[self.split_cards(self.cards[c][i[1]])]) + for c, cards in self.parent.hud.cards.iteritems(): + self.grid_contents[(1, c - 1)].set_text(self.get_screen_name(c)) + for i in ((0, cards[0:2]), (1, cards[2:4]), (2, cards[4:6]), (3, cards[6:8]), + (4, cards[8:10]), (5, cards[10:12]), (6, cards[12:14])): + if not i[1] == "xx": + self.seen_cards[(i[0], c - 1)]. \ + set_from_pixbuf(self.card_images[self.split_cards(i[1])]) ## action in tool tips for 3rd street cards for c in (0, 1, 2): for r in range(0, self.rows): @@ -279,6 +260,13 @@ class Stud_cards: for r in range(0, self.rows): 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): return (card[0], card[1].upper()) From 9557117a16b78b3be4297760bbb1804f32d7f9a6 Mon Sep 17 00:00:00 2001 From: eblade Date: Thu, 26 Feb 2009 09:27:59 -0500 Subject: [PATCH 10/20] add "totalprofit" stat --- pyfpdb/Stats.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py index 0870c73e..cad3af88 100644 --- a/pyfpdb/Stats.py +++ b/pyfpdb/Stats.py @@ -70,6 +70,13 @@ def do_stat(stat_dict, player = 24, stat = 'vpip'): ########################################### # 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', '0', '0', 'Total Profit') + def playername(stat_dict, player): """ Player Name.""" return (stat_dict[player]['screen_name'], From 6d862cff529161bd5439a3034c18de54ae704757 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 27 Feb 2009 00:35:15 +0900 Subject: [PATCH 11/20] addPlayerCards done - now need to print it --- pyfpdb/FulltiltToFpdb.py | 8 ++++---- pyfpdb/Hand.py | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index a2420251..73607790 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -191,12 +191,12 @@ class FullTilt(HandHistoryConverter): print hand.streets.group(street) for player in m: print player.groups() - #hand.hero = m.group('PNAME') - # "2c, qh" -> set(["2c","qc"]) - # Also works with Omaha hands. cards = player.group('CARDS') + if player.group('NEWCARD') != None: + print cards + cards = cards + " " + player.group('NEWCARD') cards = set(cards.split(' ')) -# hand.addHoleCards(cards, m.group('PNAME')) + hand.addPlayerCards(cards, player.group('PNAME')) def readAction(self, hand, street): m = self.re_Action.finditer(hand.streets.group(street)) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 861808ab..80591a5f 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -146,6 +146,22 @@ player (string) name of player 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 set of card bigrams e.g. set(['2h','Jc']) +player (string) name of player + +Should probably be merged with addHoleCards +""" + print "DEBUG: addPlayerCards", cards,player + try: + self.checkPlayerExists(player) + cards = set([self.card(c) for c in cards]) + self.holecards[player].update(cards) + except FpdbParseError, e: + print "[ERROR] Tried to add holecards for unknown player: %s" % (player,) + def addShownCards(self, cards, player, holeandboard=None): """\ For when a player shows cards for any reason (for showdown or out of choice). @@ -514,12 +530,12 @@ Map the tuple self.gametype onto the pokerstars string describing it if 'ANTES' in self.actions: for act in self.actions['ANTES']: - print act print >>fh, _("%s: posts the ante $%s" %(act[0], act[3])) - if 'THIRD' in self.actions: 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']: #FIXME: Need some logic here for bringin vs completes self.printActionLine(act, fh) From ca57a5a5ff159fa6bb239700df4e95e71ef16258 Mon Sep 17 00:00:00 2001 From: Matt Turnbull Date: Thu, 26 Feb 2009 16:04:08 +0000 Subject: [PATCH 12/20] set -> list --- pyfpdb/EverleafToFpdb.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pyfpdb/EverleafToFpdb.py b/pyfpdb/EverleafToFpdb.py index 4c565d44..fb6ff54d 100755 --- a/pyfpdb/EverleafToFpdb.py +++ b/pyfpdb/EverleafToFpdb.py @@ -177,7 +177,7 @@ class Everleaf(HandHistoryConverter): # "2c, qh" -> set(["2c","qc"]) # Also works with Omaha hands. cards = m.group('CARDS') - cards = set(cards.split(', ')) + cards = cards.split(', ') hand.addHoleCards(cards, m.group('PNAME')) def readAction(self, hand, street): @@ -198,9 +198,10 @@ class Everleaf(HandHistoryConverter): def readShowdownActions(self, hand): + """Reads lines where holecards are reported in a showdown""" for shows in self.re_ShowdownAction.finditer(hand.string): cards = shows.group('CARDS') - cards = set(cards.split(', ')) + cards = cards.split(', ') hand.addShownCards(cards, shows.group('PNAME')) def readCollectPot(self,hand): @@ -208,10 +209,11 @@ class Everleaf(HandHistoryConverter): hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT')) def readShownCards(self,hand): + """Reads lines where hole & board cards are mixed to form a hand (summary lines)""" for m in self.re_CollectPot.finditer(hand.string): if m.group('CARDS') is not None: cards = m.group('CARDS') - cards = set(cards.split(', ')) + cards = cards.split(', ') hand.addShownCards(cards=None, player=m.group('PNAME'), holeandboard=cards) From 3fba85456cce622b2dfc69ae3f812e9bdcac4224 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 27 Feb 2009 01:26:50 +0900 Subject: [PATCH 13/20] Fix button regex --- pyfpdb/FulltiltToFpdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 73607790..2d2e36d1 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -28,7 +28,7 @@ class FullTilt(HandHistoryConverter): re_GameInfo = re.compile('- \$?(?P[.0-9]+)/\$?(?P[.0-9]+) (Ante \$(?P[.0-9]+) )?- (?P(No|Pot)? )?Limit (?P(Hold\'em|Omaha|Razz))') re_SplitHands = re.compile(r"\n\n+") re_HandInfo = re.compile('.*#(?P[0-9]+): Table (?P[- a-zA-Z]+) (\((?P.+)\) )?- \$?(?P[.0-9]+)/\$?(?P[.0-9]+) (Ante \$(?P[.0-9]+) )?- (?P[a-zA-Z\' ]+) - (?P.*)') - re_Button = re.compile('^The button is in seat #(?P