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

This commit is contained in:
Eric Blade 2010-12-17 06:57:35 -05:00
commit f8bf59b5fc
37 changed files with 2594 additions and 763 deletions

View File

@ -30,14 +30,17 @@ py2exe 0.6.9 ... http://sourceforge.net/projects/py2exe/files/py2exe/0.6.9/py2ex
psycopg2 ... http://www.stickpeople.com/projects/python/win-psycopg/psycopg2-2.2.1.win32-py2.6-pg8.4.3-release.exe psycopg2 ... http://www.stickpeople.com/projects/python/win-psycopg/psycopg2-2.2.1.win32-py2.6-pg8.4.3-release.exe
(Note: stickpeople is the offical repository, not a community build) (Note: stickpeople is the offical repository, not a community build)
(py)pokereval v138 ... http://sourceforge.net/projects/fpdb/files/fpdb/pypoker-eval-win32/pokereval-138.win32.exe/download
(Note: There are no official windows builds, this installer is built from source. A walkthrough is in the same directory as this walkthrough.
1.2/ MySQL 1.2/ MySQL
MySQL-python-1.2.3.win32-py2.6-fpdb0.20.exe ... http://www.mediafire.com/file/iodnnnznmj1/MySQL-python-1.2.3.win32-py2.6-fpdb0.20.exe Install the following file:
This is an intaller built from source by gimick. There are no official mysql-python2.6 builds for windows. MySQL-python-1.2.3.win32-py2.6-fpdb0.20.exe ... http://sourceforge.net/projects/fpdb/files/fpdb/MySQL-python-1.2.3-win32-py2.6/MySQL-python-1.2.3.win32-py2.6-fpdb0.20.exe/download
Community builds are also available from some developers. see www.codegood.com for example. Note: This is an intaller built from source by gimick. A walkthrough to build this installer is in the same directory as this walkthrough.
Note: There is no official mysql-python2.6 build for windows. Community builds are available from some developers. see www.codegood.com for example.
1.3/ pytz fixup to work in an executable package 1.3/ pytz fixup to work in an executable package

View File

@ -0,0 +1,159 @@
pypokereval packaging for fpdb project
--------------------------------------
Created by Gimick on 11th December 2010
Content is available under the the GNU Affero General Public License version 3
Background
----------
The walktrough builds an unoffical python installer package for pypokereval.
In a previous walkthrough, the pypokereval dll(pyd) was built from source.
In this walkthrough, we are going to generate a windows package which will allow
the sources to be installed through distutils onto a client computer
The current situation is that there is no windows build or windows installer provided
by the package authors.
Until a package is available, the fpdb project needs some method of providing a windows
installation for the pypokereval module. This walkthrough will therefore be obsolete once
an official package becomes available.
Actually, for windows fpdb users, the majority will use a pre-built fpdb executable (which contains the
pypokereval package) Therefore, pypokereval installation will only be needed for two groups of people:
i) anyone wanting to build an fpdb package using py2exe
ii) anyone wanting to run fpdb on windows from source
Credits
-------
To loic@dachary.org at pokersource http://pokersource.sourceforge.net/
To donn.ingle@gmail.com for the tutorial here ... http://wiki.python.org/moin/Distutils/Tutorial
Official python reference here ... http://docs.python.org/distutils/index.html
Assumptions
-----------
The underlying dll(pyd) and pokereval library is built for win32 x86 platform only, so we will assume
32bit only in this walkthrough. Contributions for a x86-64 build are most welcome.
Similarly, the underlying package is built against the python 2-6 library and is valid only for that version.
The underlying package was not built with sse enabled, and therefore should work for legacy systems.
1. Install pre-requisites
-------------------------
System used for building is winXP home
1.1/ Install python runtime from here ...
Python 2.6.5 ... http://www.python.org/ftp/python/2.6.5/python-2.6.5.msi
1.2/ Grab pypokereval stuff from fpdb project here ...
pypokereval ... http://sourceforge.net/projects/fpdb/files/fpdb/pypoker-eval-win32/dev/pypokereval-138-win32-py265-fpdb-1.1.exe/download
1.3/ Double click the pypokereval-138-win32-py265-fpdb-1.1.exe and extract the folder to the desktop
2. Prepare a folder containing the items needing packaging
----------------------------------------------------------
dos>cd desktop
dos>mkdir temp
dos>cd temp
dos>mkdir pokereval
dos>cd pokereval
dos>copy ..\..\pypokereval-138-win32-py265-fpdb-1.1\_pokereval_2_6.pyd
dos>copy ..\..\pypokereval-138-win32-py265-fpdb-1.1\pokereval.py
dos>mkdir utils
dos>cd utils
dos>copy ..\..\..\pypokereval-138-win32-py265-fpdb-1.1\test.py
dos>cd ..
The next step is to rename the pokereval.py file to __init__.py. The reason for doing this
is that site-packages require an __init__ file to be found when the module is imported at runtime
Inserting a dummy __init__.py which simply imports pokereval does not work, the reason being that the
PokerEval class is not seen by the caller. Syntax such as "from pokereval import PokerEval"
does not work unless the pokereval.py (which defines the PokerEval class) is renamed to __init__.py.
dos> rename pokereval.py __init__.py
3. Prepare the additional packaging files
-----------------------------------------
dos>cd desktop
dos>cd temp
3.1/ setup.py
-------------
dos> edit setup.py
Include the following python code:
#==================================================
from distutils.core import setup
filelist = ["utils/*", "_pokereval_2_6.pyd"]
setup(name = "pokereval",
version = "138",
description = "pypokereval installer (unofficial)",
author = "project fpdb",
author_email = "Fpdb-main@lists.sourceforge.net",
url = "fpdb.sourceforge.net",
packages = ['pokereval'],
package_data = {'pokereval' : filelist },
long_description = """An unofficial and experimental installer for pypokereval v138
Built for 32bit windows and python v2.6.5
pokereval official project page is at http://www.pokersource.info/"""
)
#==================================================
3.2 / review directory tree
---------------------------
The following structure should now exist.
temp
|--setup.py
|--pokereval
|--_pokereval_2_6.pyd
|--__init__.py
|--utils
|--test.py
3.3 Build
---------
Navigate to the desktop/temp directory
dos>c:\Python26\python.exe setup.py bdist_wininst --plat-name=win32 --user-access-control force
Note: UAC auto seems to cause lockup on my win7 system
3.4 Complete
------------
The executable file pokereval-138.win32.exe will be in the newly-created dist folder.
3.5 Install and test
--------------------
Double click to install
Navigate to c:\python26\lib\site-packages\pokereval\test
execute dos>c:\Python26\python.exe test.py
Output should scroll down the screen

View File

@ -211,7 +211,7 @@ class HandInternal(DerivedStats):
def isDuplicate(self, session): def isDuplicate(self, session):
"""Checks if current hand already exists in db """Checks if current hand already exists in db
siteHandNo ans gameTypeId have to be setted siteHandNo ans gametypeId have to be setted
""" """
return session.query(HandInternal).filter_by( return session.query(HandInternal).filter_by(
siteHandNo=self.siteHandNo, gametypeId=self.gametypeId).count()!=0 siteHandNo=self.siteHandNo, gametypeId=self.gametypeId).count()!=0

View File

