Merge branch 'master' of git://git.assembla.com/fpdboz.git

Conflicts:
	pyfpdb/Database.py
	pyfpdb/TableWindow.py
This commit is contained in:
Eric Blade 2010-12-03 16:14:10 -05:00
commit 8855530617
18 changed files with 466 additions and 156 deletions

2
pyfpdb/Anonymise.py Normal file → Executable file
View File

@ -26,6 +26,8 @@ import HandHistoryConverter
import Configuration import Configuration
import sys import sys
# command line is:
# ./Anonymise.py -f <valid path to HH file> -k <name of input filter>
(options, argv) = Options.fpdb_options() (options, argv) = Options.fpdb_options()
config = Configuration.Config() config = Configuration.Config()

View File

@ -479,12 +479,13 @@ class Import:
self.hhArchiveBase = node.getAttribute("hhArchiveBase") self.hhArchiveBase = node.getAttribute("hhArchiveBase")
self.hhBulkPath = node.getAttribute("hhBulkPath") self.hhBulkPath = node.getAttribute("hhBulkPath")
self.saveActions = string_to_bool(node.getAttribute("saveActions"), default=False) self.saveActions = string_to_bool(node.getAttribute("saveActions"), default=False)
self.cacheSessions = string_to_bool(node.getAttribute("cacheSessions"), default=False)
self.fastStoreHudCache = string_to_bool(node.getAttribute("fastStoreHudCache"), default=False) self.fastStoreHudCache = string_to_bool(node.getAttribute("fastStoreHudCache"), default=False)
self.saveStarsHH = string_to_bool(node.getAttribute("saveStarsHH"), default=False) self.saveStarsHH = string_to_bool(node.getAttribute("saveStarsHH"), default=False)
def __str__(self): def __str__(self):
return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\n" \ return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\n" \
% (self.interval, self.callFpdbHud, self.hhArchiveBase, self.saveActions, self.fastStoreHudCache) % (self.interval, self.callFpdbHud, self.hhArchiveBase, self.saveActions, self.cacheSessions, self.fastStoreHudCache)
class HudUI: class HudUI:
def __init__(self, node): def __init__(self, node):
@ -1259,6 +1260,9 @@ class Config:
try: imp['saveActions'] = self.imp.saveActions try: imp['saveActions'] = self.imp.saveActions
except: imp['saveActions'] = False except: imp['saveActions'] = False
try: imp['cacheSessions'] = self.imp.cacheSessions
except: imp['cacheSessions'] = False
try: imp['saveStarsHH'] = self.imp.saveStarsHH try: imp['saveStarsHH'] = self.imp.saveStarsHH
except: imp['saveStarsHH'] = False except: imp['saveStarsHH'] = False

View File

@ -37,7 +37,7 @@ import os
import sys import sys
import traceback import traceback
from datetime import datetime, date, time, timedelta from datetime import datetime, date, time, timedelta
from time import time, strftime, sleep, strptime from time import time, strftime, sleep
from decimal import Decimal from decimal import Decimal
import string import string
import re import re
@ -73,7 +73,7 @@ except ImportError:
use_numpy = False use_numpy = False
DB_VERSION = 145 DB_VERSION = 146
# Variance created as sqlite has a bunch of undefined aggregate functions. # Variance created as sqlite has a bunch of undefined aggregate functions.
@ -255,6 +255,11 @@ class Database:
self.database = db_params['db-databaseName'] self.database = db_params['db-databaseName']
self.host = db_params['db-host'] self.host = db_params['db-host']
self.db_path = '' self.db_path = ''
gen = c.get_general_params()
self.day_start = 0
if 'day_start' in gen:
self.day_start = float(gen['day_start'])
# where possible avoid creating new SQL instance by using the global one passed in # where possible avoid creating new SQL instance by using the global one passed in
if sql is None: if sql is None:
@ -689,12 +694,16 @@ class Database:
else: else:
if row and row[0]: if row and row[0]:
self.hand_1day_ago = int(row[0]) self.hand_1day_ago = int(row[0])
d = timedelta(days=hud_days) tz = datetime.utcnow() - datetime.today()
tz_offset = tz.seconds/3600
tz_day_start_offset = self.day_start + tz_offset
d = timedelta(days=hud_days, hours=tz_day_start_offset)
now = datetime.utcnow() - d now = datetime.utcnow() - d
self.date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day) self.date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day)
d = timedelta(days=h_hud_days) d = timedelta(days=h_hud_days, hours=tz_day_start_offset)
now = datetime.utcnow() - d now = datetime.utcnow() - d
self.h_date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day) self.h_date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day)
@ -788,7 +797,7 @@ class Database:
elif h_hud_style == 'S': elif h_hud_style == 'S':
h_stylekey = 'zzzzzzz' # all stylekey values should be lower than this h_stylekey = 'zzzzzzz' # all stylekey values should be lower than this
else: else:
h_stylekey = '000000' h_stylekey = '00000000'
log.info('h_hud_style: %s' % h_hud_style) log.info('h_hud_style: %s' % h_hud_style)
#elif h_hud_style == 'H': #elif h_hud_style == 'H':
@ -1823,8 +1832,15 @@ class Database:
def storeHudCache(self, gid, pids, starttime, pdata): def storeHudCache(self, gid, pids, starttime, pdata):
"""Update cached statistics. If update fails because no record exists, do an insert.""" """Update cached statistics. If update fails because no record exists, do an insert."""
tz = datetime.utcnow() - datetime.today()
tz_offset = tz.seconds/3600
tz_day_start_offset = self.day_start + tz_offset
d = timedelta(hours=tz_day_start_offset)
starttime_offset = starttime - d
if self.use_date_in_hudcache: if self.use_date_in_hudcache:
styleKey = datetime.strftime(starttime, 'd%y%m%d') styleKey = datetime.strftime(starttime_offset, 'd%y%m%d')
#styleKey = "d%02d%02d%02d" % (hand_start_time.year-2000, hand_start_time.month, hand_start_time.day) #styleKey = "d%02d%02d%02d" % (hand_start_time.year-2000, hand_start_time.month, hand_start_time.day)
else: else:
# hard-code styleKey as 'A000000' (all-time cache, no key) for now # hard-code styleKey as 'A000000' (all-time cache, no key) for now
@ -1950,6 +1966,53 @@ class Database:
else: else:
#print "DEBUG: Successfully updated HudCacho using UPDATE" #print "DEBUG: Successfully updated HudCacho using UPDATE"
pass pass
def storeSessionsCache(self, pids, starttime, pdata):
"""Update cached sessions. If update fails because no record exists, do an insert."""
#In development
pass
#update_sessionscache = self.sql.query['update_sessionscache']
#update_sessionscache = update_sessionscache.replace('%s', self.sql.query['placeholder'])
#insert_sessionscache = self.sql.query['insert_sessionscache']
#insert_sessionscache = insert_sessionscache.replace('%s', self.sql.query['placeholder'])
#merge_sessionscache = self.sql.query['merge_sessionscache']
#merge_sessionscache = merge_sessionscache.replace('%s', self.sql.query['placeholder'])
#print "DEBUG: %s %s %s" %(hid, pids, pdata)
#inserts = []
#for p in pdata:
#line = [0]*5
#line[0] = 1 # HDs
#line[1] = pdata[p]['totalProfit']
#line[2] = pids[p] # playerId
#line[3] = sessionStart
#line[4] = sessionEnd
#inserts.append(line)
#cursor = self.get_cursor()
#for row in inserts:
# Try to do the update first:
#num = cursor.execute(update_sessionscache, row)
#print "DEBUG: values: %s" % row[-3:]
# Test statusmessage to see if update worked, do insert if not
# num is a cursor in sqlite
#if ((self.backend == self.PGSQL and cursor.statusmessage != "UPDATE 1")
#or (self.backend == self.MYSQL_INNODB and num == 0)
#or (self.backend == self.SQLITE and num.rowcount == 0)):
#move the last 6 items in WHERE clause of row from the end of the array
# to the beginning for the INSERT statement
#print "DEBUG: using INSERT: %s" % num
#row = row[-3:] + row[:-3]
#num = cursor.execute(insert_sessionscache, row)
#print "DEBUG: Successfully(?: %s) updated HudCacho using INSERT" % num
#else:
#print "DEBUG: Successfully updated HudCacho using UPDATE"
#pass
def isDuplicate(self, gametypeID, siteHandNo): def isDuplicate(self, gametypeID, siteHandNo):
dup = False dup = False

