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

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

178
utils/pypokertest.py Normal file
View File

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