@ -303,6 +303,7 @@ def encodeRazzStartHand(cards):
encodeRazzList = { encodeRazzList = {
'(00)A':-13,'(00)2':-12,'(00)3':-11,'(00)4':-10,'(00)5':-9,'(00)6':-8,'(00)7':-7,'(00)8':-6,'(00)9':-5,'(00)T':-4, '(00)A':-13,'(00)2':-12,'(00)3':-11,'(00)4':-10,'(00)5':-9,'(00)6':-8,'(00)7':-7,'(00)8':-6,'(00)9':-5,'(00)T':-4,
'(00)J':-3,'(00)Q':-2,'(00)K':-1, '(00)J':-3,'(00)Q':-2,'(00)K':-1,
'(00)0':0,
'(32)A':1,'(3A)2':2,'(2A)3':3,'(42)A':4,'(4A)2':5,'(2A)4':6,'(43)A':7,'(4A)3':8,'(3A)4':9, '(32)A':1,'(3A)2':2,'(2A)3':3,'(42)A':4,'(4A)2':5,'(2A)4':6,'(43)A':7,'(4A)3':8,'(3A)4':9,
'(43)2':10,'(42)3':11,'(32)4':12,'(52)A':13,'(5A)2':14,'(2A)5':15,'(53)A':16,'(5A)3':17,'(3A)5':18,'(53)2':19, '(43)2':10,'(42)3':11,'(32)4':12,'(52)A':13,'(5A)2':14,'(2A)5':15,'(53)A':16,'(5A)3':17,'(3A)5':18,'(53)2':19,
'(52)3':20,'(32)5':21,'(54)A':22,'(5A)4':23,'(4A)5':24,'(54)2':25,'(52)4':26,'(42)5':27,'(54)3':28,'(53)4':29, '(52)3':20,'(32)5':21,'(54)A':22,'(5A)4':23,'(4A)5':24,'(54)2':25,'(52)4':26,'(42)5':27,'(54)3':28,'(53)4':29,

View File

@ -1692,7 +1692,13 @@ class Database:
# NEWIMPORT CODE # NEWIMPORT CODE
########################### ###########################
def storeHand(self, p): def storeHand(self, p, printdata = False):
if printdata:
print "######## Hands ##########"
import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(p)
print "###### End Hands ########"
#stores into table hands: #stores into table hands:
q = self.sql.query['store_hand'] q = self.sql.query['store_hand']
@ -1702,7 +1708,7 @@ class Database:
c.execute(q, ( c.execute(q, (
p['tableName'], p['tableName'],
p['gameTypeId'], p['gametypeId'],
p['siteHandNo'], p['siteHandNo'],
p['tourneyId'], p['tourneyId'],
p['startTime'], p['startTime'],
@ -1860,10 +1866,12 @@ class Database:
def storeHandsActions(self, hid, pids, hpid, adata, printdata = False): def storeHandsActions(self, hid, pids, hpid, adata, printdata = False):
#print "DEBUG: %s %s %s" %(hid, pids, adata) #print "DEBUG: %s %s %s" %(hid, pids, adata)
if printdata:
import pprint # This can be used to generate test data. Currently unused
pp = pprint.PrettyPrinter(indent=4) #if printdata:
pp.pprint(adata) # import pprint
# pp = pprint.PrettyPrinter(indent=4)
# pp.pprint(adata)
inserts = [] inserts = []
for a in adata: for a in adata:
@ -2026,19 +2034,25 @@ class Database:
pass pass
def storeSessionsCache(self, pids, startTime, game, pdata): def storeSessionsCache(self, pids, startTime, game, pdata):
"""Update cached sessions. If update fails because no record exists, do an insert.""" """Update cached sessions. If update fails because no record exists, do an insert"""
THRESHOLD = timedelta(seconds=int(self.sessionTimeout * 60)) #convert minutes to seconds THRESHOLD = timedelta(seconds=int(self.sessionTimeout * 60))
bigBet = int(Decimal(game['bb'])*200) bigBet = int(Decimal(game['bb'])*200)
check_sessionscache = self.sql.query['check_sessionscache'] select_sessionscache = self.sql.query['select_sessionscache']
check_sessionscache = check_sessionscache.replace('%s', self.sql.query['placeholder']) select_sessionscache = select_sessionscache.replace('%s', self.sql.query['placeholder'])
update_sessionscache = self.sql.query['update_sessionscache'] select_sessionscache_mid = self.sql.query['select_sessionscache_mid']
update_sessionscache = update_sessionscache.replace('%s', self.sql.query['placeholder']) select_sessionscache_mid = select_sessionscache_mid.replace('%s', self.sql.query['placeholder'])
select_sessionscache_start = self.sql.query['select_sessionscache_start']
select_sessionscache_start = select_sessionscache_start.replace('%s', self.sql.query['placeholder'])
update_sessionscache_mid = self.sql.query['update_sessionscache_mid']
update_sessionscache_mid = update_sessionscache_mid.replace('%s', self.sql.query['placeholder'])
update_sessionscache_start = self.sql.query['update_sessionscache_start'] update_sessionscache_start = self.sql.query['update_sessionscache_start']
update_sessionscache_start = update_sessionscache_start.replace('%s', self.sql.query['placeholder']) update_sessionscache_start = update_sessionscache_start.replace('%s', self.sql.query['placeholder'])
update_sessionscache_end = self.sql.query['update_sessionscache_end'] update_sessionscache_end = self.sql.query['update_sessionscache_end']
update_sessionscache_end = update_sessionscache_end.replace('%s', self.sql.query['placeholder']) update_sessionscache_end = update_sessionscache_end.replace('%s', self.sql.query['placeholder'])
insert_sessionscache = self.sql.query['insert_sessionscache'] insert_sessionscache = self.sql.query['insert_sessionscache']
insert_sessionscache = insert_sessionscache.replace('%s', self.sql.query['placeholder']) insert_sessionscache = insert_sessionscache.replace('%s', self.sql.query['placeholder'])
merge_sessionscache = self.sql.query['merge_sessionscache'] merge_sessionscache = self.sql.query['merge_sessionscache']
@ -2083,77 +2097,62 @@ class Database:
cursor = self.get_cursor() cursor = self.get_cursor()
for row in inserts: for row in inserts:
check = [] threshold = []
check.append(row[-1]-THRESHOLD) threshold.append(row[-1]-THRESHOLD)
check.append(row[-1]+THRESHOLD) threshold.append(row[-1]+THRESHOLD)
num = cursor.execute(check_sessionscache, check) cursor.execute(select_sessionscache, threshold)
#DEBUG log.info(_("check yurself: '%s'") % (num.rowcount)) num = cursor.rowcount
if (num == 1):
# Try to do the update first: # Try to do the update first:
if ((self.backend == self.PGSQL and cursor.statusmessage == "UPDATE 1") #print "DEBUG: found 1 record to update"
or (self.backend == self.MYSQL_INNODB and num == 1) update_mid = row + row[-1:]
or (self.backend == self.SQLITE and num.rowcount == 1)): cursor.execute(select_sessionscache_mid, update_mid[-2:])
update = row + row[-1:] mid = cursor.rowcount
mid = cursor.execute(update_sessionscache, update) if (mid == 0):
#DEBUG log.info(_("update '%s' rows, no change to session times ") % str(mid.rowcount)) update_startend = row[-1:] + row + threshold
if ((self.backend == self.PGSQL and cursor.statusmessage != "UPDATE 1") cursor.execute(select_sessionscache_start, update_startend[-3:])
or (self.backend == self.MYSQL_INNODB and mid == 0) start = cursor.rowcount
or (self.backend == self.SQLITE and mid.rowcount == 0)): if (start == 0):
update_start = row[-1:] + row + check #print "DEBUG:", start, " start record found. Update stats and start time"
start = cursor.execute(update_sessionscache_start, update_start) cursor.execute(update_sessionscache_end, update_startend)
#DEBUG log.info(_("update '%s' rows, and updated sessionStart") % str(start.rowcount))
if ((self.backend == self.PGSQL and cursor.statusmessage != "UPDATE 1")
or (self.backend == self.MYSQL_INNODB and start == 0)
or (self.backend == self.SQLITE and start.rowcount == 0)):
update_end = row[-1:] + row + check
end = cursor.execute(update_sessionscache_end, update_end)
#DEBUG log.info(_("update '%s' rows, and updated sessionEnd") % str(end.rowcount))
else: else:
pass #print "DEBUG: 1 end record found. Update stats and end time time"
cursor.execute(update_sessionscache_start, update_startend)
else: else:
pass #print "DEBUG: update stats mid-session"
elif ((self.backend == self.PGSQL and cursor.statusmessage != "UPDATE 1" and "UPDATE" in cursor.statusmessage) cursor.execute(update_sessionscache_mid, update_mid)
or (self.backend == self.MYSQL_INNODB and num > 1) elif (num > 1):
or (self.backend == self.SQLITE and num.rowcount > 1)): # Multiple matches found - merge them into one session and update:
#DEBUG log.info(_("multiple matches")) #print "DEBUG:", num, "matches found"
pass cursor.execute(merge_sessionscache, threshold)
#merge two sessions if there are multiple matches
cursor.execute(merge_sessionscache, check)
merge = cursor.fetchone() merge = cursor.fetchone()
cursor.execute(delete_sessions, check) cursor.execute(delete_sessions, threshold)
cursor.execute(insert_sessionscache, merge) cursor.execute(insert_sessionscache, merge)
update = row + row[-1:] update_mid = row + row[-1:]
mid = cursor.execute(update_sessionscache, update) cursor.execute(select_sessionscache_mid, update_mid[-2:])
#DEBUG log.info(_("update '%s' rows, no change to session times ") % str(mid.rowcount)) mid = cursor.rowcount
if ((self.backend == self.PGSQL and cursor.statusmessage != "UPDATE 1") if (mid == 0):
or (self.backend == self.MYSQL_INNODB and mid == 0) update_startend = row[-1:] + row + threshold
or (self.backend == self.SQLITE and mid.rowcount == 0)): cursor.execute(select_sessionscache_start, update_startend[-3:])
update_start = row[-1:] + row + check start = cursor.rowcount
start = cursor.execute(update_sessionscache_start, update_start) if (start == 0):
#DEBUG log.info(_("update '%s' rows, and updated sessionStart") % str(start.rowcount)) #print "DEBUG:", start, " start record found. Update stats and start time"
if ((self.backend == self.PGSQL and cursor.statusmessage != "UPDATE 1") cursor.execute(update_sessionscache_end, update_startend)
or (self.backend == self.MYSQL_INNODB and start == 0)
or (self.backend == self.SQLITE and start.rowcount == 0)):
update_end = row[-1:] + row + check
end = cursor.execute(update_sessionscache_end, update_end)
#DEBUG log.info(_("update '%s' rows, and updated sessionEnd") % str(end.rowcount))
else: else:
pass #print "DEBUG: 1 end record found. Update stats and end time time"
cursor.execute(update_sessionscache_start, update_startend)
else: else:
pass #print "DEBUG: update stats mid-session"
cursor.execute(update_sessionscache_mid, update_mid)
elif ((self.backend == self.PGSQL and cursor.statusmessage != "UPDATE 1") elif (num == 0):
or (self.backend == self.MYSQL_INNODB and num == 0) # No matches found, insert new session:
or (self.backend == self.SQLITE and num.rowcount == 0)):
#move the last 2 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
insert = row + row[-1:] insert = row + row[-1:]
insert = insert[-2:] + insert[:-2] insert = insert[-2:] + insert[:-2]
#DEBUG log.info(_("insert row: '%s'") % (insert)) #print "DEBUG: No matches found. Insert record", insert
cursor.execute(insert_sessionscache, insert) cursor.execute(insert_sessionscache, insert)
else: else:
pass # Something bad happened
pass
def isDuplicate(self, gametypeID, siteHandNo): def isDuplicate(self, gametypeID, siteHandNo):
dup = False dup = False

View File

@ -135,7 +135,7 @@ class DerivedStats():
#print "DEBUG: vpip: %s" %(self.hands['playersVpi']) #print "DEBUG: vpip: %s" %(self.hands['playersVpi'])
self.playersAtStreetX(hand) # Gives playersAtStreet1..4 and Showdown self.playersAtStreetX(hand) # Gives playersAtStreet1..4 and Showdown
#print "DEBUG: playersAtStreet 1:'%s' 2:'%s' 3:'%s' 4:'%s'" %(self.hands['playersAtStreet1'],self.hands['playersAtStreet2'],self.hands['playersAtStreet3'],self.hands['playersAtStreet4']) #print "DEBUG: playersAtStreet 1:'%s' 2:'%s' 3:'%s' 4:'%s'" %(self.hands['playersAtStreet1'],self.hands['playersAtStreet2'],self.hands['playersAtStreet3'],self.hands['playersAtStreet4'])
self.streetXRaises(hand) # Empty function currently self.streetXRaises(hand)
def assembleHandsPlayers(self, hand): def assembleHandsPlayers(self, hand):
#street0VPI/vpip already called in Hand #street0VPI/vpip already called in Hand

View File

@ -106,7 +106,10 @@ or None if we fail to get the info """
m = self.re_GameInfo.search(handText) m = self.re_GameInfo.search(handText)
if not m: if not m:
return None tmp = handText[0:100]
log.error(_("determineGameType: Unable to recognise gametype from: '%s'") % tmp)
log.error(_("determineGameType: Raising FpdbParseError"))
raise FpdbParseError(_("Unable to recognise gametype from: '%s'") % tmp)
mg = m.groupdict() mg = m.groupdict()

View File

@ -63,10 +63,10 @@ class Fulltilt(HandHistoryConverter):
[%(LS)s]?(?P<SB>[.0-9]+)/[%(LS)s]?(?P<BB>[.0-9]+)\s(Ante\s[%(LS)s]?(?P<ANTE>[.0-9]+)\s)?-\s [%(LS)s]?(?P<SB>[.0-9]+)/[%(LS)s]?(?P<BB>[.0-9]+)\s(Ante\s[%(LS)s]?(?P<ANTE>[.0-9]+)\s)?-\s
[%(LS)s]?(?P<CAP>[.0-9]+\sCap\s)? [%(LS)s]?(?P<CAP>[.0-9]+\sCap\s)?
(?P<GAMETYPE>[-\da-zA-Z\/\'\s]+)\s-\s (?P<GAMETYPE>[-\da-zA-Z\/\'\s]+)\s-\s
(?P<DATETIME>\d+:\d+:\d+\s(?P<TZ1>\w+)\s-\s\d+/\d+/\d+|\d+:\d+\s(?P<TZ2>\w+)\s-\s\w+\,\s\w+\s\d+\,\s\d+) (?P<DATETIME>.*$)
(?P<PARTIAL>\(partial\))?\n (?P<PARTIAL>\(partial\))?\n
(?:.*?\n(?P<CANCELLED>Hand\s\#(?P=HID)\shas\sbeen\scanceled))? (?:.*?\n(?P<CANCELLED>Hand\s\#(?P=HID)\shas\sbeen\scanceled))?
''' % substitutions, re.VERBOSE|re.DOTALL) ''' % substitutions, re.MULTILINE|re.VERBOSE)
re_TourneyExtraInfo = re.compile('''(((?P<TOURNEY_NAME>[^$]+)? re_TourneyExtraInfo = re.compile('''(((?P<TOURNEY_NAME>[^$]+)?
(?P<CURRENCY>[%(LS)s])?(?P<BUYIN>[.0-9]+)?\s*\+\s*[%(LS)s]?(?P<FEE>[.0-9]+)? (?P<CURRENCY>[%(LS)s])?(?P<BUYIN>[.0-9]+)?\s*\+\s*[%(LS)s]?(?P<FEE>[.0-9]+)?
(\s(?P<SPECIAL>(KO|Heads\sUp|Matrix\s\dx|Rebuy|Madness)))? (\s(?P<SPECIAL>(KO|Heads\sUp|Matrix\s\dx|Rebuy|Madness)))?
@ -123,6 +123,7 @@ class Fulltilt(HandHistoryConverter):
re_Mixed = re.compile(r'\s\-\s(?P<MIXED>HA|HORSE|HOSE)\s\-\s', re.VERBOSE) re_Mixed = re.compile(r'\s\-\s(?P<MIXED>HA|HORSE|HOSE)\s\-\s', re.VERBOSE)
re_Max = re.compile("(?P<MAX>\d+)( max)?", re.MULTILINE) re_Max = re.compile("(?P<MAX>\d+)( max)?", re.MULTILINE)
# NB: if we ever match "Full Tilt Poker" we should also match "FullTiltPoker", which PT Stud erroneously exports. # NB: if we ever match "Full Tilt Poker" we should also match "FullTiltPoker", which PT Stud erroneously exports.
re_DateTime = re.compile("""((?P<H>[0-9]+):(?P<MIN>[0-9]+):(?P<S>[0-9]+)\s(?P<TZ>\w+)\s-\s(?P<Y>[0-9]{4})\/(?P<M>[0-9]{2})\/(?P<D>[0-9]{2})|(?P<H2>[0-9]+):(?P<MIN2>[0-9]+)\s(?P<TZ2>\w+)\s-\s\w+\,\s(?P<M2>\w+)\s(?P<D2>\d+)\,\s(?P<Y2>[0-9]{4}))""", re.MULTILINE)
@ -225,18 +226,24 @@ class Fulltilt(HandHistoryConverter):
hand.handid = m.group('HID') hand.handid = m.group('HID')
hand.tablename = m.group('TABLE') hand.tablename = m.group('TABLE')
timezone = "ET" if m.group('DATETIME'):
if m.group('TZ1') == "CET" or m.group('TZ2') == "CET": # This section of code should match either a single date (which is ET) or
timezone = "CET" # the last date in the header, which is also recorded in ET.
try: timezone = "ET"
stringformat = "%H:%M:%S " + m.group('TZ1') + " - %Y/%m/%d" m1 = self.re_DateTime.finditer(m.group('DATETIME'))
hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), stringformat) datetimestr = "2000/01/01 00:00:00"
except: for a in m1:
stringformat = "%H:%M " + m.group('TZ2') + " - %a, %B %d, %Y" if a.group('TZ2') == None:
hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), stringformat) datetimestr = "%s/%s/%s %s:%s:%s" % (a.group('Y'), a.group('M'),a.group('D'),a.group('H'),a.group('MIN'),a.group('S'))
timezone = a.group('TZ')
hand.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S")
else: # Short-lived date format
datetimestr = "%s/%s/%s %s:%s" % (a.group('Y2'), a.group('M2'),a.group('D2'),a.group('H2'),a.group('MIN2'))
timezone = a.group('TZ2')
hand.startTime = datetime.datetime.strptime(datetimestr, "%Y/%B/%d %H:%M")
hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, timezone, "UTC")
hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, timezone, "UTC")
if m.group("CANCELLED") or m.group("PARTIAL"): if m.group("CANCELLED") or m.group("PARTIAL"):
raise FpdbParseError(hid=m.group('HID')) raise FpdbParseError(hid=m.group('HID'))

View File

@ -224,9 +224,6 @@ class GuiGraphViewer (threading.Thread):
self.graphBox.add(self.canvas) self.graphBox.add(self.canvas)
self.canvas.show() self.canvas.show()
self.canvas.draw() self.canvas.draw()
#TODO: Do something useful like alert user
#print "No hands returned by graph query"
else: else:
self.ax.set_title(_("Profit graph for ring games"+names),fontsize=12) self.ax.set_title(_("Profit graph for ring games"+names),fontsize=12)
@ -340,7 +337,10 @@ class GuiGraphViewer (threading.Thread):
if len(winnings) == 0: if len(winnings) == 0:
return (None, None, None) return (None, None, None)
green = map(lambda x:float(x[1]), winnings) #Insert a 0th entry into winnings so graph starts 'zerod'
winnings.insert(0, (0,0,0))
green = map(lambda x: float(x[1]), winnings)
blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings)
red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings)
greenline = cumsum(green) greenline = cumsum(green)

View File

@ -397,7 +397,7 @@ class GuiPositionalStats (threading.Thread):
query = query.replace("<selectgt.bigBlind>", bigblindselect) query = query.replace("<selectgt.bigBlind>", bigblindselect)
query = query.replace("<groupbygt.bigBlind>", "") query = query.replace("<groupbygt.bigBlind>", "")
query = query.replace("<hcgametypeId>", "-1") query = query.replace("<hcgametypeId>", "-1")
query = query.replace("<hgameTypeId>", "-1") query = query.replace("<hgametypeId>", "-1")
else: else:
if self.db.backend == self.MYSQL_INNODB: if self.db.backend == self.MYSQL_INNODB:
bigblindselect = """concat('$', trim(leading ' ' from bigblindselect = """concat('$', trim(leading ' ' from
@ -416,7 +416,7 @@ class GuiPositionalStats (threading.Thread):
query = query.replace("<selectgt.bigBlind>", bigblindselect) query = query.replace("<selectgt.bigBlind>", bigblindselect)
query = query.replace("<groupbygt.bigBlind>", ",gt.bigBlind") query = query.replace("<groupbygt.bigBlind>", ",gt.bigBlind")
query = query.replace("<hcgametypeId>", "hc.gametypeId") query = query.replace("<hcgametypeId>", "hc.gametypeId")
query = query.replace("<hgameTypeId>", "h.gameTypeId") query = query.replace("<hgametypeId>", "h.gametypeId")
# Filter on dates # Filter on dates
query = query.replace("<datestest>", " between '" + dates[0] + "' and '" + dates[1] + "'") query = query.replace("<datestest>", " between '" + dates[0] + "' and '" + dates[1] + "'")

View File

@ -33,28 +33,38 @@ import gobject
class GuiReplayer: class GuiReplayer:
def __init__(self, config, querylist, mainwin, debug=True): def __init__(self, config, querylist, mainwin, options = None, debug=True):
self.debug = debug self.debug = debug
self.conf = config self.conf = config
self.main_window = mainwin self.main_window = mainwin
self.sql = querylist self.sql = querylist
# These are temporary variables until it becomes possible
# to select() a Hand object from the database
self.filename="regression-test-files/cash/Stars/Flop/NLHE-FR-USD-0.01-0.02-201005.microgrind.txt"
self.site="PokerStars"
if options.filename != None:
self.filename = options.filename
if options.sitename != None:
self.site = options.sitename
self.db = Database.Database(self.conf, sql=self.sql) self.db = Database.Database(self.conf, sql=self.sql)
filters_display = { "Heroes" : True, filters_display = { "Heroes" : True,
"Sites" : True, "Sites" : False,
"Games" : True, "Games" : False,
"Limits" : True, "Limits" : False,
"LimitSep" : True, "LimitSep" : False,
"LimitType" : True, "LimitType" : False,
"Type" : True, "Type" : False,
"Seats" : True, "Seats" : False,
"SeatSep" : True, "SeatSep" : False,
"Dates" : True, "Dates" : True,
"Groups" : True, "Groups" : False,
"GroupsAll" : True, "GroupsAll" : False,
"Button1" : True, "Button1" : True,
"Button2" : True "Button2" : False
} }
@ -239,36 +249,90 @@ class GuiReplayer:
be replaced by a function to select a hand from the db in the not so distant future. be replaced by a function to select a hand from the db in the not so distant future.
This code has been shamelessly stolen from Carl This code has been shamelessly stolen from Carl
""" """
config = Configuration.Config(file = "HUD_config.test.xml") if True:
db = Database.Database(config) settings = {}
sql = SQL.Sql(db_server = 'sqlite') settings.update(self.conf.get_db_parameters())
settings = {} settings.update(self.conf.get_import_parameters())
settings.update(config.get_db_parameters()) settings.update(self.conf.get_default_paths())
settings.update(config.get_import_parameters())
settings.update(config.get_default_paths())
#db.recreate_tables()
importer = fpdb_import.Importer(False, settings, config, None)
importer.setDropIndexes("don't drop")
importer.setFailOnError(True)
importer.setThreads(-1)
importer.setCallHud(False)
importer.setFakeCacheHHC(True)
#Get a simple regression file with a few hands of Hold'em importer = fpdb_import.Importer(False, settings, self.conf, None)
filename="regression-test-files/cash/Stars/Flop/NLHE-FR-USD-0.01-0.02-201005.microgrind.txt" importer.setDropIndexes("don't drop")
site="PokerStars" importer.setFailOnError(True)
importer.setThreads(-1)
importer.setCallHud(False)
importer.setFakeCacheHHC(True)
print "DEBUG: self.filename: '%s' self.site: '%s'" %(self.filename, self.site)
importer.addBulkImportImportFileOrDir(self.filename, site=self.site)
(stored, dups, partial, errs, ttime) = importer.runImport()
importer.addBulkImportImportFileOrDir(filename, site=site) hhc = importer.getCachedHHC()
(stored, dups, partial, errs, ttime) = importer.runImport() handlist = hhc.getProcessedHands()
return handlist[0]
else:
# Fetch hand info
# We need at least sitename, gametype, handid
# for the Hand.__init__
hhc = importer.getCachedHHC() ####### Shift this section in Database.py for all to use ######
handlist = hhc.getProcessedHands() handid = 40
q = self.sql.query['get_gameinfo_from_hid']
return handlist[0] q = q.replace('%s', self.sql.query['placeholder'])
c = self.db.get_cursor()
c.execute(q, (handid,))
res = c.fetchone()
gametype = {'category':res[1],'base':res[2],'type':res[3],'limitType':res[4],'hilo':res[5],'sb':res[6],'bb':res[7], 'currency':res[10]}
#FIXME: smallbet and bigbet are res[8] and res[9] respectively
###### End section ########
print "DEBUG: gametype: %s" % gametype
if gametype['base'] == 'hold':
h = HoldemOmahaHand(config = self.conf, hhc = None, sitename=res[0], gametype = gametype, handText=None, builtFrom = "DB", handid=handid)
h.select(self.db, handid)
elif gametype['base'] == 'stud':
print "DEBUG: Create stud hand here"
elif gametype['base'] == 'draw':
print "DEBUG: Create draw hand here"
def temp(self): def temp(self):
pass pass
def main(argv=None):
"""main can also be called in the python interpreter, by supplying the command line as the argument."""
if argv is None:
argv = sys.argv[1:]
def destroy(*args): # call back for terminating the main eventloop
gtk.main_quit()
import Options
(options, argv) = Options.fpdb_options()
if options.usage == True:
#Print usage examples and exit
sys.exit(0)
if options.sitename:
options.sitename = Options.site_alias(options.sitename)
if options.sitename == False:
usage()
config = Configuration.Config(file = "HUD_config.test.xml")
db = Database.Database(config)
sql = SQL.Sql(db_server = 'sqlite')
main_window = gtk.Window()
main_window.connect('destroy', destroy)
replayer = GuiReplayer(config, sql, main_window, options=options, debug=True)
main_window.add(replayer.get_vbox())
main_window.set_default_size(800,800)
main_window.show()
gtk.main()
if __name__ == '__main__':
sys.exit(main())

View File

@ -652,18 +652,18 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
query = query.replace("<gtbigBlind_test>", bbtest) query = query.replace("<gtbigBlind_test>", bbtest)
if holecards: # re-use level variables for hole card query if holecards: # re-use level variables for hole card query
query = query.replace("<hgameTypeId>", "hp.startcards") query = query.replace("<hgametypeId>", "hp.startcards")
query = query.replace("<orderbyhgameTypeId>" query = query.replace("<orderbyhgametypeId>"
, ",case when floor((hp.startcards-1)/13) >= mod((hp.startcards-1),13) then hp.startcards + 0.1 " , ",case when floor((hp.startcards-1)/13) >= mod((hp.startcards-1),13) then hp.startcards + 0.1 "
+ " else 13*mod((hp.startcards-1),13) + floor((hp.startcards-1)/13) + 1 " + " else 13*mod((hp.startcards-1),13) + floor((hp.startcards-1)/13) + 1 "
+ " end desc ") + " end desc ")
else: else:
query = query.replace("<orderbyhgameTypeId>", "") query = query.replace("<orderbyhgametypeId>", "")
groupLevels = "show" not in str(limits) groupLevels = "show" not in str(limits)
if groupLevels: if groupLevels:
query = query.replace("<hgameTypeId>", "p.name") # need to use p.name for sqlite posn stats to work query = query.replace("<hgametypeId>", "p.name") # need to use p.name for sqlite posn stats to work
else: else:
query = query.replace("<hgameTypeId>", "h.gameTypeId") query = query.replace("<hgametypeId>", "h.gametypeId")
# process self.detailFilters (a list of tuples) # process self.detailFilters (a list of tuples)
flagtest = '' flagtest = ''

View File

@ -37,8 +37,6 @@ try:
from matplotlib.finance import candlestick2 from matplotlib.finance import candlestick2
from numpy import diff, nonzero, sum, cumsum, max, min, append from numpy import diff, nonzero, sum, cumsum, max, min, append
# from matplotlib.dates import DateFormatter, WeekdayLocator, HourLocator, \
# DayLocator, MONDAY, timezone
except ImportError, inst: except ImportError, inst:
print _("""Failed to load numpy and/or matplotlib in Session Viewer""") print _("""Failed to load numpy and/or matplotlib in Session Viewer""")
@ -265,8 +263,9 @@ Thankyou
#end def fillStatsFrame(self, vbox): #end def fillStatsFrame(self, vbox):
def generateDatasets(self, playerids, sitenos, limits, seats): def generateDatasets(self, playerids, sitenos, limits, seats):
THRESHOLD = 1800 # Minimum number of seconds between consecutive hands before being considered a new session print "DEBUG: Starting generateDatasets"
PADDING = 5 # Additional time in minutes to add to a session, session startup, shutdown etc (FiXME: user configurable) THRESHOLD = 1800 # Min # of secs between consecutive hands before being considered a new session
PADDING = 5 # Additional time in minutes to add to a session, session startup, shutdown etc
# Get a list of all handids and their timestampts # Get a list of all handids and their timestampts
#FIXME: Query still need to filter on blind levels #FIXME: Query still need to filter on blind levels
@ -284,10 +283,15 @@ Thankyou
self.db.cursor.execute(q) self.db.cursor.execute(q)
hands = self.db.cursor.fetchall() hands = self.db.cursor.fetchall()
hands.insert(0, (hands[0][0], 0, 0, 0, 0))
# Take that list and create an array of the time between hands # Take that list and create an array of the time between hands
times = map(lambda x:long(x[0]), hands) times = map(lambda x:long(x[0]), hands)
handids = map(lambda x:int(x[1]), hands) handids = map(lambda x:int(x[1]), hands)
winnings = map(lambda x:float(x[4]), hands) winnings = map(lambda x:float(x[4]), hands)
#print "DEBUG: times : %s" % times
#print "DEBUG: handids : %s" % handids
#print "DEBUG: winnings: %s" % winnings
#print "DEBUG: len(times) %s" %(len(times)) #print "DEBUG: len(times) %s" %(len(times))
diffs = diff(times) # This array is the difference in starttime between consecutive hands diffs = diff(times) # This array is the difference in starttime between consecutive hands
diffs2 = append(diffs,THRESHOLD + 1) # Append an additional session to the end of the diffs, so the next line diffs2 = append(diffs,THRESHOLD + 1) # Append an additional session to the end of the diffs, so the next line
@ -318,8 +322,9 @@ Thankyou
cum_sum = cum_sum/100 cum_sum = cum_sum/100
sid = 1 sid = 1
# Take all results and format them into a list for feeding into gui model. # Take all results and format them into a list for feeding into gui model.
#print "DEBUG: range(len(index[0]): %s" % range(len(index[0]))
for i in range(len(index[0])): for i in range(len(index[0])):
hds = index[0][i] - first_idx + 1 # Number of hands in session hds = index[0][i] - first_idx # Number of hands in session
if hds > 0: if hds > 0:
stime = strftime("%d/%m/%Y %H:%M", localtime(times[first_idx])) # Formatted start time stime = strftime("%d/%m/%Y %H:%M", localtime(times[first_idx])) # Formatted start time
etime = strftime("%d/%m/%Y %H:%M", localtime(times[index[0][i]])) # Formatted end time etime = strftime("%d/%m/%Y %H:%M", localtime(times[index[0][i]])) # Formatted end time
@ -328,12 +333,14 @@ Thankyou
minutesplayed = 1 minutesplayed = 1
minutesplayed = minutesplayed + PADDING minutesplayed = minutesplayed + PADDING
hph = hds*60/minutesplayed # Hands per hour hph = hds*60/minutesplayed # Hands per hour
won = sum(winnings[first_idx:index[0][i]])/100.0 end_idx = first_idx+hds+1
hwm = max(cum_sum[first_idx:index[0][i]]) won = sum(winnings[first_idx:end_idx])/100.0
lwm = min(cum_sum[first_idx:index[0][i]]) #print "DEBUG: winnings[%s:%s]: %s" % (first_idx, end_idx, winnings[first_idx:end_idx])
hwm = max(cum_sum[first_idx:end_idx])
lwm = min(cum_sum[first_idx:end_idx])
open = (sum(winnings[:first_idx]))/100 open = (sum(winnings[:first_idx]))/100
close = (sum(winnings[:index[0][i]]))/100 close = (sum(winnings[:end_idx]))/100
#print "DEBUG: range: (%s, %s) - (min, max): (%s, %s) - (open,close): (%s, %s)" %(first_idx, index[0][i], lwm, hwm, open, close) #print "DEBUG: range: (%s, %s) - (min, max): (%s, %s) - (open,close): (%s, %s)" %(first_idx, end_idx, lwm, hwm, open, close)
results.append([sid, hds, stime, etime, hph, won]) results.append([sid, hds, stime, etime, hph, won])
opens.append(open) opens.append(open)
@ -374,17 +381,17 @@ Thankyou
def generateGraph(self, opens, closes, highs, lows): def generateGraph(self, opens, closes, highs, lows):
self.clearGraphData() self.clearGraphData()
# print "DEBUG:" #print "DEBUG:"
# print "highs = %s" % highs #print "\thighs = %s" % highs
# print "lows = %s" % lows #print "\tlows = %s" % lows
# print "opens = %s" % opens #print "\topens = %s" % opens
# print "closes = %s" % closes #print "\tcloses = %s" % closes
# print "len(highs): %s == len(lows): %s" %(len(highs), len(lows)) #print "\tlen(highs): %s == len(lows): %s" %(len(highs), len(lows))
# print "len(opens): %s == len(closes): %s" %(len(opens), len(closes)) #print "\tlen(opens): %s == len(closes): %s" %(len(opens), len(closes))
#
# for i in range(len(highs)): #for i in range(len(highs)):
# print "DEBUG: (%s, %s, %s, %s)" %(lows[i], opens[i], closes[i], highs[i]) # print "DEBUG: (%s, %s, %s, %s)" %(lows[i], opens[i], closes[i], highs[i])
# print "DEBUG: diffs h/l: %s o/c: %s" %(lows[i] - highs[i], opens[i] - closes[i]) # print "DEBUG: diffs h/l: %s o/c: %s" %(lows[i] - highs[i], opens[i] - closes[i])
self.ax = self.fig.add_subplot(111) self.ax = self.fig.add_subplot(111)

View File

@ -54,7 +54,7 @@ class GuiStove():
self.mainHBox.show_all() self.mainHBox.show_all()
if DEBUG == False: if DEBUG == False:
warning_string = """ warning_string = _("""
Stove is a GUI mockup of a EV calculation page, and completely non functional. Stove is a GUI mockup of a EV calculation page, and completely non functional.
Unless you are interested in developing this feature, please ignore this page. Unless you are interested in developing this feature, please ignore this page.
@ -62,7 +62,7 @@ Unless you are interested in developing this feature, please ignore this page.
If you are interested in developing the code further see GuiStove.py and Stove.py If you are interested in developing the code further see GuiStove.py and Stove.py
Thankyou Thankyou
""" """)
self.warning_box(warning_string) self.warning_box(warning_string)
@ -161,14 +161,14 @@ Against the range: {
69.91% 15.83% 14.26% 69.91% 15.83% 14.26%
""" """
label = gtk.Label(outstring) self.outputlabel = gtk.Label(outstring)
out_frame.add(label) out_frame.add(self.outputlabel)
# Input Frame # Input Frame
table = gtk.Table(4, 4, True) table = gtk.Table(4, 4, True)
label = gtk.Label("Board:") label = gtk.Label("Board:")
board = gtk.Entry() board = gtk.Entry()
#board.connect("changed", self._some_function, arg) board.connect("changed", self.set_board_flop, board)
btn1 = gtk.Button() btn1 = gtk.Button()
btn1.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) btn1.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
@ -180,7 +180,7 @@ Against the range: {
label = gtk.Label("Player1:") label = gtk.Label("Player1:")
board = gtk.Entry() board = gtk.Entry()
#board.connect("changed", self._some_function, arg) board.connect("changed", self.set_hero_cards_flop, board)
btn2 = gtk.Button() btn2 = gtk.Button()
btn2.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) btn2.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
#btn.connect('clicked', self._some_function, arg) #btn.connect('clicked', self._some_function, arg)
@ -195,7 +195,7 @@ Against the range: {
label = gtk.Label("Player2:") label = gtk.Label("Player2:")
board = gtk.Entry() board = gtk.Entry()
#board.connect("changed", self._some_function, arg) board.connect("changed", self.set_villain_cards_flop, board)
btn4 = gtk.Button() btn4 = gtk.Button()
btn4.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) btn4.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
#btn.connect('clicked', self._some_function, arg) #btn.connect('clicked', self._some_function, arg)
@ -210,6 +210,15 @@ Against the range: {
#table.attach(label, i, i+1, j, j+1,) #table.attach(label, i, i+1, j, j+1,)
in_frame.add(table) in_frame.add(table)
def set_board_flop(self, caller, string):
print "DEBUG: called set_board_flop: '%s' '%s'" %(caller ,string)
def set_hero_cards_flop(self, caller, string):
print "DEBUG: called set_hero_cards_flop"
def set_villain_cards_flop(self, caller, string):
print "DEBUG: called set_villain_cards_flop"
def get_vbox(self): def get_vbox(self):

View File

@ -382,7 +382,7 @@ class GuiTourneyPlayerStats (GuiPlayerStats.GuiPlayerStats):
#query = query.replace("<gtbigBlind_test>", bbtest) #query = query.replace("<gtbigBlind_test>", bbtest)
#query = query.replace("<orderbyhgameTypeId>", "") #query = query.replace("<orderbyhgametypeId>", "")
# process self.detailFilters (a list of tuples) # process self.detailFilters (a list of tuples)
flagtest = '' flagtest = ''

View File

@ -126,7 +126,7 @@ class HUD_main(object):
self.main_window.set_icon_stock(gtk.STOCK_HOME) self.main_window.set_icon_stock(gtk.STOCK_HOME)
if not options.hidden: if not options.hidden:
self.main_window.show_all() self.main_window.show_all()
gobject.timeout_add(100, self.check_tables) # gobject.timeout_add(100, self.check_tables)
except: except:
log.exception("Error initializing main_window") log.exception("Error initializing main_window")
@ -282,6 +282,7 @@ class HUD_main(object):
table_name = "%s %s" % (tour_number, tab_number) table_name = "%s %s" % (tour_number, tab_number)
log.error("HUD create: table name %s not found, skipping." % table_name) log.error("HUD create: table name %s not found, skipping." % table_name)
else: else:
tablewindow.key = temp_key
tablewindow.max = max tablewindow.max = max
tablewindow.site = site_name tablewindow.site = site_name
# Test that the table window still exists # Test that the table window still exists
@ -328,9 +329,9 @@ def idle_kill(hud_main, table):
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
try: try:
if table in hud_main.hud_dict: if table in hud_main.hud_dict:
hud_main.hud_dict[table].kill()
hud_main.hud_dict[table].main_window.destroy()
hud_main.vb.remove(hud_main.hud_dict[table].tablehudlabel) hud_main.vb.remove(hud_main.hud_dict[table].tablehudlabel)
hud_main.hud_dict[table].main_window.destroy()
hud_main.hud_dict[table].kill()
del(hud_main.hud_dict[table]) del(hud_main.hud_dict[table])
hud_main.main_window.resize(1, 1) hud_main.main_window.resize(1, 1)
except: except:
@ -342,7 +343,8 @@ def idle_create(hud_main, new_hand_id, table, temp_key, max, poker_game, type, s
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
try: try:
table.gdkhandle = gtk.gdk.window_foreign_new(table.number) if table.gdkhandle is not None: # on windows this should already be set
table.gdkhandle = gtk.gdk.window_foreign_new(table.number)
newlabel = gtk.Label("%s - %s" % (table.site, temp_key)) newlabel = gtk.Label("%s - %s" % (table.site, temp_key))
hud_main.vb.add(newlabel) hud_main.vb.add(newlabel)
newlabel.show() newlabel.show()

View File

@ -261,11 +261,11 @@ db: a connected Database object"""
if not db.isDuplicate(self.dbid_gt, hh['siteHandNo']): if not db.isDuplicate(self.dbid_gt, hh['siteHandNo']):
# Hands - Summary information of hand indexed by handId - gameinfo # Hands - Summary information of hand indexed by handId - gameinfo
hh['gameTypeId'] = self.dbid_gt hh['gametypeId'] = self.dbid_gt
# seats TINYINT NOT NULL, # seats TINYINT NOT NULL,
hh['seats'] = len(self.dbid_pids) hh['seats'] = len(self.dbid_pids)
self.dbid_hands = db.storeHand(hh) self.dbid_hands = db.storeHand(hh, printdata = printtest)
self.dbid_hpid = db.storeHandsPlayers(self.dbid_hands, self.dbid_pids, self.dbid_hpid = db.storeHandsPlayers(self.dbid_hands, self.dbid_pids,
self.stats.getHandsPlayers(), printdata = printtest) self.stats.getHandsPlayers(), printdata = printtest)
if self.saveActions: if self.saveActions:
@ -282,75 +282,10 @@ db: a connected Database object"""
def updateSessionsCache(self, db): def updateSessionsCache(self, db):
db.storeSessionsCache(self.dbid_pids, self.startTime, self.gametype, self.stats.getHandsPlayers()) db.storeSessionsCache(self.dbid_pids, self.startTime, self.gametype, self.stats.getHandsPlayers())
def select(self, handId): def select(self, db, handId):
""" Function to create Hand object from database """ """ Function to create Hand object from database """
c = cnxn.cursor() c = db.get_cursor()
q = """SELECT
# We need at least sitename, gametype, handid
# for the Hand.__init__
c.execute("""SELECT
s.name,
g.category,
g.base,
g.type,
g.limitType,
g.hilo,
round(g.smallBlind / 100.0,2),
round(g.bigBlind / 100.0,2),
round(g.smallBet / 100.0,2),
round(g.bigBet / 100.0,2),
s.currency,
h.boardcard1,
h.boardcard2,
h.boardcard3,
h.boardcard4,
h.boardcard5
FROM
hands as h,
sites as s,
gametypes as g,
handsplayers as hp,
players as p
WHERE
h.id = %(handid)s
and g.id = h.gametypeid
and hp.handid = h.id
and p.id = hp.playerid
and s.id = p.siteid
limit 1""", {'handid':handid})
#TODO: siteid should be in hands table - we took the scenic route through players here.
res = c.fetchone()
gametype = {'category':res[1],'base':res[2],'type':res[3],'limitType':res[4],'hilo':res[5],'sb':res[6],'bb':res[7], 'currency':res[10]}
c = Configuration.Config()
h = HoldemOmahaHand(config = c, hhc = None, sitename=res[0], gametype = gametype, handText=None, builtFrom = "DB", handid=handid)
cards = map(Card.valueSuitFromCard, res[11:16] )
if cards[0]:
h.setCommunityCards('FLOP', cards[0:3])
if cards[3]:
h.setCommunityCards('TURN', [cards[3]])
if cards[4]:
h.setCommunityCards('RIVER', [cards[4]])
#[Card.valueSuitFromCard(x) for x in cards]
# HandInfo : HID, TABLE
# BUTTON - why is this treated specially in Hand?
# answer: it is written out in hand histories
# still, I think we should record all the active seat positions in a seat_order array
c.execute("""SELECT
h.sitehandno as hid,
h.tablename as table,
h.startTime as startTime
FROM
hands as h
WHERE h.id = %(handid)s
""", {'handid':handid})
res = c.fetchone()
h.handid = res[0]
h.tablename = res[1]
h.startTime = res[2] # automatically a datetime
# PlayerStacks
c.execute("""SELECT
hp.seatno, hp.seatno,
round(hp.winnings / 100.0,2) as winnings, round(hp.winnings / 100.0,2) as winnings,
p.name, p.name,
@ -358,69 +293,101 @@ db: a connected Database object"""
hp.card1,hp.card2, hp.card1,hp.card2,
hp.position hp.position
FROM FROM
handsplayers as hp, HandsPlayers as hp,
players as p Players as p
WHERE WHERE
hp.handid = %(handid)s hp.handId = %s
and p.id = hp.playerid and p.id = hp.playerid
""", {'handid':handid}) """
q = q.replace('%s', db.sql.query['placeholder'])
# PlayerStacks
c.execute(q, (handId,))
for (seat, winnings, name, chips, card1,card2, position) in c.fetchall(): for (seat, winnings, name, chips, card1,card2, position) in c.fetchall():
h.addPlayer(seat,name,chips) print "DEBUG: seat: '%s'\tname: '%s'\tchips: '%s'" % (seat, name, chips)
if card1 and card2: self.addPlayer(seat,name,str(chips))
h.addHoleCards(map(Card.valueSuitFromCard, (card1,card2)), name, dealt=True) #if card1 and card2:
if winnings > 0: # self.addHoleCards(map(Card.valueSuitFromCard, (card1,card2)), name, dealt=True)
h.addCollectPot(name, winnings) #if winnings > 0:
if position == 'B': # self.addCollectPot(name, winnings)
h.buttonpos = seat #if position == 'B':
# self.buttonpos = seat
# HandInfo : HID, TABLE
# BUTTON - why is this treated specially in Hand?
# answer: it is written out in hand histories
# still, I think we should record all the active seat positions in a seat_order array
#c.execute("""SELECT
# h.sitehandno as hid,
# h.tablename as table,
# h.startTime as startTime
# FROM
# Hands as h
# WHERE h.id = %(handid)s
# """, {'handid':handid})
#res = c.fetchone()
#h.handid = res[0]
#h.tablename = res[1]
#h.startTime = res[2] # automatically a datetime
#cards = map(Card.valueSuitFromCard, res[11:16] )
#if cards[0]:
# h.setCommunityCards('FLOP', cards[0:3])
#if cards[3]:
# h.setCommunityCards('TURN', [cards[3]])
#if cards[4]:
# h.setCommunityCards('RIVER', [cards[4]])
#[Card.valueSuitFromCard(x) for x in cards]
# actions # actions
c.execute("""SELECT #c.execute("""SELECT
(ha.street,ha.actionno) as actnum, # (ha.street,ha.actionno) as actnum,
p.name, # p.name,
ha.street, # ha.street,
ha.action, # ha.action,
ha.allin, # ha.allin,
round(ha.amount / 100.0,2) # round(ha.amount / 100.0,2)
FROM # FROM
handsplayers as hp, # handsplayers as hp,
handsactions as ha, # handsactions as ha,
players as p # players as p
WHERE # WHERE
hp.handid = %(handid)s # hp.handid = %(handid)s
and ha.handsplayerid = hp.id # and ha.handsplayerid = hp.id
and p.id = hp.playerid # and p.id = hp.playerid
ORDER BY # ORDER BY
ha.street,ha.actionno # ha.street,ha.actionno
""", {'handid':handid}) # """, {'handid':handid})
res = c.fetchall() #res = c.fetchall()
for (actnum,player, streetnum, act, allin, amount) in res: #for (actnum,player, streetnum, act, allin, amount) in res:
act=act.strip() # act=act.strip()
street = h.allStreets[streetnum+1] # street = h.allStreets[streetnum+1]
if act==u'blind': # if act==u'blind':
h.addBlind(player, 'big blind', amount) # h.addBlind(player, 'big blind', amount)
# TODO: The type of blind is not recorded in the DB. # # TODO: The type of blind is not recorded in the DB.
# TODO: preflop street name anomalies in Hand # # TODO: preflop street name anomalies in Hand
elif act==u'fold': # elif act==u'fold':
h.addFold(street,player) # h.addFold(street,player)
elif act==u'call': # elif act==u'call':
h.addCall(street,player,amount) # h.addCall(street,player,amount)
elif act==u'bet': # elif act==u'bet':
h.addBet(street,player,amount) # h.addBet(street,player,amount)
elif act==u'check': # elif act==u'check':
h.addCheck(street,player) # h.addCheck(street,player)
elif act==u'unbet': # elif act==u'unbet':
pass # pass
else: # else:
print act, player, streetnum, allin, amount # print act, player, streetnum, allin, amount
# TODO : other actions # # TODO : other actions
#hhc.readShowdownActions(self) #hhc.readShowdownActions(self)
#hc.readShownCards(self) #hc.readShownCards(self)
h.totalPot() #h.totalPot()
h.rake = h.totalpot - h.totalcollected #h.rake = h.totalpot - h.totalcollected
return h
def addPlayer(self, seat, name, chips): def addPlayer(self, seat, name, chips):
"""\ """\
@ -853,10 +820,11 @@ class HoldemOmahaHand(Hand):
hhc.readOther(self) hhc.readOther(self)
#print "\nHand:\n"+str(self) #print "\nHand:\n"+str(self)
elif builtFrom == "DB": elif builtFrom == "DB":
if handid is not None: #if handid is not None:
self.select(handid) # Will need a handId # self.select(handid) # Will need a handId
else: #else:
log.warning(_("HoldemOmahaHand.__init__:Can't assemble hand from db without a handid")) # log.warning(_("HoldemOmahaHand.__init__:Can't assemble hand from db without a handid"))
print "DEBUG: HoldemOmaha hand initialised for select()"
else: else:
log.warning(_("HoldemOmahaHand.__init__:Neither HHC nor DB+handid provided")) log.warning(_("HoldemOmahaHand.__init__:Neither HHC nor DB+handid provided"))
pass pass
@ -1580,6 +1548,11 @@ Add a complete on [street] by [player] to [amountTo]
else: else:
log.warning(_("join_holecards: # of holecards should be either < 4, 4 or 7 - 5 and 6 should be impossible for anyone who is not a hero")) log.warning(_("join_holecards: # of holecards should be either < 4, 4 or 7 - 5 and 6 should be impossible for anyone who is not a hero"))
log.warning(_("join_holcards: holecards(%s): %s") %(player, holecards)) log.warning(_("join_holcards: holecards(%s): %s") %(player, holecards))
if holecards == [u'0x', u'0x']:
log.warning(_("join_holecards: Player '%s' appears not to have been dealt a card"))
# If a player is listed but not dealt a card in a cash game this can occur
# Noticed in FTP Razz hand. Return 3 empty cards in this case
holecards = [u'0x', u'0x', u'0x']
return holecards return holecards

View File

@ -41,6 +41,9 @@ def fpdb_options():
parser.add_option("-k", "--konverter", parser.add_option("-k", "--konverter",
dest="hhc", default="PokerStarsToFpdb", dest="hhc", default="PokerStarsToFpdb",
help=_("Module name for Hand History Converter")) help=_("Module name for Hand History Converter"))
parser.add_option("-s", "--sitename",
dest="sitename", default=None,
help=_("A sitename"))
parser.add_option("-l", "--logging", parser.add_option("-l", "--logging",
dest = "log_level", dest = "log_level",
choices = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL', 'EMPTY'), choices = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL', 'EMPTY'),
@ -74,6 +77,36 @@ def fpdb_options():
(options, argv) = parser.parse_args() (options, argv) = parser.parse_args()
return (options, argv) return (options, argv)
def site_alias(alias):
"""Function for converting various site aliases to the FPDB name"""
tmp = alias
aliases = {
"PokerStars" : "PokerStars",
"Full Tilt Poker": "Full Tilt Poker",
"PartyPoker" : "PartyPoker",
"Betfair" : "Betfair",
"OnGame" : "OnGame",
"Absolute" : "Absolute",
"UltimateBet" : "UltimateBet",
"Everleaf" : "Everleaf",
"Carbon" : "Carbon",
"iPoker" : "iPoker",
"Winamax" : "Winamax",
"Win2day" : "Win2day",
"Stars" : "PokerStars",
"FTP" : "Full Tilt Poker",
"Party" : "PartyPoker",
"AP" : "Absolute",
"UB" : "UltimateBet",
}
try:
tmp = aliases[alias]
except KeyError, e:
tmp = False
print _("Alias '%s' unknown" % alias)
return tmp
if __name__== "__main__": if __name__== "__main__":
(options, argv) = fpdb_options() (options, argv) = fpdb_options()
print "errorsToConsole =", options.errorsToConsole print "errorsToConsole =", options.errorsToConsole

View File

@ -57,9 +57,11 @@ class PokerStars(HandHistoryConverter):
'20.00': ('5.00', '10.00'), '20': ('5.00', '10.00'), '20.00': ('5.00', '10.00'), '20': ('5.00', '10.00'),
'30.00': ('10.00', '15.00'), '30': ('10.00', '15.00'), '30.00': ('10.00', '15.00'), '30': ('10.00', '15.00'),
'60.00': ('15.00', '30.00'), '60': ('15.00', '30.00'), '60.00': ('15.00', '30.00'), '60': ('15.00', '30.00'),
'80.00': ('20.00', '40.00'), '80': ('20.00', '40.00'),
'100.00': ('25.00', '50.00'), '100': ('25.00', '50.00'), '100.00': ('25.00', '50.00'), '100': ('25.00', '50.00'),
'200.00': ('50.00', '100.00'), '200': ('50.00', '100.00'), '200.00': ('50.00', '100.00'), '200': ('50.00', '100.00'),
'400.00': ('100.00', '200.00'), '400': ('100.00', '200.00'), '400.00': ('100.00', '200.00'), '400': ('100.00', '200.00'),
'800.00': ('200.00', '400.00'), '800': ('200.00', '400.00'),
'1000.00': ('250.00', '500.00'),'1000': ('250.00', '500.00') '1000.00': ('250.00', '500.00'),'1000': ('250.00', '500.00')
} }

View File

@ -1400,11 +1400,11 @@ class Sql:
self.query['addTourneyIndex'] = """CREATE UNIQUE INDEX siteTourneyNo ON Tourneys (siteTourneyNo, tourneyTypeId)""" self.query['addTourneyIndex'] = """CREATE UNIQUE INDEX siteTourneyNo ON Tourneys (siteTourneyNo, tourneyTypeId)"""
if db_server == 'mysql': if db_server == 'mysql':
self.query['addHandsIndex'] = """ALTER TABLE Hands ADD UNIQUE INDEX siteHandNo(siteHandNo, gameTypeId)""" self.query['addHandsIndex'] = """ALTER TABLE Hands ADD UNIQUE INDEX siteHandNo(siteHandNo, gametypeId)"""
elif db_server == 'postgresql': elif db_server == 'postgresql':
self.query['addHandsIndex'] = """CREATE UNIQUE INDEX siteHandNo ON Hands (siteHandNo, gameTypeId)""" self.query['addHandsIndex'] = """CREATE UNIQUE INDEX siteHandNo ON Hands (siteHandNo, gametypeId)"""
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['addHandsIndex'] = """CREATE UNIQUE INDEX siteHandNo ON Hands (siteHandNo, gameTypeId)""" self.query['addHandsIndex'] = """CREATE UNIQUE INDEX siteHandNo ON Hands (siteHandNo, gametypeId)"""
if db_server == 'mysql': if db_server == 'mysql':
self.query['addPlayersIndex'] = """ALTER TABLE Players ADD UNIQUE INDEX name(name, siteId)""" self.query['addPlayersIndex'] = """ALTER TABLE Players ADD UNIQUE INDEX name(name, siteId)"""
@ -1451,6 +1451,34 @@ class Sql:
and (p.siteId = %s or %s = -1) and (p.siteId = %s or %s = -1)
""" """
self.query['get_gameinfo_from_hid'] = """
SELECT
s.name,
g.category,
g.base,
g.type,
g.limitType,
g.hilo,
round(g.smallBlind / 100.0,2),
round(g.bigBlind / 100.0,2),
round(g.smallBet / 100.0,2),
round(g.bigBet / 100.0,2),
g.currency
FROM
Hands as h,
Sites as s,
Gametypes as g,
HandsPlayers as hp,
Players as p
WHERE
h.id = %s
and g.id = h.gametypeid
and hp.handid = h.id
and p.id = hp.playerid
and s.id = p.siteid
limit 1
"""
self.query['get_stats_from_hand'] = """ self.query['get_stats_from_hand'] = """
SELECT hc.playerId AS player_id, SELECT hc.playerId AS player_id,
hp.seatNo AS seat, hp.seatNo AS seat,
@ -2145,7 +2173,7 @@ class Sql:
if db_server == 'mysql': if db_server == 'mysql':
self.query['playerDetailedStats'] = """ self.query['playerDetailedStats'] = """
select <hgameTypeId> AS hgametypeid select <hgametypeId> AS hgametypeid
,<playerName> AS pname ,<playerName> AS pname
,gt.base ,gt.base
,gt.category ,gt.category
@ -2231,7 +2259,7 @@ class Sql:
,variance(hp.totalProfit/100.0) AS variance ,variance(hp.totalProfit/100.0) AS variance
from HandsPlayers hp from HandsPlayers hp
inner join Hands h on (h.id = hp.handId) inner join Hands h on (h.id = hp.handId)
inner join Gametypes gt on (gt.Id = h.gameTypeId) inner join Gametypes gt on (gt.Id = h.gametypeId)
inner join Sites s on (s.Id = gt.siteId) inner join Sites s on (s.Id = gt.siteId)
inner join Players p on (p.Id = hp.playerId) inner join Players p on (p.Id = hp.playerId)
where hp.playerId in <player_test> where hp.playerId in <player_test>
@ -2242,7 +2270,7 @@ class Sql:
<flagtest> <flagtest>
<gtbigBlind_test> <gtbigBlind_test>
and date_format(h.startTime, '%Y-%m-%d %T') <datestest> and date_format(h.startTime, '%Y-%m-%d %T') <datestest>
group by hgameTypeId group by hgametypeId
,pname ,pname
,gt.base ,gt.base
,gt.category ,gt.category
@ -2259,14 +2287,14 @@ class Sql:
when 'S' then 'S' when 'S' then 'S'
else concat('Z', <position>) else concat('Z', <position>)
end end
<orderbyhgameTypeId> <orderbyhgametypeId>
,upper(gt.limitType) desc ,upper(gt.limitType) desc
,maxbigblind desc ,maxbigblind desc
,s.name ,s.name
""" """
elif db_server == 'postgresql': elif db_server == 'postgresql':
self.query['playerDetailedStats'] = """ self.query['playerDetailedStats'] = """
select <hgameTypeId> AS hgametypeid select <hgametypeId> AS hgametypeid
,<playerName> AS pname ,<playerName> AS pname
,gt.base ,gt.base
,gt.category ,gt.category
@ -2352,7 +2380,7 @@ class Sql:
,variance(hp.totalProfit/100.0) AS variance ,variance(hp.totalProfit/100.0) AS variance
from HandsPlayers hp from HandsPlayers hp
inner join Hands h on (h.id = hp.handId) inner join Hands h on (h.id = hp.handId)
inner join Gametypes gt on (gt.Id = h.gameTypeId) inner join Gametypes gt on (gt.Id = h.gametypeId)
inner join Sites s on (s.Id = gt.siteId) inner join Sites s on (s.Id = gt.siteId)
inner join Players p on (p.Id = hp.playerId) inner join Players p on (p.Id = hp.playerId)
where hp.playerId in <player_test> where hp.playerId in <player_test>
@ -2363,7 +2391,7 @@ class Sql:
<flagtest> <flagtest>
<gtbigBlind_test> <gtbigBlind_test>
and to_char(h.startTime, 'YYYY-MM-DD HH24:MI:SS') <datestest> and to_char(h.startTime, 'YYYY-MM-DD HH24:MI:SS') <datestest>
group by hgameTypeId group by hgametypeId
,pname ,pname
,gt.base ,gt.base
,gt.category ,gt.category
@ -2381,14 +2409,14 @@ class Sql:
when '0' then 'Y' when '0' then 'Y'
else 'Z'||<position> else 'Z'||<position>
end end
<orderbyhgameTypeId> <orderbyhgametypeId>
,upper(gt.limitType) desc ,upper(gt.limitType) desc
,maxbigblind desc ,maxbigblind desc
,s.name ,s.name
""" """
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['playerDetailedStats'] = """ self.query['playerDetailedStats'] = """
select <hgameTypeId> AS hgametypeid select <hgametypeId> AS hgametypeid
,<playerName> AS pname ,<playerName> AS pname
,gt.base ,gt.base
,gt.category AS category ,gt.category AS category
@ -2474,7 +2502,7 @@ class Sql:
,variance(hp.totalProfit/100.0) AS variance ,variance(hp.totalProfit/100.0) AS variance
from HandsPlayers hp from HandsPlayers hp
inner join Hands h on (h.id = hp.handId) inner join Hands h on (h.id = hp.handId)
inner join Gametypes gt on (gt.Id = h.gameTypeId) inner join Gametypes gt on (gt.Id = h.gametypeId)
inner join Sites s on (s.Id = gt.siteId) inner join Sites s on (s.Id = gt.siteId)
inner join Players p on (p.Id = hp.playerId) inner join Players p on (p.Id = hp.playerId)
where hp.playerId in <player_test> where hp.playerId in <player_test>
@ -2485,7 +2513,7 @@ class Sql:
<flagtest> <flagtest>
<gtbigBlind_test> <gtbigBlind_test>
and datetime(h.startTime) <datestest> and datetime(h.startTime) <datestest>
group by hgameTypeId group by hgametypeId
,hp.playerId ,hp.playerId
,gt.base ,gt.base
,gt.category ,gt.category
@ -2503,7 +2531,7 @@ class Sql:
when '0' then 'Y' when '0' then 'Y'
else 'Z'||<position> else 'Z'||<position>
end end
<orderbyhgameTypeId> <orderbyhgametypeId>
,upper(gt.limitType) desc ,upper(gt.limitType) desc
,max(gt.bigBlind) desc ,max(gt.bigBlind) desc
,s.name ,s.name
@ -2693,7 +2721,7 @@ class Sql:
,format( sum(activeSeats*HDs)/(sum(HDs)+0.0), 2) AS AvgSeats ,format( sum(activeSeats*HDs)/(sum(HDs)+0.0), 2) AS AvgSeats
from Gametypes gt from Gametypes gt
inner join Sites s on s.Id = gt.siteId inner join Sites s on s.Id = gt.siteId
inner join HudCache hc on hc.gameTypeId = gt.Id inner join HudCache hc on hc.gametypeId = gt.Id
where hc.playerId in <player_test> where hc.playerId in <player_test>
and <gtbigBlind_test> and <gtbigBlind_test>
and hc.activeSeats <seats_test> and hc.activeSeats <seats_test>
@ -2714,7 +2742,7 @@ class Sql:
else variance(hprof.profit/100.0) else variance(hprof.profit/100.0)
end as variance end as variance
from from
(select hp.handId, <hgameTypeId> as gtId, hp.totalProfit as profit (select hp.handId, <hgametypeId> as gtId, hp.totalProfit as profit
from HandsPlayers hp from HandsPlayers hp
inner join Hands h ON h.id = hp.handId inner join Hands h ON h.id = hp.handId
where hp.playerId in <player_test> where hp.playerId in <player_test>
@ -2798,7 +2826,7 @@ class Sql:
,to_char(sum(activeSeats*HDs)/(sum(HDs)+0.0),'90D00') AS AvgSeats ,to_char(sum(activeSeats*HDs)/(sum(HDs)+0.0),'90D00') AS AvgSeats
from Gametypes gt from Gametypes gt
inner join Sites s on s.Id = gt.siteId inner join Sites s on s.Id = gt.siteId
inner join HudCache hc on hc.gameTypeId = gt.Id inner join HudCache hc on hc.gametypeId = gt.Id
where hc.playerId in <player_test> where hc.playerId in <player_test>
and <gtbigBlind_test> and <gtbigBlind_test>
and hc.activeSeats <seats_test> and hc.activeSeats <seats_test>
@ -2819,7 +2847,7 @@ class Sql:
else variance(hprof.profit/100.0) else variance(hprof.profit/100.0)
end as variance end as variance
from from
(select hp.handId, <hgameTypeId> as gtId, hp.totalProfit as profit (select hp.handId, <hgametypeId> as gtId, hp.totalProfit as profit
from HandsPlayers hp from HandsPlayers hp
inner join Hands h ON (h.id = hp.handId) inner join Hands h ON (h.id = hp.handId)
where hp.playerId in <player_test> where hp.playerId in <player_test>
@ -2921,7 +2949,7 @@ class Sql:
,format( sum(activeSeats*HDs)/(sum(HDs)+0.0), 2) AS AvgSeats ,format( sum(activeSeats*HDs)/(sum(HDs)+0.0), 2) AS AvgSeats
from Gametypes gt from Gametypes gt
inner join Sites s on s.Id = gt.siteId inner join Sites s on s.Id = gt.siteId
inner join HudCache hc on hc.gameTypeId = gt.Id inner join HudCache hc on hc.gametypeId = gt.Id
where hc.playerId in <player_test> where hc.playerId in <player_test>
and <gtbigBlind_test> and <gtbigBlind_test>
and hc.activeSeats <seats_test> and hc.activeSeats <seats_test>
@ -2951,7 +2979,7 @@ class Sql:
else variance(hprof.profit/100.0) else variance(hprof.profit/100.0)
end as variance end as variance
from from
(select hp.handId, <hgameTypeId> as gtId, hp.position (select hp.handId, <hgametypeId> as gtId, hp.position
, hp.totalProfit as profit , hp.totalProfit as profit
from HandsPlayers hp from HandsPlayers hp
inner join Hands h ON (h.id = hp.handId) inner join Hands h ON (h.id = hp.handId)
@ -3060,7 +3088,7 @@ class Sql:
,to_char(sum(activeSeats*HDs)/(sum(HDs)+0.0),'90D00') AS AvgSeats ,to_char(sum(activeSeats*HDs)/(sum(HDs)+0.0),'90D00') AS AvgSeats
from Gametypes gt from Gametypes gt
inner join Sites s on (s.Id = gt.siteId) inner join Sites s on (s.Id = gt.siteId)
inner join HudCache hc on (hc.gameTypeId = gt.Id) inner join HudCache hc on (hc.gametypeId = gt.Id)
where hc.playerId in <player_test> where hc.playerId in <player_test>
and <gtbigBlind_test> and <gtbigBlind_test>
and hc.activeSeats <seats_test> and hc.activeSeats <seats_test>
@ -3090,14 +3118,14 @@ class Sql:
else variance(hprof.profit/100.0) else variance(hprof.profit/100.0)
end as variance end as variance
from from
(select hp.handId, <hgameTypeId> as gtId, hp.position (select hp.handId, <hgametypeId> as gtId, hp.position
, hp.totalProfit as profit , hp.totalProfit as profit
from HandsPlayers hp from HandsPlayers hp
inner join Hands h ON (h.id = hp.handId) inner join Hands h ON (h.id = hp.handId)
where hp.playerId in <player_test> where hp.playerId in <player_test>
and hp.tourneysPlayersId IS NULL and hp.tourneysPlayersId IS NULL
and to_char(h.startTime, 'YYYY-MM-DD') <datestest> and to_char(h.startTime, 'YYYY-MM-DD') <datestest>
group by hp.handId, gameTypeId, hp.position, hp.totalProfit group by hp.handId, gametypeId, hp.position, hp.totalProfit
) hprof ) hprof
group by hprof.gtId, PlPosition group by hprof.gtId, PlPosition
) hprof2 ) hprof2
@ -3191,7 +3219,7 @@ class Sql:
SELECT UNIX_TIMESTAMP(h.startTime) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit SELECT UNIX_TIMESTAMP(h.startTime) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
FROM HandsPlayers hp FROM HandsPlayers hp
INNER JOIN Hands h on (h.id = hp.handId) INNER JOIN Hands h on (h.id = hp.handId)
INNER JOIN Gametypes gt on (gt.Id = h.gameTypeId) INNER JOIN Gametypes gt on (gt.Id = h.gametypeId)
INNER JOIN Sites s on (s.Id = gt.siteId) INNER JOIN Sites s on (s.Id = gt.siteId)
INNER JOIN Players p on (p.Id = hp.playerId) INNER JOIN Players p on (p.Id = hp.playerId)
WHERE hp.playerId in <player_test> WHERE hp.playerId in <player_test>
@ -3203,7 +3231,7 @@ class Sql:
SELECT EXTRACT(epoch from h.startTime) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit SELECT EXTRACT(epoch from h.startTime) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
FROM HandsPlayers hp FROM HandsPlayers hp
INNER JOIN Hands h on (h.id = hp.handId) INNER JOIN Hands h on (h.id = hp.handId)
INNER JOIN Gametypes gt on (gt.Id = h.gameTypeId) INNER JOIN Gametypes gt on (gt.Id = h.gametypeId)
INNER JOIN Sites s on (s.Id = gt.siteId) INNER JOIN Sites s on (s.Id = gt.siteId)
INNER JOIN Players p on (p.Id = hp.playerId) INNER JOIN Players p on (p.Id = hp.playerId)
WHERE hp.playerId in <player_test> WHERE hp.playerId in <player_test>
@ -3215,7 +3243,7 @@ class Sql:
SELECT STRFTIME('<ampersand_s>', h.startTime) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit SELECT STRFTIME('<ampersand_s>', h.startTime) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
FROM HandsPlayers hp FROM HandsPlayers hp
INNER JOIN Hands h on (h.id = hp.handId) INNER JOIN Hands h on (h.id = hp.handId)
INNER JOIN Gametypes gt on (gt.Id = h.gameTypeId) INNER JOIN Gametypes gt on (gt.Id = h.gametypeId)
INNER JOIN Sites s on (s.Id = gt.siteId) INNER JOIN Sites s on (s.Id = gt.siteId)
INNER JOIN Players p on (p.Id = hp.playerId) INNER JOIN Players p on (p.Id = hp.playerId)
WHERE hp.playerId in <player_test> WHERE hp.playerId in <player_test>
@ -4019,26 +4047,57 @@ class Sql:
(case when tourneyTypeId+0=%s then 1 else 0 end) end)=1 (case when tourneyTypeId+0=%s then 1 else 0 end) end)=1
AND styleKey=%s""" AND styleKey=%s"""
self.query['check_sessionscache'] = """ self.query['get_hero_hudcache_start'] = """select min(hc.styleKey)
UPDATE SessionsCache SET from HudCache hc
sessionStart=sessionStart, where hc.playerId in <playerid_list>
sessionEnd=sessionEnd, and hc.styleKey like 'd%'"""
ringHDs=ringHDs,
tourHDs=tourHDs, ####################################
totalProfit=totalProfit, # Queries to rebuild/modify sessionscache
bigBets=bigBets ####################################
WHERE sessionEnd>=%s
AND sessionStart<=%s""" self.query['select_sessionscache'] = """
SELECT sessionStart,
self.query['insert_sessionscache'] = """
INSERT INTO SessionsCache (
sessionStart,
sessionEnd, sessionEnd,
ringHDs, ringHDs,
tourHDs, tourHDs,
totalProfit, totalProfit,
bigBets) bigBets
VALUES (%s, %s, %s, %s, %s, %s)""" FROM SessionsCache
WHERE sessionEnd>=%s
AND sessionStart<=%s"""
self.query['select_sessionscache_mid'] = """
SELECT sessionStart,
sessionEnd,
ringHDs,
tourHDs,
totalProfit,
bigBets
FROM SessionsCache
WHERE sessionEnd>=%s
AND sessionStart<=%s"""
self.query['select_sessionscache_start'] = """
SELECT sessionStart,
sessionEnd,
ringHDs,
tourHDs,
totalProfit,
bigBets
FROM SessionsCache
WHERE sessionStart>%s
AND sessionEnd>=%s
AND sessionStart<=%s"""
self.query['update_sessionscache_mid'] = """
UPDATE SessionsCache SET
ringHDs=ringHDs+%s,
tourHDs=tourHDs+%s,
totalProfit=totalProfit+%s,
bigBets=bigBets+%s
WHERE sessionStart<=%s
AND sessionEnd>=%s"""
self.query['update_sessionscache_start'] = """ self.query['update_sessionscache_start'] = """
UPDATE SessionsCache SET UPDATE SessionsCache SET
@ -4050,7 +4109,7 @@ class Sql:
WHERE sessionStart>%s WHERE sessionStart>%s
AND sessionEnd>=%s AND sessionEnd>=%s
AND sessionStart<=%s""" AND sessionStart<=%s"""
self.query['update_sessionscache_end'] = """ self.query['update_sessionscache_end'] = """
UPDATE SessionsCache SET UPDATE SessionsCache SET
sessionEnd=%s, sessionEnd=%s,
@ -4062,30 +4121,26 @@ class Sql:
AND sessionEnd>=%s AND sessionEnd>=%s
AND sessionStart<=%s""" AND sessionStart<=%s"""
self.query['update_sessionscache'] = """ self.query['insert_sessionscache'] = """
UPDATE SessionsCache SET INSERT INTO SessionsCache (
ringHDs=ringHDs+%s, sessionStart,
tourHDs=tourHDs+%s, sessionEnd,
totalProfit=totalProfit+%s, ringHDs,
bigBets=bigBets+%s tourHDs,
WHERE sessionStart<=%s totalProfit,
AND sessionEnd>=%s""" bigBets)
VALUES (%s, %s, %s, %s, %s, %s)"""
self.query['merge_sessionscache'] = """ self.query['merge_sessionscache'] = """
SELECT min(sessionStart), max(sessionEnd), sum(ringHDs), sum(tourHDs), sum(totalProfit), sum(bigBets) SELECT min(sessionStart), max(sessionEnd), sum(ringHDs), sum(tourHDs), sum(totalProfit), sum(bigBets)
FROM SessionsCache FROM SessionsCache
WHERE sessionStart>=%s WHERE sessionEnd>=%s
AND sessionEnd<=%s""" AND sessionStart<=%s"""
self.query['delete_sessions'] = """ self.query['delete_sessions'] = """
DELETE FROM SessionsCache DELETE FROM SessionsCache
WHERE sessionStart>=%s WHERE sessionEnd>=%s
AND sessionEnd<=%s""" AND sessionStart<=%s"""
self.query['get_hero_hudcache_start'] = """select min(hc.styleKey)
from HudCache hc
where hc.playerId in <playerid_list>
and hc.styleKey like 'd%'"""
if db_server == 'mysql': if db_server == 'mysql':
self.query['analyze'] = """ self.query['analyze'] = """

View File

@ -117,6 +117,7 @@ class Table_Window(object):
self.config = config self.config = config
self.site = site self.site = site
self.hud = None # fill in later self.hud = None # fill in later
self.gdkhandle = None
if tournament is not None and table_number is not None: if tournament is not None and table_number is not None:
self.tournament = int(tournament) self.tournament = int(tournament)
self.table = int(table_number) self.table = int(table_number)
@ -124,13 +125,11 @@ class Table_Window(object):
self.type = "tour" self.type = "tour"
table_kwargs = dict(tournament = self.tournament, table_number = self.table) table_kwargs = dict(tournament = self.tournament, table_number = self.table)
self.tableno_re = getTableNoRe(self.config, self.site, tournament = self.tournament) self.tableno_re = getTableNoRe(self.config, self.site, tournament = self.tournament)
self.key = tournament # used as key for the hud_dict in HUD_main
elif table_name is not None: elif table_name is not None:
self.name = table_name self.name = table_name
self.type = "cash" self.type = "cash"
self.tournament = None self.tournament = None
table_kwargs = dict(table_name = table_name) table_kwargs = dict(table_name = table_name)
self.key = table_name
else: else:
return None return None
@ -138,10 +137,6 @@ class Table_Window(object):
self.search_string = getTableTitleRe(self.config, self.site, self.type, **table_kwargs) self.search_string = getTableTitleRe(self.config, self.site, self.type, **table_kwargs)
self.find_table_parameters() self.find_table_parameters()
try:
self.gdkhandle = gtk.gdk.window_foreign_new(self.number)
except AttributeError: # self.number does not exist, table was closed
return None
geo = self.get_geometry() geo = self.get_geometry()
if geo is None: return None if geo is None: return None
self.width = geo['width'] self.width = geo['width']

View File

@ -28,6 +28,9 @@ import Configuration
import Database import Database
import SQL import SQL
import fpdb_import import fpdb_import
import Options
import datetime
import pytz
class FpdbError: class FpdbError:
@ -59,6 +62,69 @@ class FpdbError:
idx = f.find('regression') idx = f.find('regression')
print "(%3d) : %s" %(self.histogram[f], f[idx:]) print "(%3d) : %s" %(self.histogram[f], f[idx:])
def compare_handsplayers_file(filename, importer, errors):
hashfilename = filename + '.hp'
in_fh = codecs.open(hashfilename, 'r', 'utf8')
whole_file = in_fh.read()
in_fh.close()
testhash = eval(whole_file)
hhc = importer.getCachedHHC()
handlist = hhc.getProcessedHands()
#We _really_ only want to deal with a single hand here.
for hand in handlist:
ghash = hand.stats.getHandsPlayers()
for p in ghash:
#print "DEBUG: player: '%s'" % p
pstat = ghash[p]
teststat = testhash[p]
for stat in pstat:
#print "pstat[%s][%s]: %s == %s" % (p, stat, pstat[stat], teststat[stat])
try:
if pstat[stat] == teststat[stat]:
# The stats match - continue
pass
else:
# Stats don't match - Doh!
errors.error_report(filename, hand, stat, ghash, testhash, p)
except KeyError, e:
errors.error_report(filename, False, "KeyError: '%s'" % stat, False, False, p)
def compare_hands_file(filename, importer, errors):
hashfilename = filename + '.hands'
in_fh = codecs.open(hashfilename, 'r', 'utf8')
whole_file = in_fh.read()
in_fh.close()
testhash = eval(whole_file)
hhc = importer.getCachedHHC()
handlist = hhc.getProcessedHands()
for hand in handlist:
ghash = hand.stats.getHands()
for datum in ghash:
#print "DEBUG: hand: '%s'" % datum
try:
if ghash[datum] == testhash[datum]:
# The stats match - continue
pass
else:
# Stats don't match.
if datum == "gametypeId":
# Not an error. gametypeIds are dependent on the order added to the db.
#print "DEBUG: Skipping mismatched gamtypeId"
pass
else:
errors.error_report(filename, hand, datum, ghash, testhash, None)
except KeyError, e:
errors.error_report(filename, False, "KeyError: '%s'" % stat, False, False, p)
def compare(leaf, importer, errors, site): def compare(leaf, importer, errors, site):
filename = leaf filename = leaf
#print "DEBUG: fileanme: %s" % filename #print "DEBUG: fileanme: %s" % filename
@ -69,39 +135,13 @@ def compare(leaf, importer, errors, site):
importer.addBulkImportImportFileOrDir(filename, site=site) importer.addBulkImportImportFileOrDir(filename, site=site)
(stored, dups, partial, errs, ttime) = importer.runImport() (stored, dups, partial, errs, ttime) = importer.runImport()
if os.path.isfile(filename + '.hp') and errs < 1:
# Compare them
hashfilename = filename + '.hp'
in_fh = codecs.open(hashfilename, 'r', 'utf8')
whole_file = in_fh.read()
in_fh.close()
testhash = eval(whole_file)
hhc = importer.getCachedHHC()
handlist = hhc.getProcessedHands()
#We _really_ only want to deal with a single hand here.
for hand in handlist:
ghash = hand.stats.getHandsPlayers()
for p in ghash:
#print "DEBUG: player: '%s'" % p
pstat = ghash[p]
teststat = testhash[p]
for stat in pstat:
#print "pstat[%s][%s]: %s == %s" % (p, stat, pstat[stat], teststat[stat])
try:
if pstat[stat] == teststat[stat]:
# The stats match - continue
pass
else:
# Stats don't match - Doh!
errors.error_report(filename, hand, stat, ghash, testhash, p)
except KeyError, e:
errors.error_report(filename, False, "KeyError: '%s'" % stat, False, False, p)
if errs > 0: if errs > 0:
errors.error_report(filename, False, "Parse", False, False, False) errors.error_report(filename, False, "Parse", False, False, False)
else:
if os.path.isfile(filename + '.hp'):
compare_handsplayers_file(filename, importer, errors)
if os.path.isfile(filename + '.hands'):
compare_hands_file(filename, importer, errors)
importer.clearFileList() importer.clearFileList()
@ -117,10 +157,28 @@ def walk_testfiles(dir, function, importer, errors, site):
else: else:
compare(nfile, importer, errors, site) compare(nfile, importer, errors, site)
def usage():
print "USAGE:"
sys.exit(0)
def main(argv=None): def main(argv=None):
if argv is None: if argv is None:
argv = sys.argv[1:] argv = sys.argv[1:]
(options, argv) = Options.fpdb_options()
test_all_sites = True
if options.usage == True:
usage()
if options.sitename:
options.sitename = Options.site_alias(options.sitename)
if options.sitename == False:
usage()
print "Only regression testing '%s' files" % (options.sitename)
test_all_sites = False
config = Configuration.Config(file = "HUD_config.test.xml") config = Configuration.Config(file = "HUD_config.test.xml")
db = Database.Database(config) db = Database.Database(config)
sql = SQL.Sql(db_server = 'sqlite') sql = SQL.Sql(db_server = 'sqlite')
@ -159,21 +217,27 @@ def main(argv=None):
] ]
sites = { sites = {
'PokerStars' : True, 'PokerStars' : False,
'Full Tilt Poker' : True, 'Full Tilt Poker' : False,
'PartyPoker' : True, 'PartyPoker' : False,
'Betfair' : True, 'Betfair' : False,
'OnGame' : True, 'OnGame' : False,
'Absolute' : True, 'Absolute' : False,
'UltimateBet' : True, 'UltimateBet' : False,
'Everleaf' : True, 'Everleaf' : False,
'Carbon' : True, 'Carbon' : False,
'PKR' : False, #'PKR' : False,
'iPoker' : True, 'iPoker' : False,
'Win2day' : True, 'Win2day' : False,
'Winamax' : True, 'Winamax' : False,
} }
if test_all_sites == True:
for s in sites:
sites[s] = True
else:
sites[options.sitename] = True
if sites['PokerStars'] == True: if sites['PokerStars'] == True:
walk_testfiles("regression-test-files/cash/Stars/", compare, importer, PokerStarsErrors, "PokerStars") walk_testfiles("regression-test-files/cash/Stars/", compare, importer, PokerStarsErrors, "PokerStars")
walk_testfiles("regression-test-files/tour/Stars/", compare, importer, PokerStarsErrors, "PokerStars") walk_testfiles("regression-test-files/tour/Stars/", compare, importer, PokerStarsErrors, "PokerStars")
@ -195,8 +259,8 @@ def main(argv=None):
walk_testfiles("regression-test-files/cash/Everleaf/", compare, importer, EverleafErrors, "Everleaf") walk_testfiles("regression-test-files/cash/Everleaf/", compare, importer, EverleafErrors, "Everleaf")
if sites['Carbon'] == True: if sites['Carbon'] == True:
walk_testfiles("regression-test-files/cash/Carbon/", compare, importer, CarbonErrors, "Carbon") walk_testfiles("regression-test-files/cash/Carbon/", compare, importer, CarbonErrors, "Carbon")
if sites['PKR'] == True: #if sites['PKR'] == True:
walk_testfiles("regression-test-files/cash/PKR/", compare, importer, PKRErrors, "PKR") # walk_testfiles("regression-test-files/cash/PKR/", compare, importer, PKRErrors, "PKR")
if sites['iPoker'] == True: if sites['iPoker'] == True:
walk_testfiles("regression-test-files/cash/iPoker/", compare, importer, iPokerErrors, "iPoker") walk_testfiles("regression-test-files/cash/iPoker/", compare, importer, iPokerErrors, "iPoker")
if sites['Winamax'] == True: if sites['Winamax'] == True:

View File

@ -76,6 +76,11 @@ class Table(Table_Window):
self.title = titles[hwnd] self.title = titles[hwnd]
self.hud = None self.hud = None
self.number = hwnd self.number = hwnd
if self.gdkhandle is not None:
try: # Windows likes this here - Linux doesn't
self.gdkhandle = gtk.gdk.window_foreign_new(self.number)
except AttributeError:
pass
def get_geometry(self): def get_geometry(self):
try: try:

View File

@ -65,28 +65,35 @@ class Table(Table_Window):
if self.number is None: if self.number is None:
return None return None
(self.window, self.parent) = self.get_window_from_xid(self.number) (self.window, self.parent) = self.get_window_from_xid(self.number)
# def get_window_from_xid(self, id):
# for outside in root.query_tree().children:
# if outside.id == id:
# return (outside, outside.query_tree().parent)
# for inside in outside.query_tree().children:
# if inside.id == id: # GNOME, Xfce
# return (inside, inside.query_tree().parent)
# for wayinside in inside.query_tree().children:
# if wayinside.id == id: # KDE
# parent = wayinside.query_tree().parent
# return (wayinside, parent.query_tree().parent)
# return (None, None)
def get_window_from_xid(self, id): def get_window_from_xid(self, id):
for outside in root.query_tree().children: for top_level in root.query_tree().children:
if outside.id == id: if top_level.id == id:
return (outside, outside.query_tree().parent) return (top_level, None)
for inside in outside.query_tree().children: for w in treewalk(top_level):
if inside.id == id: # GNOME, Xfce if w.id == id:
return (inside, inside.query_tree().parent) return (w, top_level)
for wayinside in inside.query_tree().children:
if wayinside.id == id: # KDE
parent = wayinside.query_tree().parent
return (wayinside, parent.query_tree().parent)
return (None, None)
def get_geometry(self): def get_geometry(self):
try: try:
my_geo = self.window.get_geometry() my_geo = self.window.get_geometry()
if self.parent is None: if self.parent is None:
return {'x' : my_geo.x + pa_geo.x, return {'x' : my_geo.x,
'y' : my_geo.y + pa_geo.y, 'y' : my_geo.y,
'width' : my_geo.width, 'width' : my_geo.width,
'height' : my_geo.height 'height' : my_geo.height
} }
@ -116,3 +123,10 @@ class Table(Table_Window):
# This is the gdkhandle for the HUD window # This is the gdkhandle for the HUD window
gdkwindow = gtk.gdk.window_foreign_new(window.window.xid) gdkwindow = gtk.gdk.window_foreign_new(window.window.xid)
gdkwindow.set_transient_for(self.gdkhandle) gdkwindow.set_transient_for(self.gdkhandle)
def treewalk(parent):
for w in parent.query_tree().children:
for ww in treewalk(w):
yield ww
yield w

Binary file not shown.

View File

@ -1,338 +0,0 @@
#
# 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
# for fpdb alter the following line from __import__ to import...as... .
# fpdb py2exe package build does no recognise __import__ statement,
# and fails at runtime with _pokereval_2_6 not found
#_pokereval = __import__('_pokereval_' + sys.version[0] + '_' + sys.version[2])
import _pokereval_2_6 as _pokereval
from types import *
class PokerEval:
"""\
Evaluate the strengh of a poker hand for a given poker variant.
In all methods, when a list of cards is to be provided (for instance
with the "hand" argument of the "best" method), each member of the
list may be a number or a string designating a card according to
the following table:
2h/00 2d/13 2c/26 2s/39
3h/01 3d/14 3c/27 3s/40
4h/02 4d/15 4c/28 4s/41
5h/03 5d/16 5c/29 5s/42
6h/04 6d/17 6c/30 6s/43
7h/05 7d/18 7c/31 7s/44
8h/06 8d/19 8c/32 8s/45
9h/07 9d/20 9c/33 9s/46
Th/08 Td/21 Tc/34 Ts/47
Jh/09 Jd/22 Jc/35 Js/48
Qh/10 Qd/23 Qc/36 Qs/49
Kh/11 Kd/24 Kc/37 Ks/50
Ah/12 Ad/25 Ac/38 As/51
The string __ (two underscore) or the number 255 are placeholders
meaning that the card is unknown.
"""
def best(self, side, hand, board = []):
"""\
Return the best five card combination that can be made with the cards
listed in "hand" and, optionally, board. The "side" may be "hi" or
"low". The "board" argument must only be provided for variants where
knowing if a given card is taken from the board or not is significant
(such as Omaha but not Holdem).
A list is returned. The first element is the numerical value
of the hand (better hands have higher values if "side" is "hi" and
lower values if "side" is "low"). The second element is a list whose
first element is the strength of the hand among the following:
Nothing (only if "side" equals "low")
NoPair
TwoPair
Trips
Straight
Flush
FlHouse
Quads
StFlush
The last five elements are numbers describing the best hand properly
sorted (for instance the ace is at the end for no pair if "side" is low or
at the beginning if "side" high).
Examples:
[134414336, ['StFlush', 29, 28, 27, 26, 38]] is the wheel five to ace, clubs
[475920, ['NoPair', 45, 29, 41, 39, 51]] is As, 8s, 5c, 4s, 2s
[268435455, ['Nothing']] means there is no qualifying low
"""
if len(hand + board) >= 5:
return _pokereval.eval_hand(side, hand, board)
else:
return False
def best_hand(self, side, hand, board = []):
"""\
Return the best five card combination that can be made with the cards
listed in "hand" and, optionaly, board. The "side" may be "hi" or
"low". The returned value is the second element of the list returned
by the "best" method.
"""
if len(hand + board) >= 5:
return _pokereval.eval_hand(side, hand, board)[1]
else:
return False
def best_hand_value(self, side, hand, board = []):
"""\
Return the best five card combination that can be made with the cards
listed in "hand" and, optionaly, board. The "side" may be "hi" or
"low". The returned value is the first element of the list returned
by the "best" method.
"""
if len(hand + board) >= 5:
return _pokereval.eval_hand(side, hand, board)[0]
else:
return False
def evaln(self, cards):
"""\
Call the poker-eval Hand_EVAL_N function with the "cards" argument.
Return the strength of the "cards" as a number. The higher the
better.
"""
return _pokereval.evaln(cards)
def winners(self, *args, **kwargs):
"""\
Return a list of the indexes of the best hands, relative to the "pockets"
keyword argument. For instance, if the first pocket and third pocket cards
tie, the list would be [0, 2]. Since there may be more than one way to
win a hand, a hash is returned with the list of the winners for each so
called side. For instace {'hi': [0], 'low': [1]} means pocket cards
at index 0 won the high side of the hand and pocket cards at index 1
won the low side.
See the"poker_eval" method for a detailed
explanation of the semantics of the arguments.
If the keyword argument "fill_pockets" is set, pocket cards
can contain a placeholder (i.e. 255 or __) that will be be
used as specified in the "poker_eval" method documentation.
If the keyword argument "fill_pockets" is not set, pocket cards
that contain at least one placeholder (i.e. 255 or __) are
ignored completly. For instance if winners is called as follows
o.winners(game = 'holdem', pockets = [ [ '__', 'As' ], [ 'Ks', 'Kd'] ])
it is strictly equivalent as calling
o.winners(game = 'holdem', pockets = [ [ 'Ks', 'Kd'] ]).
"""
index2index = {}
normalized_pockets = []
normalized_index = 0
pockets = kwargs["pockets"][:]
for index in xrange(len(pockets)):
if not kwargs.has_key("fill_pockets"):
if 255 in pockets[index] or "__" in pockets[index]:
pockets[index] = []
if pockets[index] != []:
normalized_pockets.append(pockets[index])
index2index[index] = normalized_index
normalized_index += 1
kwargs["pockets"] = normalized_pockets
results = _pokereval.poker_eval(*args, **kwargs)
(count, haslopot, hashipot) = results.pop(0)
winners = { 'low': [], 'hi': [] }
for index in xrange(len(pockets)):
if index2index.has_key(index):
result = results[index2index[index]]
if result[1] == 1 or result[3] == 1:
winners["hi"].append(index)
if result[4] == 1 or result[6] == 1:
winners["low"].append(index)
if not haslopot or len(winners["low"]) == 0:
del winners["low"]
if not hashipot:
del winners["hi"]
return winners
def poker_eval(self, *args, **kwargs):
"""\
Provided with a description of a poker game, return the outcome (if at showdown) or
the expected value of each hand. The poker game description is provided as a set
of keyword arguments with the following meaning:
game : the variant (holdem, holdem8, omaha, omaha8, 7stud, 7stud8, razz,
5draw, 5draw8, 5drawnsq, lowball, lowball27).
Mandatory, no default.
pockets : list of pocket cards for each player still in game. Each member
of the list is a list of cards. The position of the pocket cards
in the list is meaningfull for the value returned will refer to
this position when stating which player wins, tie or loose.
Example: [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]]
Cards do not have to be real cards like "tc" or "4s". They may also be a
placeholder, denoted by "__" or 255. When using placeholders, the
keyword argument "iterations" may be specified to use Monte Carlo instead of
exhaustive exploration of all the possible combinations.
Example2: [ ["tc", "__"], [255, "ah"], ["8c", "6h"]]
Mandatory, no default.
board : list of community cards, for games where this is meaningfull. If
specified when irrelevant, the return value cannot be predicted.
Default: []
dead : list of dead cards. These cards won't be accounted for when exloring
the possible hands.
Default: []
iterations: the maximum number of iterations when exploring the
possible outcome of a given hand. Roughly speaking, each
iteration means to distribute cards that are missing (for
which there are place holders in the board or pockets
keywords arguments, i.e. 255 or __). If the number of
iterations is not specified and there are place holders,
the return value cannot be predicted.
Default: +infinite (i.e. exhaustive exploration)
Example: object.poker_eval(game = "holdem",
pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]],
dead = [],
board = ["7h", "3s", "2c"])
The return value is a map of two entries:
'info' contains three integers:
- the number of samples (which must be equal to the number of iterations given
in argument).
- 1 if the game has a low side, 0 otherwise
- 1 if the game has a high side, 0 otherwise
'eval' is a list of as many maps as there are pocket cards, each
made of the following entries:
'scoop': the number of time these pocket cards scoop
'winhi': the number of time these pocket cards win the high side
'losehi': the number of time these pocket cards lose the high side
'tiehi': the number of time these pocket cards tie for the high side
'winlo': the number of time these pocket cards win the low side
'loselo': the number of time these pocket cards lose the low side
'tielo': the number of time these pocket cards tie for the low side
'ev': the EV of these pocket cards as an int in the range [0,1000] with
1000 being the best.
It should be clear that if there is only one sample (i.e. because all the
cards are known which is the situation that occurs at showdown) the details
provided by the 'eval' entry is mostly irrelevant and the caller might
prefer to call the winners method instead.
"""
result = _pokereval.poker_eval(*args, **kwargs)
return {
'info': result[0],
'eval': [ { 'scoop': x[0],
'winhi': x[1],
'losehi': x[2],
'tiehi': x[3],
'winlo': x[4],
'loselo': x[5],
'tielo': x[6],
'ev': int(x[7] * 1000) } for x in result[1:] ]
}
def deck(self):
"""\
Return the list of all cards in the deck.
"""
return [ self.string2card(i + j) for i in "23456789TJQKA" for j in "hdcs" ]
def nocard(self):
"""Return 255, the numerical value of a place holder in a list of cards."""
return 255
def string2card(self, cards):
"""\
Convert card names (strings) to card numbers (integers) according to the
following map:
2h/00 2d/13 2c/26 2s/39
3h/01 3d/14 3c/27 3s/40
4h/02 4d/15 4c/28 4s/41
5h/03 5d/16 5c/29 5s/42
6h/04 6d/17 6c/30 6s/43
7h/05 7d/18 7c/31 7s/44
8h/06 8d/19 8c/32 8s/45
9h/07 9d/20 9c/33 9s/46
Th/08 Td/21 Tc/34 Ts/47
Jh/09 Jd/22 Jc/35 Js/48
Qh/10 Qd/23 Qc/36 Qs/49
Kh/11 Kd/24 Kc/37 Ks/50
Ah/12 Ad/25 Ac/38 As/51
The "cards" argument may be either a list in which case a converted list
is returned or a string in which case the corresponding number is
returned.
"""
if type(cards) is ListType or type(cards) is TupleType:
return [ _pokereval.string2card(card) for card in cards ]
else:
return _pokereval.string2card(cards)
def card2string(self, cards):
"""\
Convert card numbers (integers) to card names (strings) according to the
following map:
2h/00 2d/13 2c/26 2s/39
3h/01 3d/14 3c/27 3s/40
4h/02 4d/15 4c/28 4s/41
5h/03 5d/16 5c/29 5s/42
6h/04 6d/17 6c/30 6s/43
7h/05 7d/18 7c/31 7s/44
8h/06 8d/19 8c/32 8s/45
9h/07 9d/20 9c/33 9s/46
Th/08 Td/21 Tc/34 Ts/47
Jh/09 Jd/22 Jc/35 Js/48
Qh/10 Qd/23 Qc/36 Qs/49
Kh/11 Kd/24 Kc/37 Ks/50
Ah/12 Ad/25 Ac/38 As/51
The "cards" argument may be either a list in which case a converted list
is returned or an integer in which case the corresponding string is
returned.
"""
if type(cards) is ListType or type(cards) is TupleType:
return [ _pokereval.card2string(card) for card in cards ]
else:
return _pokereval.card2string(cards)

View File

@ -0,0 +1,32 @@
{ 'boardcard1': 0,
'boardcard2': 0,
'boardcard3': 0,
'boardcard4': 0,
'boardcard5': 0,
'gametypeId': 7,
'importTime': None,
'maxSeats': 6,
'playersAtShowdown': 1,
'playersAtStreet-1': 6,
'playersAtStreet0': 1,
'playersAtStreet1': 1,
'playersAtStreet2': 1,
'playersAtStreet3': 1,
'playersAtStreet4': 0,
'playersVpi': 1,
'seats': 6,
'showdownPot': 0,
'siteHandNo': u'20000000801',
'startTime': datetime.datetime(2010, 8, 13, 19, 59, 2, tzinfo=pytz.utc),
'street0Raises': 1,
'street1Pot': 0,
'street1Raises': 0,
'street2Pot': 0,
'street2Raises': 0,
'street3Pot': 0,
'street3Raises': 0,
'street4Pot': 0,
'street4Raises': 0,
'tableName': u'Douai\u2013Lens',
'texture': None,
'tourneyId': None}

View File

@ -0,0 +1,32 @@
{ 'boardcard1': 0,
'boardcard2': 0,
'boardcard3': 0,
'boardcard4': 0,
'boardcard5': 0,
'gametypeId': 6,
'importTime': None,
'maxSeats': 9,
'playersAtShowdown': 0,
'playersAtStreet-1': 8,
'playersAtStreet0': 0,
'playersAtStreet1': 0,
'playersAtStreet2': 0,
'playersAtStreet3': 0,
'playersAtStreet4': 0,
'playersVpi': 0,
'seats': 9,
'showdownPot': 0,
'siteHandNo': u'22488827305',
'startTime': datetime.datetime(2010, 7, 21, 19, 13, tzinfo=pytz.utc),
'street0Raises': 0,
'street1Pot': 0,
'street1Raises': 0,
'street2Pot': 0,
'street2Raises': 0,
'street3Pot': 0,
'street3Raises': 0,
'street4Pot': 0,
'street4Raises': 0,
'tableName': u'Flash',
'texture': None,
'tourneyId': None}

View File

@ -0,0 +1,32 @@
{ 'boardcard1': 37,
'boardcard2': 20,
'boardcard3': 8,
'boardcard4': 51,
'boardcard5': 5,
'gametypeId': 8,
'importTime': None,
'maxSeats': 6,
'playersAtShowdown': 2,
'playersAtStreet-1': 6,
'playersAtStreet0': 4,
'playersAtStreet1': 3,
'playersAtStreet2': 3,
'playersAtStreet3': 2,
'playersAtStreet4': 0,
'playersVpi': 3,
'seats': 6,
'showdownPot': 0,
'siteHandNo': u'18932478237',
'startTime': datetime.datetime(2010, 3, 3, 16, 37, 56, tzinfo=pytz.utc),
'street0Raises': 0,
'street1Pot': 20,
'street1Raises': 1,
'street2Pot': 50,
'street2Raises': 1,
'street3Pot': 100,
'street3Raises': 1,
'street4Pot': 0,
'street4Raises': 0,
'tableName': u'Gaines',
'texture': None,
'tourneyId': None}

View File

@ -0,0 +1,32 @@
{ 'boardcard1': 0,
'boardcard2': 0,
'boardcard3': 0,
'boardcard4': 0,
'boardcard5': 0,
'gametypeId': 5,
'importTime': None,
'maxSeats': 8,
'playersAtShowdown': 1,
'playersAtStreet-1': 7,
'playersAtStreet0': 3,
'playersAtStreet1': 3,
'playersAtStreet2': 2,
'playersAtStreet3': 1,
'playersAtStreet4': 1,
'playersVpi': 3,
'seats': 7,
'showdownPot': 0,
'siteHandNo': u'26190453000',
'startTime': datetime.datetime(2010, 12, 7, 9, 10, 10, tzinfo=pytz.utc),
'street0Raises': 0,
'street1Pot': 0,
'street1Raises': 1,
'street2Pot': 0,
'street2Raises': 1,
'street3Pot': 0,
'street3Raises': 1,
'street4Pot': 0,
'street4Raises': 0,
'tableName': u'Mart',
'texture': None,
'tourneyId': None}

View File

@ -0,0 +1,658 @@
{ u'Hero': { 'card1': 18,
'card2': 25,
'card3': 42,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 3,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 1,
'sitout': False,
'startCards': 700,
'startCash': 450,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -2,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player2': { 'card1': 0,
'card2': 0,
'card3': 40,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 2,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 2,
'sitout': False,
'startCards': -12,
'startCash': 563,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -2,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player3': { 'card1': 0,
'card2': 0,
'card3': 4,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 1,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 3,
'sitout': False,
'startCards': -9,
'startCash': 760,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -2,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player4': { 'card1': 0,
'card2': 0,
'card3': 32,
'card4': 33,
'card5': 16,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': True,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': True,
'otherRaisedStreet2': True,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 0,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 4,
'sitout': False,
'startCards': -7,
'startCash': 211,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 1,
'street0Raises': 0,
'street0VPI': True,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 1,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': True,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': True,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -22,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player5': { 'card1': 0,
'card2': 0,
'card3': 51,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 'S',
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 5,
'sitout': False,
'startCards': -1,
'startCash': 818,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -5,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player7': { 'card1': 0,
'card2': 0,
'card3': 5,
'card4': 8,
'card5': 30,
'card6': 14,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': True,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': True,
'otherRaisedStreet2': True,
'otherRaisedStreet3': True,
'otherRaisedStreet4': False,
'position': 5,
'raiseFirstInChance': True,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 7,
'sitout': False,
'startCards': -8,
'startCash': 260,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 2,
'street0Raises': 0,
'street0VPI': True,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 1,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': True,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 1,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': True,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': True,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -42,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player8': { 'card1': 0,
'card2': 0,
'card3': 45,
'card4': 26,
'card5': 7,
'card6': 28,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 4,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 5,
'sawShowdown': False,
'seatNo': 8,
'sitout': False,
'startCards': -7,
'startCash': 175,
'street0Aggr': True,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': True,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': True,
'street1Bets': 1,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': True,
'street2Aggr': True,
'street2Bets': 1,
'street2CBChance': True,
'street2CBDone': True,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': True,
'street3Aggr': True,
'street3Bets': 1,
'street3CBChance': True,
'street3CBDone': True,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': True,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': 70,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 112,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 1.0,
'wonWhenSeenStreet2': 1.0,
'wonWhenSeenStreet3': 1.0,
'wonWhenSeenStreet4': 0.0}}

View File

@ -0,0 +1,32 @@
{ 'boardcard1': 0,
'boardcard2': 0,
'boardcard3': 0,
'boardcard4': 0,
'boardcard5': 0,
'gametypeId': 1,
'importTime': None,
'maxSeats': 8,
'playersAtShowdown': 1,
'playersAtStreet-1': 7,
'playersAtStreet0': 3,
'playersAtStreet1': 2,
'playersAtStreet2': 1,
'playersAtStreet3': 1,
'playersAtStreet4': 1,
'playersVpi': 2,
'seats': 8,
'showdownPot': 0,
'siteHandNo': u'26190500040',
'startTime': datetime.datetime(2010, 12, 7, 9, 19, tzinfo=pytz.utc),
'street0Raises': 0,
'street1Pot': 0,
'street1Raises': 1,
'street2Pot': 0,
'street2Raises': 1,
'street3Pot': 0,
'street3Raises': 0,
'street4Pot': 0,
'street4Raises': 0,
'tableName': u'Mart',
'texture': None,
'tourneyId': None}

View File

@ -0,0 +1,752 @@
{ u'Hero': { 'card1': 36,
'card2': 14,
'card3': 44,
'card4': 8,
'card5': 34,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': True,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': True,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 5,
'raiseFirstInChance': True,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 1,
'sitout': False,
'startCards': 395,
'startCash': 574,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 1,
'street0Raises': 0,
'street0VPI': True,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': True,
'street1Bets': 1,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': True,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': True,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -15,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player2': { 'card1': 0,
'card2': 0,
'card3': 23,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 4,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 2,
'sitout': False,
'startCards': -3,
'startCash': 650,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -2,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player3': { 'card1': 0,
'card2': 0,
'card3': 26,
'card4': 10,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': True,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': True,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 3,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 3,
'sitout': False,
'startCards': -13,
'startCash': 690,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 1,
'street0Raises': 0,
'street0VPI': True,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': True,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -5,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player4': { 'card1': 0,
'card2': 0,
'card3': 41,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 2,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 4,
'sitout': False,
'startCards': -11,
'startCash': 168,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -2,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player5': { 'card1': 0,
'card2': 0,
'card3': 6,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 1,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 5,
'sitout': False,
'startCards': -7,
'startCash': 802,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -2,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player6': { 'card1': 0,
'card2': 0,
'card3': 0,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 2,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 6,
'sitout': False,
'startCards': 0,
'startCash': 54,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': 0,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player7': { 'card1': 0,
'card2': 0,
'card3': 52,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 0,
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 7,
'sitout': False,
'startCards': -13,
'startCash': 281,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -2,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'Player8': { 'card1': 0,
'card2': 0,
'card3': 37,
'card4': 46,
'card5': 18,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': True,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 'S',
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 2,
'sawShowdown': False,
'seatNo': 8,
'sitout': False,
'startCards': -2,
'startCash': 187,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 1,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': True,
'street2Aggr': True,
'street2Bets': 1,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': True,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': 26,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 41,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 1.0,
'wonWhenSeenStreet2': 1.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0}}

View File

@ -0,0 +1,16 @@
PokerStars Game #2344646393: Hold'em Limit ($1/$2 USD) - 2005/08/15 14:27:10 ET
Table 'Phad' Seat #6 is the button
Seat 6: Hero ($40 in chips)
Seat 7: fblm2002 ($24.75 in chips)
fblm2002: posts small blind $0.50
Hero: posts big blind $1
*** HOLE CARDS ***
Dealt to Hero [3s 4s]
fblm2002: folds
Hero collected $1 from pot
*** SUMMARY ***
Total pot $1 | Rake $0
Seat 6: Hero (button) (big blind) collected ($1)
Seat 7: fblm2002 (small blind) folded before Flop

View File

@ -0,0 +1,188 @@
{ u'Hero': { 'card1': 41,
'card2': 42,
'card3': 0,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 'B',
'raiseFirstInChance': False,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 6,
'sitout': False,
'startCards': 28,
'startCash': 4000,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': 50,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 100,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0},
u'fblm2002': { 'card1': 0,
'card2': 0,
'card3': 0,
'card4': 0,
'card5': 0,
'card6': 0,
'card7': 0,
'foldBbToStealChance': False,
'foldSbToStealChance': False,
'foldToOtherRaisedStreet0': False,
'foldToOtherRaisedStreet1': False,
'foldToOtherRaisedStreet2': False,
'foldToOtherRaisedStreet3': False,
'foldToOtherRaisedStreet4': False,
'foldToStreet1CBChance': False,
'foldToStreet1CBDone': False,
'foldToStreet2CBChance': False,
'foldToStreet2CBDone': False,
'foldToStreet3CBChance': False,
'foldToStreet3CBDone': False,
'foldToStreet4CBChance': False,
'foldToStreet4CBDone': False,
'foldedBbToSteal': False,
'foldedSbToSteal': False,
'other3BStreet0': False,
'other4BStreet0': False,
'otherRaisedStreet0': False,
'otherRaisedStreet1': False,
'otherRaisedStreet2': False,
'otherRaisedStreet3': False,
'otherRaisedStreet4': False,
'position': 'S',
'raiseFirstInChance': True,
'raisedFirstIn': False,
'rake': 0,
'sawShowdown': False,
'seatNo': 7,
'sitout': False,
'startCards': 0,
'startCash': 2475,
'street0Aggr': False,
'street0Bets': 0,
'street0Calls': 0,
'street0Raises': 0,
'street0VPI': False,
'street0_3BChance': False,
'street0_3BDone': False,
'street0_4BChance': False,
'street0_4BDone': False,
'street1Aggr': False,
'street1Bets': 0,
'street1CBChance': False,
'street1CBDone': False,
'street1Calls': 0,
'street1CheckCallRaiseChance': False,
'street1CheckCallRaiseDone': False,
'street1Raises': 0,
'street1Seen': False,
'street2Aggr': False,
'street2Bets': 0,
'street2CBChance': False,
'street2CBDone': False,
'street2Calls': 0,
'street2CheckCallRaiseChance': False,
'street2CheckCallRaiseDone': False,
'street2Raises': 0,
'street2Seen': False,
'street3Aggr': False,
'street3Bets': 0,
'street3CBChance': False,
'street3CBDone': False,
'street3Calls': 0,
'street3CheckCallRaiseChance': False,
'street3CheckCallRaiseDone': False,
'street3Raises': 0,
'street3Seen': False,
'street4Aggr': False,
'street4Bets': 0,
'street4CBChance': False,
'street4CBDone': False,
'street4Calls': 0,
'street4CheckCallRaiseChance': False,
'street4CheckCallRaiseDone': False,
'street4Raises': 0,
'street4Seen': False,
'totalProfit': -50,
'tourneyTypeId': None,
'tourneysPlayersIds': None,
'winnings': 0,
'wonAtSD': 0.0,
'wonWhenSeenStreet1': 0.0,
'wonWhenSeenStreet2': 0.0,
'wonWhenSeenStreet3': 0.0,
'wonWhenSeenStreet4': 0.0}}