View File

@ -33,6 +33,7 @@ class FullTiltPokerSummary(TourneySummary):
games = { # base, category games = { # base, category
"Hold'em" : ('hold','holdem'), "Hold'em" : ('hold','holdem'),
'Omaha' : ('hold','omahahi'), 'Omaha' : ('hold','omahahi'),
'Omahai Hi' : ('hold','omahahi'),
'Omaha Hi/Lo' : ('hold','omahahilo'), 'Omaha Hi/Lo' : ('hold','omahahilo'),
'Razz' : ('stud','razz'), 'Razz' : ('stud','razz'),
'RAZZ' : ('stud','razz'), 'RAZZ' : ('stud','razz'),
@ -55,7 +56,7 @@ class FullTiltPokerSummary(TourneySummary):
re_TourneyInfo = re.compile(u""" re_TourneyInfo = re.compile(u"""
\s.* \s.*
(?P<TYPE>Tournament|Sit\s\&\sGo)\s\((?P<TOURNO>[0-9]+)\)(\s+)? (?P<TYPE>Tournament|Sit\s\&\sGo)\s\((?P<TOURNO>[0-9]+)\)(\s+)?
(?P<GAME>Hold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|5\sCard\sDraw)\s+ (?P<GAME>Hold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|5\sCard\sDraw)\s+
(?P<LIMIT>No\sLimit|Limit|LIMIT|Pot\sLimit)\s+ (?P<LIMIT>No\sLimit|Limit|LIMIT|Pot\sLimit)\s+
(Buy-In:\s\$(?P<BUYIN>[.\d]+)(\s\+\s\$(?P<FEE>[.\d]+))?\s+)? (Buy-In:\s\$(?P<BUYIN>[.\d]+)(\s\+\s\$(?P<FEE>[.\d]+))?\s+)?
(Buy-In\sChips:\s(?P<CHIPS>\d+)\s+)? (Buy-In\sChips:\s(?P<CHIPS>\d+)\s+)?

View File

@ -45,8 +45,8 @@ class GuiStove():
self.notebook.set_show_border(True) self.notebook.set_show_border(True)
self.createFlopTab() self.createFlopTab()
#self.createStudTab() self.createStudTab()
#self.createDrawTab() self.createDrawTab()
self.mainHBox.add(self.notebook) self.mainHBox.add(self.notebook)
@ -92,6 +92,19 @@ Thankyou
combobox.set_active(0) combobox.set_active(0)
return combobox return combobox
def createDrawTab(self):
tab_title = "Draw"
label = gtk.Label(tab_title)
ddbox = gtk.VBox(False, 0)
self.notebook.append_page(ddbox, label)
def createStudTab(self):
tab_title = "Stud"
label = gtk.Label(tab_title)
ddbox = gtk.VBox(False, 0)
self.notebook.append_page(ddbox, label)
def createFlopTab(self): def createFlopTab(self):
# hierarchy: hbox / ddbox / ddhbox / Label + flop_games_cb | label + players_cb # hierarchy: hbox / ddbox / ddhbox / Label + flop_games_cb | label + players_cb

View File

@ -2,7 +2,7 @@
<FreePokerToolsConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FreePokerToolsConfig.xsd"> <FreePokerToolsConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FreePokerToolsConfig.xsd">
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import> <import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True" cacheSessions="False"></import>
<!-- These values determine what stats are displayed in the HUD <!-- These values determine what stats are displayed in the HUD

View File

@ -12,7 +12,7 @@
config_difficulty="expert" config_difficulty="expert"
/> />
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import> <import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True" cacheSessions="False"></import>
<gui_cash_stats> <gui_cash_stats>
<col col_name="game" disp_all="True" disp_posn="True" col_title="Game" xalignment="0.0" field_format="%s" field_type="str" /> <col col_name="game" disp_all="True" disp_posn="True" col_title="Game" xalignment="0.0" field_format="%s" field_type="str" />

View File

@ -192,11 +192,12 @@ class HUD_main(object):
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
try: try:
table.gdkhandle = gtk.gdk.window_foreign_new(table.number)
newlabel = gtk.Label("%s - %s" % (table.site, table_name)) newlabel = gtk.Label("%s - %s" % (table.site, table_name))
self.vb.add(newlabel) self.vb.add(newlabel)
newlabel.show() newlabel.show()
self.main_window.resize_children() self.main_window.resize_children()
self.hud_dict[table.key].tablehudlabel = newlabel self.hud_dict[table.key].tablehudlabel = newlabel
self.hud_dict[table.key].create(new_hand_id, self.config, stat_dict, cards) self.hud_dict[table.key].create(new_hand_id, self.config, stat_dict, cards)
for m in self.hud_dict[table.key].aux_windows: for m in self.hud_dict[table.key].aux_windows:
@ -308,7 +309,8 @@ class HUD_main(object):
t1 = time.time() t1 = time.time()
if type == "tour": # hand is from a tournament if type == "tour": # hand is from a tournament
temp_key = tour_number # temp_key = tour_number
temp_key = "%s Table %s" % (tour_number, tab_number)
else: else:
temp_key = table_name temp_key = table_name

View File

@ -278,6 +278,9 @@ db: a connected Database object"""
def updateHudCache(self, db): def updateHudCache(self, db):
db.storeHudCache(self.dbid_gt, self.dbid_pids, self.startTime, self.stats.getHandsPlayers()) db.storeHudCache(self.dbid_gt, self.dbid_pids, self.startTime, self.stats.getHandsPlayers())
def updateSessionsCache(self, db):
db.storeSessionsCache(self.dbid_pids, self.startTime, self.stats.getHandsPlayers())
def select(self, handId): def select(self, handId):
""" Function to create Hand object from database """ """ Function to create Hand object from database """

10
pyfpdb/Mucked.py Executable file → Normal file
View File

@ -25,17 +25,17 @@ Mucked cards display for FreePokerTools HUD.
# to do # to do
# Standard Library modules # Standard Library modules
import sys #import sys
import pprint #import pprint
# pyGTK modules # pyGTK modules
import pygtk #import pygtk
import gtk import gtk
import gobject import gobject
# FreePokerTools modules # FreePokerTools modules
import Configuration #import Configuration
import Database #import Database
import Card import Card
class Aux_Window(object): class Aux_Window(object):

View File

@ -45,22 +45,27 @@ class PartyPoker(HandHistoryConverter):
codepage = "utf8" codepage = "utf8"
siteId = 9 siteId = 9
filetype = "text" filetype = "text"
sym = {'USD': "\$", } sym = {'USD': "\$", 'EUR': u"\u20ac", 'T$': ""}
currencies = {"\$": "USD", "$": "USD", u"\xe2\x82\xac": "EUR", u"\u20ac": "EUR", '': "T$"}
substitutions = {
'LEGAL_ISO' : "USD|EUR", # legal ISO currency codes
'LS' : "\$|\u20AC|\xe2\x82\xac|" # legal currency symbols - Euro(cp1252, utf-8)
}
# Static regexes # Static regexes
# $5 USD NL Texas Hold'em - Saturday, July 25, 07:53:52 EDT 2009 # $5 USD NL Texas Hold'em - Saturday, July 25, 07:53:52 EDT 2009
# NL Texas Hold'em $1 USD Buy-in Trny:45685440 Level:8 Blinds-Antes(600/1 200 -50) - Sunday, May 17, 11:25:07 MSKS 2009 # NL Texas Hold'em $1 USD Buy-in Trny:45685440 Level:8 Blinds-Antes(600/1 200 -50) - Sunday, May 17, 11:25:07 MSKS 2009
re_GameInfoRing = re.compile(""" re_GameInfoRing = re.compile(u"""
(?P<CURRENCY>\$|)\s*(?P<RINGLIMIT>[.,0-9]+)([.,0-9/$]+)?\s*(?:USD)?\s* (?P<CURRENCY>[%(LS)s])\s*(?P<RINGLIMIT>[.,0-9]+)([.,0-9/$]+)?\s*(?:%(LEGAL_ISO)s)?\s*
(?P<LIMIT>(NL|PL|))\s* (?P<LIMIT>(NL|PL|))\s*
(?P<GAME>(Texas\ Hold\'em|Omaha|7 Card Stud Hi-Lo)) (?P<GAME>(Texas\ Hold\'em|Omaha|7\ Card\ Stud\ Hi-Lo))
\s*\-\s* \s*\-\s*
(?P<DATETIME>.+) (?P<DATETIME>.+)
""", re.VERBOSE | re.UNICODE) """ % substitutions, re.VERBOSE | re.UNICODE)
re_GameInfoTrny = re.compile(""" re_GameInfoTrny = re.compile("""
(?P<LIMIT>(NL|PL|))\s* (?P<LIMIT>(NL|PL|))\s*
(?P<GAME>(Texas\ Hold\'em|Omaha))\s+ (?P<GAME>(Texas\ Hold\'em|Omaha))\s+
(?:(?P<BUYIN>\$?[.,0-9]+)\s*(?P<BUYIN_CURRENCY>USD)?\s*Buy-in\s+)? (?:(?P<BUYIN>\$?[.,0-9]+)\s*(?P<BUYIN_CURRENCY>%(LEGAL_ISO)s)?\s*Buy-in\s+)?
Trny:\s?(?P<TOURNO>\d+)\s+ Trny:\s?(?P<TOURNO>\d+)\s+
Level:\s*(?P<LEVEL>\d+)\s+ Level:\s*(?P<LEVEL>\d+)\s+
((Blinds|Stakes)(?:-Antes)?)\( ((Blinds|Stakes)(?:-Antes)?)\(
@ -70,15 +75,14 @@ class PartyPoker(HandHistoryConverter):
\) \)
\s*\-\s* \s*\-\s*
(?P<DATETIME>.+) (?P<DATETIME>.+)
""", re.VERBOSE | re.UNICODE) """ % substitutions, re.VERBOSE | re.UNICODE)
re_Hid = re.compile("^Game \#(?P<HID>\d+) starts.") re_Hid = re.compile("Game \#(?P<HID>\d+) starts.")
re_PlayerInfo = re.compile(""" re_PlayerInfo = re.compile(u"""
Seat\s(?P<SEAT>\d+):\s Seat\s(?P<SEAT>\d+):\s
(?P<PNAME>.*)\s (?P<PNAME>.*)\s
\(\s*\$?(?P<CASH>[0-9,.]+)\s*(?:USD|)\s*\) \(\s*[%(LS)s]?(?P<CASH>[0-9,.]+)\s*(?:%(LEGAL_ISO)s|)\s*\)
""" , """ % substitutions, re.VERBOSE| re.UNICODE)
re.VERBOSE)
re_HandInfo = re.compile(""" re_HandInfo = re.compile("""
^Table\s+(?P<TTYPE>[$a-zA-Z0-9 ]+)?\s+ ^Table\s+(?P<TTYPE>[$a-zA-Z0-9 ]+)?\s+
@ -123,18 +127,16 @@ class PartyPoker(HandHistoryConverter):
self.compiledPlayers = players self.compiledPlayers = players
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")" player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
subst = {'PLYR': player_re, 'CUR_SYM': hand.SYMBOL[hand.gametype['currency']], subst = {'PLYR': player_re, 'CUR_SYM': self.sym[hand.gametype['currency']],
'CUR': hand.gametype['currency'] if hand.gametype['currency']!='T$' else ''} 'CUR': hand.gametype['currency'] if hand.gametype['currency']!='T$' else ''}
for key in ('CUR_SYM', 'CUR'):
subst[key] = re.escape(subst[key])
self.re_PostSB = re.compile( self.re_PostSB = re.compile(
r"^%(PLYR)s posts small blind \[%(CUR_SYM)s(?P<SB>[.,0-9]+) ?%(CUR)s\]\." % subst, r"^%(PLYR)s posts small blind \[%(CUR_SYM)s(?P<SB>[.,0-9]+) ?%(CUR)s\]\."
re.MULTILINE) % subst, re.MULTILINE)
self.re_PostBB = re.compile( self.re_PostBB = re.compile(
r"^%(PLYR)s posts big blind \[%(CUR_SYM)s(?P<BB>[.,0-9]+) ?%(CUR)s\]\." % subst, u"%(PLYR)s posts big blind \[%(CUR_SYM)s(?P<BB>[.,0-9]+) ?%(CUR)s\]\."
re.MULTILINE) % subst, re.MULTILINE)
self.re_PostDead = re.compile( self.re_PostDead = re.compile(
r"^%(PLYR)s posts big blind \+ dead \[(?P<BBNDEAD>[.,0-9]+) ?%(CUR_SYM)s\]\." % subst, r"^%(PLYR)s posts big blind + dead \[(?P<BBNDEAD>[.,0-9]+) ?%(CUR_SYM)s\]\." % subst,
re.MULTILINE) re.MULTILINE)
self.re_Antes = re.compile( self.re_Antes = re.compile(
r"^%(PLYR)s posts ante \[%(CUR_SYM)s(?P<ANTE>[.,0-9]+) ?%(CUR)s\]" % subst, r"^%(PLYR)s posts ante \[%(CUR_SYM)s(?P<ANTE>[.,0-9]+) ?%(CUR)s\]" % subst,
@ -142,11 +144,10 @@ class PartyPoker(HandHistoryConverter):
self.re_HeroCards = re.compile( self.re_HeroCards = re.compile(
r"^Dealt to %(PLYR)s \[\s*(?P<NEWCARDS>.+)\s*\]" % subst, r"^Dealt to %(PLYR)s \[\s*(?P<NEWCARDS>.+)\s*\]" % subst,
re.MULTILINE) re.MULTILINE)
self.re_Action = re.compile(r""" self.re_Action = re.compile(u"""
^%(PLYR)s\s+(?P<ATYPE>bets|checks|raises|calls|folds|is\sall-In) ^%(PLYR)s\s+(?P<ATYPE>bets|checks|raises|calls|folds|is\sall-In)
(?:\s+\[%(CUR_SYM)s(?P<BET>[.,\d]+)\s*%(CUR)s\])? (?:\s+\[%(CUR_SYM)s(?P<BET>[.,\d]+)\s*%(CUR)s\])?
""" % subst, """ % subst, re.MULTILINE|re.VERBOSE)
re.MULTILINE|re.VERBOSE)
self.re_ShownCards = re.compile( self.re_ShownCards = re.compile(
r"^%s (?P<SHOWED>(?:doesn\'t )?shows?) " % player_re + r"^%s (?P<SHOWED>(?:doesn\'t )?shows?) " % player_re +
r"\[ *(?P<CARDS>.+) *\](?P<COMBINATION>.+)\.", r"\[ *(?P<CARDS>.+) *\](?P<COMBINATION>.+)\.",
@ -181,10 +182,6 @@ class PartyPoker(HandHistoryConverter):
return self._gameType return self._gameType
return self._gameType return self._gameType
@staticmethod
def decode_hand_text(handText):
return handText.encode("latin1").decode(LOCALE_ENCODING)
def determineGameType(self, handText): def determineGameType(self, handText):
"""inspect the handText and return the gametype dict """inspect the handText and return the gametype dict
@ -192,7 +189,6 @@ class PartyPoker(HandHistoryConverter):
{'limitType': xxx, 'base': xxx, 'category': xxx}""" {'limitType': xxx, 'base': xxx, 'category': xxx}"""
info = {} info = {}
handText = self.decode_hand_text(handText)
m = self._getGameType(handText) m = self._getGameType(handText)
m_20BBmin = self.re_20BBmin.search(handText) m_20BBmin = self.re_20BBmin.search(handText)
if m is None: if m is None:
@ -210,7 +206,6 @@ class PartyPoker(HandHistoryConverter):
'Omaha' : ('hold','omahahi'), 'Omaha' : ('hold','omahahi'),
"7 Card Stud Hi-Lo" : ('stud','studhi'), "7 Card Stud Hi-Lo" : ('stud','studhi'),
} }
currencies = { '$':'USD', '':'T$' }
for expectedField in ['LIMIT', 'GAME']: for expectedField in ['LIMIT', 'GAME']:
if mg[expectedField] is None: if mg[expectedField] is None:
@ -243,7 +238,7 @@ class PartyPoker(HandHistoryConverter):
info['bb'] = "%.2f" % (bb) info['bb'] = "%.2f" % (bb)
info['sb'] = "%.2f" % (sb) info['sb'] = "%.2f" % (sb)
info['currency'] = currencies[mg['CURRENCY']] info['currency'] = self.currencies[mg['CURRENCY']]
else: else:
info['sb'] = clearMoneyString(mg['SB']) info['sb'] = clearMoneyString(mg['SB'])
info['bb'] = clearMoneyString(mg['BB']) info['bb'] = clearMoneyString(mg['BB'])
@ -253,15 +248,11 @@ class PartyPoker(HandHistoryConverter):
def readHandInfo(self, hand): def readHandInfo(self, hand):
# we should redecode handtext here (as it imposible to it above)
# if you know more accurate way to do it - tell me
hand.handText = self.decode_hand_text(hand.handText)
info = {} info = {}
try: try:
info.update(self.re_Hid.search(hand.handText).groupdict()) info.update(self.re_Hid.search(hand.handText).groupdict())
except: except AttributeError, e:
raise FpdbParseError(_("Cannot read HID for current hand")) raise FpdbParseError(_("Cannot read HID for current hand: %s" % e))
try: try:
info.update(self.re_HandInfo.search(hand.handText,re.DOTALL).groupdict()) info.update(self.re_HandInfo.search(hand.handText,re.DOTALL).groupdict())
@ -374,7 +365,6 @@ class PartyPoker(HandHistoryConverter):
else: else:
#zero stacked players are added later #zero stacked players are added later
zeroStackPlayers.append([int(a.group('SEAT')), a.group('PNAME'), clearMoneyString(a.group('CASH'))]) zeroStackPlayers.append([int(a.group('SEAT')), a.group('PNAME'), clearMoneyString(a.group('CASH'))])
if hand.gametype['type'] == 'ring': if hand.gametype['type'] == 'ring':
#finds first vacant seat after an exact seat #finds first vacant seat after an exact seat
def findFirstEmptySeat(startSeat): def findFirstEmptySeat(startSeat):

View File

@ -264,7 +264,7 @@ class PokerStars(HandHistoryConverter):
hand.buyinCurrency="PSFP" hand.buyinCurrency="PSFP"
else: else:
#FIXME: handle other currencies, FPP, play money #FIXME: handle other currencies, FPP, play money
raise FpdbParseError(_("failed to detect currency")) raise FpdbParseError(_("Failed to detect currency: '%s'" % info[key]))
info['BIAMT'] = info['BIAMT'].strip(u'$€FPP') info['BIAMT'] = info['BIAMT'].strip(u'$€FPP')

View File

@ -2479,7 +2479,11 @@ class Sql:
select s.name AS siteName select s.name AS siteName
,t.tourneyTypeId AS tourneyTypeId ,t.tourneyTypeId AS tourneyTypeId
,tt.currency AS currency ,tt.currency AS currency
,(CASE WHEN tt.currency = 'USD' THEN tt.buyIn/100.0 ELSE tt.buyIn END) AS buyIn ,(CASE
WHEN tt.currency = 'USD' THEN tt.buyIn/100.0
WHEN tt.currency = 'EUR' THEN tt.buyIn/100.0
ELSE tt.buyIn
END) AS buyIn
,tt.fee/100.0 AS fee ,tt.fee/100.0 AS fee
,tt.category AS category ,tt.category AS category
,tt.limitType AS limitType ,tt.limitType AS limitType
@ -2512,7 +2516,11 @@ class Sql:
select s.name AS siteName select s.name AS siteName
,t.tourneyTypeId AS tourneyTypeId ,t.tourneyTypeId AS tourneyTypeId
,tt.currency AS currency ,tt.currency AS currency
,(CASE WHEN tt.currency = 'USD' THEN tt.buyIn/100.0 ELSE tt.buyIn END) AS buyIn ,(CASE
WHEN tt.currency = 'USD' THEN tt.buyIn/100.0
WHEN tt.currency = 'EUR' THEN tt.buyIn/100.0
ELSE tt.buyIn
END) AS buyIn
,tt.fee/100.0 AS fee ,tt.fee/100.0 AS fee
,tt.category AS category ,tt.category AS category
,tt.limitType AS limitType ,tt.limitType AS limitType
@ -2546,7 +2554,11 @@ class Sql:
select s.name AS siteName select s.name AS siteName
,t.tourneyTypeId AS tourneyTypeId ,t.tourneyTypeId AS tourneyTypeId
,tt.currency AS currency ,tt.currency AS currency
,(CASE WHEN tt.currency = 'USD' THEN tt.buyIn/100.0 ELSE tt.buyIn END) AS buyIn ,(CASE
WHEN tt.currency = 'USD' THEN tt.buyIn/100.0
WHEN tt.currency = 'EUR' THEN tt.buyIn/100.0
ELSE tt.buyIn
END) AS buyIn
,tt.fee/100.0 AS fee ,tt.fee/100.0 AS fee
,tt.category AS category ,tt.category AS category
,tt.limitType AS limitType ,tt.limitType AS limitType
@ -3968,7 +3980,8 @@ class Sql:
AND playerId=%s AND playerId=%s
AND activeSeats=%s AND activeSeats=%s
AND position=%s AND position=%s
AND tourneyTypeId+0=%s AND (case when tourneyTypeId is NULL then 1 else
(case when tourneyTypeId+0=%s then 1 else 0 end) end)=1
AND styleKey=%s""" AND styleKey=%s"""
self.query['get_hero_hudcache_start'] = """select min(hc.styleKey) self.query['get_hero_hudcache_start'] = """select min(hc.styleKey)

View File

@ -22,13 +22,56 @@ OFFSUIT = 2
ev = pokereval.PokerEval() ev = pokereval.PokerEval()
holder = None
class Holder: class Stove:
def __init__(self): def __init__(self):
self.hand = None self.hand = None
self.board = None self.board = None
self.range = None self.h_range = None
def set_board_with_list(self, board):
pass
def set_board_string(self, string):
board = Board()
# Board
b = string.strip().split()
if len(b) > 4:
board.b5 = b[4]
if len(b) > 3:
board.b4 = b[3]
if len(b) > 2:
board.b1 = b[0]
board.b2 = b[1]
board.b3 = b[2]
self.board = board
def set_hero_cards_string(self, string):
# Our pocket cards
cc = string.strip().split()
c1 = cc[0]
c2 = cc[1]
pocket_cards = Cards(c1, c2)
self.hand = pocket_cards
def set_villain_range_string(self, string):
# Villain's range
h_range = Range()
hands_in_range = string.strip().split(',')
for h in hands_in_range:
_h = h.strip()
if len(_h) > 3:
cc = _h.split()
r1 = cc[0]
r2 = cc[1]
vp = Cards(r1, r2)
h_range.add(vp)
else:
h_range.expand(expand_hands(_h, self.hand, self.board))
self.h_range = h_range
class Cards: class Cards:
@ -104,37 +147,17 @@ class SumEV:
self.n_ties += ev.n_ties self.n_ties += ev.n_ties
self.n_losses += ev.n_losses self.n_losses += ev.n_losses
def show(self, hand, range): def show(self, hand, h_range):
win_pct = 100 * (float(self.n_wins) / float(self.n_hands)) win_pct = 100 * (float(self.n_wins) / float(self.n_hands))
lose_pct = 100 * (float(self.n_losses) / float(self.n_hands)) lose_pct = 100 * (float(self.n_losses) / float(self.n_hands))
tie_pct = 100 * (float(self.n_ties) / float(self.n_hands)) tie_pct = 100 * (float(self.n_ties) / float(self.n_hands))
print 'Enumerated %d possible plays.' % self.n_hands print 'Enumerated %d possible plays.' % self.n_hands
print 'Your hand: (%s %s)' % (hand.c1, hand.c2) print 'Your hand: (%s %s)' % (hand.c1, hand.c2)
print 'Against the range: %s\n' % cards_from_range(range) print 'Against the range: %s\n' % cards_from_range(h_range)
print ' Win Lose Tie' print ' Win Lose Tie'
print ' %5.2f%% %5.2f%% %5.2f%%' % (win_pct, lose_pct, tie_pct) print ' %5.2f%% %5.2f%% %5.2f%%' % (win_pct, lose_pct, tie_pct)
def usage(me):
print """Texas Hold'Em odds calculator
Calculates odds against a range of hands.
To use: %s '<board cards>' '<your hand>' '<opponent's range>' [...]
Separate cards with space.
Separate hands in range with commas.
""" % me
def cards_from_range(range):
s = '{'
for h in range:
if h.c1 == '__' and h.c2 == '__':
s += 'random, '
else:
s += '%s%s, ' % (h.c1, h.c2)
s = s.rstrip(', ')
s += '}'
return s
# Expands hand abbreviations such as JJ and AK to full hand ranges. # Expands hand abbreviations such as JJ and AK to full hand ranges.
@ -159,7 +182,7 @@ def expand_hands(abbrev, hand, board):
else: else:
selection = ANY selection = ANY
range = [] h_range = []
considered = set() considered = set()
for s1 in SUITS: for s1 in SUITS:
c1 = r1 + s1 c1 = r1 + s1
@ -173,54 +196,18 @@ def expand_hands(abbrev, hand, board):
elif selection == OFFSUIT and s1 == s2: elif selection == OFFSUIT and s1 == s2:
continue continue
if c2 not in considered and c2 not in known_cards: if c2 not in considered and c2 not in known_cards:
range.append(Cards(c1, c2)) h_range.append(Cards(c1, c2))
return range return h_range
def parse_args(args, container): def parse_args(args, container):
# args[0] is the path being executed; need 3 more args # args[0] is the path being executed; need 3 more args
if len(args) < 4: if len(args) < 4:
return False return False
board = Board() container.set_board_string(args[1])
container.set_hero_cards_string(args[2])
# Board container.set_villain_range_string(args[3])
b = args[1].strip().split()
if len(b) > 4:
board.b5 = b[4]
if len(b) > 3:
board.b4 = b[3]
if len(b) > 2:
board.b1 = b[0]
board.b2 = b[1]
board.b3 = b[2]
# Our pocket cards
cc = args[2].strip().split()
c1 = cc[0]
c2 = cc[1]
pocket_cards = Cards(c1, c2)
# Villain's range
range = Range()
hands_in_range = args[3].strip().split(',')
for h in hands_in_range:
_h = h.strip()
if len(_h) > 3:
cc = _h.split()
r1 = cc[0]
r2 = cc[1]
vp = Cards(r1, r2)
range.add(vp)
else:
range.expand(expand_hands(_h, pocket_cards, board))
holder.hand = pocket_cards
holder.range = range
holder.board = board
return True return True
@ -273,7 +260,7 @@ def odds_for_range(holder):
iters = random.randint(25000, 125000) iters = random.randint(25000, 125000)
else: else:
iters = -1 iters = -1
for h in holder.range.get(): for h in holder.h_range.get():
e = odds_for_hand( e = odds_for_hand(
[holder.hand.c1, holder.hand.c2], [holder.hand.c1, holder.hand.c2],
[h.c1, h.c2], [h.c1, h.c2],
@ -282,28 +269,35 @@ def odds_for_range(holder):
) )
sev.add(e) sev.add(e)
sev.show(holder.hand, holder.range.get()) sev.show(holder.hand, holder.h_range.get())
def usage(me):
print """Texas Hold'Em odds calculator
Calculates odds against a range of hands.
holder = Holder() To use: %s '<board cards>' '<your hand>' '<opponent's range>' [...]
if not parse_args(sys.argv, holder):
usage(sys.argv[0])
sys.exit(2)
odds_for_range(holder)
# debugs
#print '%s, %s' % ( holder.hand.c1, holder.hand.c2)
#print '%s %s %s %s %s' % (holder.board.b1, holder.board.b2,
# holder.board.b3, holder.board.b4, holder.board.b5)
#while True:
# try:
# vl = holder.range.get()
# v = vl.pop()
# print '\t%s %s' % (v.c1, v.c2)
# except IndexError:
# break
Separate cards with space.
Separate hands in range with commas.
""" % me
def cards_from_range(h_range):
s = '{'
for h in h_range:
if h.c1 == '__' and h.c2 == '__':
s += 'random, '
else:
s += '%s%s, ' % (h.c1, h.c2)
s = s.rstrip(', ')
s += '}'
return s
def main(argv=None):
stove = Stove()
if not parse_args(sys.argv, stove):
usage(sys.argv[0])
sys.exit(2)
odds_for_range(stove)
if __name__ == '__main__':
sys.exit(main())

24
pyfpdb/fpdb_import.py Executable file → Normal file
View File

@ -83,6 +83,7 @@ class Importer:
self.pos_in_file = {} # dict to remember how far we have read in the file self.pos_in_file = {} # dict to remember how far we have read in the file
#Set defaults #Set defaults
self.callHud = self.config.get_import_parameters().get("callFpdbHud") self.callHud = self.config.get_import_parameters().get("callFpdbHud")
self.cacheSessions = self.config.get_import_parameters().get("cacheSessions")
# CONFIGURATION OPTIONS # CONFIGURATION OPTIONS
self.settings.setdefault("minPrint", 30) self.settings.setdefault("minPrint", 30)
@ -110,6 +111,9 @@ class Importer:
#Set functions #Set functions
def setCallHud(self, value): def setCallHud(self, value):
self.callHud = value self.callHud = value
def setCacheSessions(self, value):
self.cacheSessions = value
def setMinPrint(self, value): def setMinPrint(self, value):
self.settings['minPrint'] = int(value) self.settings['minPrint'] = int(value)
@ -491,14 +495,22 @@ class Importer:
if hand is not None and not hand.is_duplicate: if hand is not None and not hand.is_duplicate:
hand.updateHudCache(self.database) hand.updateHudCache(self.database)
self.database.commit() self.database.commit()
# Call sessionsCache update
if self.cacheSessions:
for hand in handlist:
if hand is not None and not hand.is_duplicate:
hand.updateSessionsCache(self.database)
self.database.commit()
#pipe the Hands.id out to the HUD #pipe the Hands.id out to the HUD
for hid in to_hud: if self.caller:
try: for hid in to_hud:
print _("fpdb_import: sending hand to hud"), hand.dbid_hands, "pipe =", self.caller.pipe_to_hud try:
self.caller.pipe_to_hud.stdin.write("%s" % (hid) + os.linesep) print _("fpdb_import: sending hand to hud"), hand.dbid_hands, "pipe =", self.caller.pipe_to_hud
except IOError, e: self.caller.pipe_to_hud.stdin.write("%s" % (hid) + os.linesep)
log.error(_("Failed to send hand to HUD: %s") % e) except IOError, e:
log.error(_("Failed to send hand to HUD: %s") % e)
errors = getattr(hhc, 'numErrors') errors = getattr(hhc, 'numErrors')
stored = getattr(hhc, 'numHands') stored = getattr(hhc, 'numHands')

View File

@ -0,0 +1,32 @@
Game #9864152000 starts.
#Game No : 9864152000
***** Hand History for Game 9864152000 *****
€10 EUR NL Texas Hold'em - Sunday, November 21, 19:00:00 CET 2010
Table Table 183347 (Real Money)
Seat 1 is the button
Total number of players : 5/6
Seat 3: Hero ( €10 EUR )
Seat 6: Player6 ( €16.49 EUR )
Seat 4: Player4 ( €10.73 EUR )
Seat 1: Player1 ( €8.56 EUR )
Seat 2: Player2 ( €4.90 EUR )
Player2 posts small blind [€0.05 EUR].
Hero posts big blind [€0.10 EUR].
** Dealing down cards **
Dealt to Hero [ Ah Kc ]
Player4 calls [€0.10 EUR]
Player6 calls [€0.10 EUR]
Player1 calls [€0.10 EUR]
Player2 calls [€0.05 EUR]
Hero raises [€0.56 EUR]
Player4 folds
Player6 folds
Player1 folds
Player2 calls [€0.56 EUR]
** Dealing Flop ** [ 5s, 9d, Ad ]
Player2 checks
Hero bets [€1.52 EUR]
Player2 folds
Hero does not show cards.
Hero wins €3.04 EUR

View File

@ -1,3 +1,6 @@
Game #9423586142 starts.
#Game No : 9423586142
***** Hand History For Game 9423586142 ***** ***** Hand History For Game 9423586142 *****
0.01/0.02 Texas Hold'em Game Table (NL) - Mon Jul 12 13:38:32 EDT 2010 0.01/0.02 Texas Hold'em Game Table (NL) - Mon Jul 12 13:38:32 EDT 2010
Table 20BB Min Speed #1775757 (Real Money) -- Seat 1 is the button Table 20BB Min Speed #1775757 (Real Money) -- Seat 1 is the button

178
utils/pypokertest.py Normal file
View File

@ -0,0 +1,178 @@
#
# Copyright (C) 2007, 2008 Loic Dachary <loic@dachary.org>
# Copyright (C) 2004, 2005, 2006 Mekensleep
#
# Mekensleep
# 24 rue vieille du temple
# 75004 Paris
# licensing@mekensleep.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Authors:
# Loic Dachary <loic@dachary.org>
#
#
import sys
sys.path.insert(0, ".")
sys.path.insert(0, ".libs")
from pokereval import PokerEval
iterations_low = 100000
iterations_high = 200000
pokereval = PokerEval()
if pokereval.best_hand_value("hi", ["Ah", "Ad", "As", "Kh", "Ks" ]) != 101494784:
sys.exit(1)
if pokereval.string2card("2h") != 0:
sys.exit(1)
print ""
pockets = [ ["As", "Ad", "Ac", "Tc", "Ts", "2d", "5c" ],
["Js", "Jc", "7s", "8c", "8d", "3c", "3h" ],
[255, 255 ] ]
print "stud7 (1) result = %s\n" % pokereval.winners(game = "7stud", pockets = pockets, dead = [], board = [])
pockets = [[22, 18, 21, 3, 41, 1, 30], [39, 255, 255, 15, 13, 17, 255]]
print "stud7 (2) result = %s\n" % pokereval.winners(game = "7stud", pockets = pockets, dead = [], board = [])
print [ j + i + "/%d" % pokereval.string2card(j + i) for i in "hdcs" for j in "23456789TJQKA" ]
print "deck = %s\n" % pokereval.deck()
print "result = %s\n" % pokereval.poker_eval(game = "holdem", pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c"])
print "winners = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c"])
print "result = %s\n" % pokereval.poker_eval(game = "holdem", pockets = [ ["tc", "ac"], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"])
print "winners = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac"], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"])
print "winners (filthy pockets) = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac", 255], [], [255, 255], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"])
print "winners omaha = %s\n" % pokereval.winners(game = "omaha", pockets = [ ["tc", "ac", "ks", "kc" ], ["th", "ah", "qs", "qc" ], ["8c", "6h", "js", "jc" ]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"])
print "winners omaha8 = %s\n" % pokereval.winners(game = "omaha8", pockets = [ ["tc", "ac", "ks", "kc" ], ["th", "ah", "qs", "qc" ], ["8c", "6h", "js", "jc" ]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"])
hand = ["Ac", "As", "Td", "7s", "7h", "3s", "2c"]
best_hand = pokereval.best_hand("hi", hand)
print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) )
print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
hand = ["Ah", "Ts", "Kh", "Qs", "Js" ]
best_hand = pokereval.best_hand("hi", hand)
print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) )
print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
hand = ["2h", "Kh", "Qh", "Jh", "Th" ]
best_hand = pokereval.best_hand("hi", hand)
print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) )
print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
hand = ['2s', '3s', 'Jd', 'Ks', 'As', '4d', '5h', '7d', '9c']
best_hand = pokereval.best_hand("hi", hand)
print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) )
print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
hand = ['As', '2s', '4d', '4s', '5c', '5d', '7s']
best_hand = pokereval.best_hand("low", hand)
print "1/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) )
print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
hand = ['As', '2s', '4d', '4s', '5c', '5d', '8s']
best_hand = pokereval.best_hand("low", hand)
print "2/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) )
print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
hand = ['7d', '6c', '5h', '4d', 'As']
best_hand = pokereval.best_hand("low", hand)
print "3/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) )
print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
board = [ 'As', '4d', '5h', '7d', '9c' ]
hand = [ '2s', 'Ts', 'Jd', 'Ks' ]
best_hand = pokereval.best_hand("low", hand, board)
print "4/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) )
print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
board = [ 'As', '4d', '6h', '7d', '3c' ]
hand = [ '2s', '5s', 'Jd', 'Ks' ]
best_hand = pokereval.best_hand("low", hand, board)
print "low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) )
print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
board = [ 'Jc', '4c', '3c', '5c', '9c' ]
hand = [ '2c', 'Ac', '5h', '9d' ]
best_hand = pokereval.best_hand("hi", hand, board)
print "hi hand from %s / %s = %s" % ( hand, board, pokereval.best("hi", hand, board) )
print "best hi hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], pokereval.card2string(best_hand[1:]))
print ""
board = [ 'Jd', '9c', 'Jc', 'Tc', '2h' ]
hand = [ '2c', '4c', 'Th', '6s' ]
best_hand = pokereval.best_hand("low", hand, board)
print "5/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) )
print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
print ""
board = [ 'Ks', 'Jd', '7s', '4d', 'Js' ]
hand = [ '2d', '6c', 'Ac', '5c' ]
best_hand = pokereval.best_hand("low", hand, board)
print "6/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) )
print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ])
if len(sys.argv) > 2:
print "f0 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "Qs", "2c", "Ac", "Kc"])
print ""
print "f1 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["7s", "Qs", "2c", "Ac", "Kc"])
print ""
print "f2 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_low, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"])
print ""
print "f3 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["As", "Ac"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"])
print ""
print "f4 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["As", "Ks"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"])
print ""
print "f5 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["2s", "2c"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"])
print ""
print "f6 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["Js", "Jc"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"])
print ""
print "f7 result = %s\n" % pokereval.poker_eval(game = "omaha", fill_pockets = 1, iterations = iterations_high, pockets = [ ["Js", "Jc", "7s", "8c"], ["__", "__", "__", "__"], ["__", "__", "__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"])
print ""
hand = ['As', 'Ad']
print "handval %s = %d " % (hand, pokereval.evaln(hand))
print ""
hand = ['Qc', '7d']
print "handval %s = %d " % (hand, pokereval.evaln(hand))
pokereval = None