Merge branch 'master' of git://git.assembla.com/fpdboz
This commit is contained in:
commit
78fdb37f38
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
@ -296,8 +296,8 @@ class Database:
|
|||
|
||||
# vars for hand ids or dates fetched according to above config:
|
||||
self.hand_1day_ago = 0 # max hand id more than 24 hrs earlier than now
|
||||
self.date_ndays_ago = 'd00000000' # date N days ago ('d' + YYMMDD)
|
||||
self.h_date_ndays_ago = 'd00000000' # date N days ago ('d' + YYMMDD) for hero
|
||||
self.date_ndays_ago = 'd000000' # date N days ago ('d' + YYMMDD)
|
||||
self.h_date_ndays_ago = 'd000000' # date N days ago ('d' + YYMMDD) for hero
|
||||
self.date_nhands_ago = {} # dates N hands ago per player - not used yet
|
||||
|
||||
self.saveActions = False if self.import_options['saveActions'] == False else True
|
||||
|
@ -701,18 +701,18 @@ class Database:
|
|||
|
||||
d = timedelta(days=hud_days, hours=tz_day_start_offset)
|
||||
now = datetime.utcnow() - d
|
||||
self.date_ndays_ago = "d%02d%02d%02d%02d" % (now.year - 2000, now.month, now.day, tz_day_start_offset)
|
||||
self.date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day)
|
||||
|
||||
d = timedelta(days=h_hud_days, hours=tz_day_start_offset)
|
||||
now = datetime.utcnow() - d
|
||||
self.h_date_ndays_ago = "d%02d%02d%02d%02d" % (now.year - 2000, now.month, now.day, tz_day_start_offset)
|
||||
self.h_date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day)
|
||||
|
||||
def init_player_hud_stat_vars(self, playerid):
|
||||
# not sure if this is workable, to be continued ...
|
||||
try:
|
||||
# self.date_nhands_ago is used for fetching stats for last n hands (hud_style = 'H')
|
||||
# This option not used yet - needs to be called for each player :-(
|
||||
self.date_nhands_ago[str(playerid)] = 'd00000000'
|
||||
self.date_nhands_ago[str(playerid)] = 'd000000'
|
||||
|
||||
# should use aggregated version of query if appropriate
|
||||
c.execute(self.sql.query['get_date_nhands_ago'], (self.hud_hands, playerid))
|
||||
|
@ -780,11 +780,11 @@ class Database:
|
|||
if hud_style == 'T':
|
||||
stylekey = self.date_ndays_ago
|
||||
elif hud_style == 'A':
|
||||
stylekey = '000000000' # all stylekey values should be higher than this
|
||||
stylekey = '0000000' # all stylekey values should be higher than this
|
||||
elif hud_style == 'S':
|
||||
stylekey = 'zzzzzzzzz' # all stylekey values should be lower than this
|
||||
stylekey = 'zzzzzzz' # all stylekey values should be lower than this
|
||||
else:
|
||||
stylekey = '000000000'
|
||||
stylekey = '0000000'
|
||||
log.info('hud_style: %s' % hud_style)
|
||||
|
||||
#elif hud_style == 'H':
|
||||
|
@ -793,9 +793,9 @@ class Database:
|
|||
if h_hud_style == 'T':
|
||||
h_stylekey = self.h_date_ndays_ago
|
||||
elif h_hud_style == 'A':
|
||||
h_stylekey = '000000000' # all stylekey values should be higher than this
|
||||
h_stylekey = '0000000' # all stylekey values should be higher than this
|
||||
elif h_hud_style == 'S':
|
||||
h_stylekey = 'zzzzzzzzz' # all stylekey values should be lower than this
|
||||
h_stylekey = 'zzzzzzz' # all stylekey values should be lower than this
|
||||
else:
|
||||
h_stylekey = '00000000'
|
||||
log.info('h_hud_style: %s' % h_hud_style)
|
||||
|
@ -1832,12 +1832,19 @@ 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%H')
|
||||
#styleKey = "d%02d%02d%02d%02d" % (hand_start_time.year-2000, hand_start_time.month, hand_start_time.day, hand_start_time.hour)
|
||||
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 'A00000000' (all-time cache, no key) for now
|
||||
styleKey = 'A00000000'
|
||||
# hard-code styleKey as 'A000000' (all-time cache, no key) for now
|
||||
styleKey = 'A000000'
|
||||
|
||||
update_hudcache = self.sql.query['update_hudcache']
|
||||
update_hudcache = update_hudcache.replace('%s', self.sql.query['placeholder'])
|
||||
|
@ -1959,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
|
||||
|
|
|
@ -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+)?
|
||||
|
|
274
pyfpdb/GuiReplayer.py
Normal file
274
pyfpdb/GuiReplayer.py
Normal file
|
@ -0,0 +1,274 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#Copyright 2010 Maxime Grandchamp
|
||||
#This program is free software: you can redistribute it and/or modify
|
||||
#it under the terms of the GNU Affero General Public License as published by
|
||||
#the Free Software Foundation, version 3 of the License.
|
||||
#
|
||||
#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 Affero General Public License
|
||||
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#In the "official" distribution you can find the license in agpl-3.0.txt.
|
||||
|
||||
import L10n
|
||||
_ = L10n.get_translation()
|
||||
|
||||
|
||||
from Hand import *
|
||||
import Configuration
|
||||
import Database
|
||||
import SQL
|
||||
import fpdb_import
|
||||
import Filters
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk
|
||||
import math
|
||||
import gobject
|
||||
|
||||
|
||||
class GuiReplayer:
|
||||
def __init__(self, config, querylist, mainwin, debug=True):
|
||||
self.debug = debug
|
||||
self.conf = config
|
||||
self.main_window = mainwin
|
||||
self.sql = querylist
|
||||
|
||||
self.db = Database.Database(self.conf, sql=self.sql)
|
||||
|
||||
filters_display = { "Heroes" : True,
|
||||
"Sites" : True,
|
||||
"Games" : True,
|
||||
"Limits" : True,
|
||||
"LimitSep" : True,
|
||||
"LimitType" : True,
|
||||
"Type" : True,
|
||||
"Seats" : True,
|
||||
"SeatSep" : True,
|
||||
"Dates" : True,
|
||||
"Groups" : True,
|
||||
"GroupsAll" : True,
|
||||
"Button1" : True,
|
||||
"Button2" : True
|
||||
}
|
||||
|
||||
|
||||
self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
|
||||
#self.filters.registerButton1Name(_("Import Hand"))
|
||||
#self.filters.registerButton1Callback(self.importhand)
|
||||
#self.filters.registerButton2Name(_("temp"))
|
||||
#self.filters.registerButton2Callback(self.temp())
|
||||
|
||||
# hierarchy: self.mainHBox / self.hpane / self.replayBox / self.area
|
||||
|
||||
self.mainHBox = gtk.HBox(False, 0)
|
||||
self.mainHBox.show()
|
||||
|
||||
self.leftPanelBox = self.filters.get_vbox()
|
||||
|
||||
self.hpane = gtk.HPaned()
|
||||
self.hpane.pack1(self.leftPanelBox)
|
||||
self.mainHBox.add(self.hpane)
|
||||
|
||||
self.replayBox = gtk.VBox(False, 0)
|
||||
self.replayBox.show()
|
||||
|
||||
self.hpane.pack2(self.replayBox)
|
||||
self.hpane.show()
|
||||
|
||||
self.area=gtk.DrawingArea()
|
||||
self.pangolayout = self.area.create_pango_layout("")
|
||||
self.area.connect("expose-event", self.area_expose)
|
||||
self.style = self.area.get_style()
|
||||
self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
|
||||
self.area.show()
|
||||
|
||||
self.replayBox.pack_start(self.area)
|
||||
|
||||
self.MyHand = self.importhand()
|
||||
|
||||
self.maxseats=self.MyHand.maxseats
|
||||
|
||||
if self.MyHand.gametype['currency']=="USD": #TODO: check if there are others ..
|
||||
self.currency="$"
|
||||
elif self.MyHand.gametype['currency']=="EUR":
|
||||
self.currency="€"
|
||||
|
||||
|
||||
self.table={} #create table with positions, player names, status (live/folded), stacks and chips on table
|
||||
for i in range(0,self.maxseats): # radius: 200, center: 250,250
|
||||
x= int (round(250+200*math.cos(2*i*math.pi/self.maxseats)))
|
||||
y= int (round(250+200*math.sin(2*i*math.pi/self.maxseats)))
|
||||
try:
|
||||
self.table[i]={"name":self.MyHand.players[i][1],"stack":Decimal(self.MyHand.players[i][2]),"x":x,"y":y,"chips":0,"status":"live"} #save coordinates of each player
|
||||
try:
|
||||
self.table[i]['holecards']=self.MyHand.holecards["PREFLOP"][self.MyHand.players[i][1]][1]+' '+self.MyHand.holecards["PREFLOP"][self.MyHand.players[i][1]][2]
|
||||
print "holecards",self.table[i]['holecards']
|
||||
except:
|
||||
self.table[i]['holecards']=''
|
||||
except IndexError: #if seat is empty
|
||||
print "seat",i+1,"out of",self.maxseats,"empty"
|
||||
|
||||
self.actions=[] #create list with all actions
|
||||
|
||||
if isinstance(self.MyHand, HoldemOmahaHand):
|
||||
if self.MyHand.gametype['category'] == 'holdem':
|
||||
self.play_holdem()
|
||||
|
||||
self.action_number=0
|
||||
self.action_level=0
|
||||
self.pot=0
|
||||
gobject.timeout_add(1000,self.draw_action)
|
||||
|
||||
|
||||
def area_expose(self, area, event):
|
||||
self.style = self.area.get_style()
|
||||
self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
|
||||
|
||||
playerid='999' #makes sure we have an error if player is not recognised
|
||||
for i in range(0,len(self.table)): #surely there must be a better way to find the player id in the table...
|
||||
if self.table[i]['name']==self.actions[self.action_number][1]:
|
||||
playerid=i
|
||||
|
||||
if self.actions[self.action_number][2]=="folds":
|
||||
self.table[playerid]["status"]="folded"
|
||||
|
||||
if self.actions[self.action_number][3]:
|
||||
self.table[playerid]["stack"] -= Decimal(self.actions[self.action_number][3]) #decreases stack if player bets
|
||||
self.pot += Decimal(self.actions[self.action_number][3]) #increase pot
|
||||
self.table[playerid]["chips"] += Decimal(self.actions[self.action_number][3]) #increase player's chips on table
|
||||
|
||||
|
||||
cm = self.gc.get_colormap() #create colormap toi be able to play with colours
|
||||
|
||||
color = cm.alloc_color("black") #defaults to black
|
||||
self.gc.set_foreground(color)
|
||||
|
||||
self.area.window.draw_arc(self.gc, 0, 125, 125, 300, 300, 0, 360*64) #table
|
||||
|
||||
for i in self.table:
|
||||
if self.table[i]["status"]=="folded":
|
||||
color = cm.alloc_color("grey") #player has folded => greyed out
|
||||
self.gc.set_foreground(color)
|
||||
else:
|
||||
color = cm.alloc_color("black") #player is live
|
||||
self.gc.set_foreground(color)
|
||||
self.pangolayout.set_text(self.table[i]["name"]+self.table[i]["holecards"]) #player names + holecards
|
||||
self.area.window.draw_layout(self.gc, self.table[i]["x"],self.table[i]["y"], self.pangolayout)
|
||||
self.pangolayout.set_text('$'+str(self.table[i]["stack"])) #player stacks
|
||||
self.area.window.draw_layout(self.gc, self.table[i]["x"]+10,self.table[i]["y"]+20, self.pangolayout)
|
||||
|
||||
color = cm.alloc_color("green")
|
||||
self.gc.set_foreground(color)
|
||||
|
||||
self.pangolayout.set_text(self.currency+str(self.pot)) #displays pot
|
||||
self.area.window.draw_layout(self.gc,270,270, self.pangolayout)
|
||||
|
||||
if self.actions[self.action_number][0]>1: #displays flop
|
||||
self.pangolayout.set_text(self.MyHand.board['FLOP'][0]+" "+self.MyHand.board['FLOP'][1]+" "+self.MyHand.board['FLOP'][2])
|
||||
self.area.window.draw_layout(self.gc,210,240, self.pangolayout)
|
||||
if self.actions[self.action_number][0]>2: #displays turn
|
||||
self.pangolayout.set_text(self.MyHand.board['TURN'][0])
|
||||
self.area.window.draw_layout(self.gc,270,240, self.pangolayout)
|
||||
if self.actions[self.action_number][0]>3: #displays river
|
||||
self.pangolayout.set_text(self.MyHand.board['RIVER'][0])
|
||||
self.area.window.draw_layout(self.gc,290,240, self.pangolayout)
|
||||
|
||||
color = cm.alloc_color("red") #highlights the action
|
||||
self.gc.set_foreground(color)
|
||||
|
||||
self.pangolayout.set_text(self.actions[self.action_number][2]) #displays action
|
||||
self.area.window.draw_layout(self.gc, self.table[playerid]["x"]+10,self.table[playerid]["y"]+35, self.pangolayout)
|
||||
if self.actions[self.action_number][3]: #displays amount
|
||||
self.pangolayout.set_text(self.currency+self.actions[self.action_number][3])
|
||||
self.area.window.draw_layout(self.gc, self.table[playerid]["x"]+10,self.table[playerid]["y"]+55, self.pangolayout)
|
||||
|
||||
color = cm.alloc_color("black") #we don't want to draw the filters and others in red
|
||||
self.gc.set_foreground(color)
|
||||
|
||||
def play_holdem(self):
|
||||
actions=('BLINDSANTES','PREFLOP','FLOP','TURN','RIVER')
|
||||
for action in actions:
|
||||
for i in range(0,len(self.MyHand.actions[action])):
|
||||
player=self.MyHand.actions[action][i][0]
|
||||
act=self.MyHand.actions[action][i][1]
|
||||
try:
|
||||
amount=str(self.MyHand.actions[action][i][2])
|
||||
except:
|
||||
amount='' #no amount
|
||||
self.actions.append([actions.index(action),player,act,amount]) #create table with all actions
|
||||
|
||||
|
||||
def draw_action(self):
|
||||
if self.action_number==len(self.actions)-1: #no more actions, we exit the loop
|
||||
return False
|
||||
|
||||
if self.actions[self.action_number][0]!=self.action_level: #have we changed street ?
|
||||
self.action_level=self.actions[self.action_number][0] #record the new street
|
||||
if self.action_level>1: #we don't want to refresh if simply moving from antes/blinds to preflop action
|
||||
alloc = self.area.get_allocation()
|
||||
rect = gtk.gdk.Rectangle(0, 0, alloc.width, alloc.height)
|
||||
self.area.window.invalidate_rect(rect, True) #make sure we refresh the whole screen
|
||||
|
||||
self.action_number+=1
|
||||
if self.area.window:
|
||||
playerid='999' #makes sure we have an error if player is not recognised
|
||||
for i in range(0,len(self.table)): #surely there must be a better way to find the player id in the table...
|
||||
if self.table[i]['name']==self.actions[self.action_number][1]:
|
||||
playerid=i
|
||||
rect = gtk.gdk.Rectangle(self.table[playerid]["x"],self.table[playerid]["y"],100,100)
|
||||
self.area.window.invalidate_rect(rect, True) #refresh player area of the screen
|
||||
rect = gtk.gdk.Rectangle(270,270,100,50)
|
||||
self.area.window.invalidate_rect(rect, True) #refresh pot area
|
||||
self.area.window.process_updates(True)
|
||||
print "draw action",self.action_number,self.actions[self.action_number][1],self.actions[self.action_number][2],self.actions[self.action_number][3]
|
||||
return True
|
||||
|
||||
|
||||
def get_vbox(self):
|
||||
"""returns the vbox of this thread"""
|
||||
return self.mainHBox
|
||||
|
||||
def importhand(self, handnumber=1):
|
||||
"""Temporary function that grabs a Hand object from a specified file. Obviously this will
|
||||
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
|
||||
"""
|
||||
config = Configuration.Config(file = "HUD_config.test.xml")
|
||||
db = Database.Database(config)
|
||||
sql = SQL.Sql(db_server = 'sqlite')
|
||||
settings = {}
|
||||
settings.update(config.get_db_parameters())
|
||||
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
|
||||
filename="regression-test-files/cash/Stars/Flop/NLHE-FR-USD-0.01-0.02-201005.microgrind.txt"
|
||||
site="PokerStars"
|
||||
|
||||
|
||||
importer.addBulkImportImportFileOrDir(filename, site=site)
|
||||
(stored, dups, partial, errs, ttime) = importer.runImport()
|
||||
|
||||
|
||||
hhc = importer.getCachedHHC()
|
||||
handlist = hhc.getProcessedHands()
|
||||
|
||||
return handlist[0]
|
||||
|
||||
|
||||
def temp(self):
|
||||
pass
|
||||
|
|
@ -75,10 +75,6 @@ onlinehelp = {'Game':_('Type of Game'),
|
|||
class DemoTips(TreeViewTooltips):
|
||||
|
||||
def __init__(self, customer_column):
|
||||
# customer_column is an instance of gtk.TreeViewColumn and
|
||||
# is being used in the gtk.TreeView to show customer names.
|
||||
# self.cust_col = customer_column
|
||||
|
||||
# call base class init
|
||||
TreeViewTooltips.__init__(self)
|
||||
|
||||
|
@ -91,11 +87,6 @@ class DemoTips(TreeViewTooltips):
|
|||
return (display)
|
||||
|
||||
def location(self, x, y, w, h):
|
||||
# rename me to "location" so I override the base class
|
||||
# method. This will demonstrate being able to change
|
||||
# where the tooltip window popups, relative to the
|
||||
# pointer.
|
||||
|
||||
# this will place the tooltip above and to the right
|
||||
return x + 30, y - (h + 10)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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 """
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
|
@ -1064,7 +1064,7 @@ class Sql:
|
|||
activeSeats SMALLINT NOT NULL,
|
||||
position CHAR(1),
|
||||
tourneyTypeId SMALLINT UNSIGNED, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
|
||||
styleKey CHAR(9) NOT NULL, /* 1st char is style (A/T/H/S), other 8 are the key */
|
||||
styleKey CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
|
||||
HDs INT NOT NULL,
|
||||
|
||||
wonWhenSeenStreet1 FLOAT,
|
||||
|
@ -1165,7 +1165,7 @@ class Sql:
|
|||
activeSeats SMALLINT,
|
||||
position CHAR(1),
|
||||
tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
|
||||
styleKey CHAR(9) NOT NULL, /* 1st char is style (A/T/H/S), other 8 are the key */
|
||||
styleKey CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
|
||||
HDs INT,
|
||||
|
||||
wonWhenSeenStreet1 FLOAT,
|
||||
|
@ -2047,7 +2047,7 @@ class Sql:
|
|||
# gets a date, would need to use handsplayers (not hudcache) to get exact hand Id
|
||||
if db_server == 'mysql':
|
||||
self.query['get_date_nhands_ago'] = """
|
||||
select concat( 'd', date_format(max(h.startTime), '%Y%m%d%H') )
|
||||
select concat( 'd', date_format(max(h.startTime), '%Y%m%d') )
|
||||
from (select hp.playerId
|
||||
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
|
||||
from HandsPlayers hp
|
||||
|
@ -2059,7 +2059,7 @@ class Sql:
|
|||
"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['get_date_nhands_ago'] = """
|
||||
select 'd' || to_char(max(h3.startTime), 'YYMMDDHH')
|
||||
select 'd' || to_char(max(h3.startTime), 'YYMMDD')
|
||||
from (select hp.playerId
|
||||
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
|
||||
from HandsPlayers hp
|
||||
|
@ -2071,7 +2071,7 @@ class Sql:
|
|||
"""
|
||||
elif db_server == 'sqlite': # untested guess at query:
|
||||
self.query['get_date_nhands_ago'] = """
|
||||
select 'd' || strftime(max(h3.startTime), 'YYMMDDHH')
|
||||
select 'd' || strftime(max(h3.startTime), 'YYMMDD')
|
||||
from (select hp.playerId
|
||||
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
|
||||
from HandsPlayers hp
|
||||
|
@ -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
|
||||
|
@ -3290,7 +3302,7 @@ class Sql:
|
|||
else 'E'
|
||||
end AS hc_position
|
||||
<tourney_select_clause>
|
||||
,date_format(h.startTime, 'd%y%m%d%H')
|
||||
,date_format(h.startTime, 'd%y%m%d')
|
||||
,count(1)
|
||||
,sum(wonWhenSeenStreet1)
|
||||
,sum(wonWhenSeenStreet2)
|
||||
|
@ -3379,7 +3391,7 @@ class Sql:
|
|||
,h.seats
|
||||
,hc_position
|
||||
<tourney_group_clause>
|
||||
,date_format(h.startTime, 'd%y%m%d%H')
|
||||
,date_format(h.startTime, 'd%y%m%d')
|
||||
"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['rebuildHudCache'] = """
|
||||
|
@ -3488,7 +3500,7 @@ class Sql:
|
|||
else 'E'
|
||||
end AS hc_position
|
||||
<tourney_select_clause>
|
||||
,'d' || to_char(h.startTime, 'YYMMDDHH')
|
||||
,'d' || to_char(h.startTime, 'YYMMDD')
|
||||
,count(1)
|
||||
,sum(wonWhenSeenStreet1)
|
||||
,sum(wonWhenSeenStreet2)
|
||||
|
@ -3577,7 +3589,7 @@ class Sql:
|
|||
,h.seats
|
||||
,hc_position
|
||||
<tourney_group_clause>
|
||||
,to_char(h.startTime, 'YYMMDDHH')
|
||||
,to_char(h.startTime, 'YYMMDD')
|
||||
"""
|
||||
else: # assume sqlite
|
||||
self.query['rebuildHudCache'] = """
|
||||
|
@ -3686,7 +3698,7 @@ class Sql:
|
|||
else 'E'
|
||||
end AS hc_position
|
||||
<tourney_select_clause>
|
||||
,'d' || substr(strftime('%Y%m%d%H', h.startTime),3,9)
|
||||
,'d' || substr(strftime('%Y%m%d', h.startTime),3,7)
|
||||
,count(1)
|
||||
,sum(wonWhenSeenStreet1)
|
||||
,sum(wonWhenSeenStreet2)
|
||||
|
@ -3775,7 +3787,7 @@ class Sql:
|
|||
,h.seats
|
||||
,hc_position
|
||||
<tourney_group_clause>
|
||||
,'d' || substr(strftime('%Y%m%d%H', h.startTime),3,9)
|
||||
,'d' || substr(strftime('%Y%m%d', h.startTime),3,7)
|
||||
"""
|
||||
|
||||
self.query['insert_hudcache'] = """
|
||||
|
@ -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)
|
||||
|
|
|
@ -27,7 +27,7 @@ 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
|
||||
|
@ -58,7 +58,7 @@ class Stove:
|
|||
|
||||
def set_villain_range_string(self, string):
|
||||
# Villain's range
|
||||
range = Range()
|
||||
h_range = Range()
|
||||
hands_in_range = string.strip().split(',')
|
||||
for h in hands_in_range:
|
||||
_h = h.strip()
|
||||
|
@ -67,11 +67,11 @@ class Stove:
|
|||
r1 = cc[0]
|
||||
r2 = cc[1]
|
||||
vp = Cards(r1, r2)
|
||||
range.add(vp)
|
||||
h_range.add(vp)
|
||||
else:
|
||||
range.expand(expand_hands(_h, pocket_cards, board))
|
||||
h_range.expand(expand_hands(_h, self.hand, self.board))
|
||||
|
||||
self.range = range
|
||||
self.h_range = h_range
|
||||
|
||||
|
||||
class Cards:
|
||||
|
@ -147,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.
|
||||
|
@ -202,7 +182,7 @@ def expand_hands(abbrev, hand, board):
|
|||
else:
|
||||
selection = ANY
|
||||
|
||||
range = []
|
||||
h_range = []
|
||||
considered = set()
|
||||
for s1 in SUITS:
|
||||
c1 = r1 + s1
|
||||
|
@ -216,8 +196,8 @@ 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):
|
||||
|
@ -229,7 +209,6 @@ def parse_args(args, container):
|
|||
container.set_hero_cards_string(args[2])
|
||||
container.set_villain_range_string(args[3])
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
@ -281,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],
|
||||
|
@ -290,7 +269,28 @@ 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.
|
||||
|
||||
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()
|
||||
|
|
|
@ -116,6 +116,7 @@ import GuiAutoImport
|
|||
import GuiGraphViewer
|
||||
import GuiTourneyGraphViewer
|
||||
import GuiSessionViewer
|
||||
import GuiReplayer
|
||||
import GuiStove
|
||||
import SQL
|
||||
import Database
|
||||
|
@ -779,6 +780,7 @@ class fpdb:
|
|||
<menuitem action="tourneyviewer"/>
|
||||
<menuitem action="posnstats"/>
|
||||
<menuitem action="sessionstats"/>
|
||||
<menuitem action="replayer"/>
|
||||
<menuitem action="stove"/>
|
||||
</menu>
|
||||
<menu action="database">
|
||||
|
@ -822,6 +824,7 @@ class fpdb:
|
|||
('tourneyviewer', None, _('Tourney _Viewer'), None, 'Tourney Viewer)', self.tab_tourney_viewer_stats),
|
||||
('posnstats', None, _('P_ositional Stats (tabulated view, not on sqlite)'), _('<control>O'), 'Positional Stats (tabulated view, not on sqlite)', self.tab_positional_stats),
|
||||
('sessionstats', None, _('Session Stats'), None, 'Session Stats', self.tab_session_stats),
|
||||
('replayer', None, _('Hand _Replayer'), None, 'Hand Replayer', self.tab_replayer),
|
||||
('database', None, _('_Database')),
|
||||
('maintaindbs', None, _('_Maintain Databases'), None, 'Maintain Databases', self.dia_maintain_dbs),
|
||||
('createtabs', None, _('Create or Recreate _Tables'), None, 'Create or Recreate Tables ', self.dia_recreate_tables),
|
||||
|
@ -1046,6 +1049,12 @@ class fpdb:
|
|||
ps_tab=new_ps_thread.get_vbox()
|
||||
self.add_and_display_tab(ps_tab, _("Session Stats"))
|
||||
|
||||
def tab_replayer(self, widget, data=None):
|
||||
new_ps_thread = GuiReplayer.GuiReplayer(self.config, self.sql, self.window)
|
||||
self.threads.append(new_ps_thread)
|
||||
ps_tab=new_ps_thread.get_vbox()
|
||||
self.add_and_display_tab(ps_tab, _("Hand Replayer"))
|
||||
|
||||
def tab_main_help(self, widget, data=None):
|
||||
"""Displays a tab with the main fpdb help screen"""
|
||||
mh_tab=gtk.Label(_("""Fpdb needs translators!
|
||||
|
|
24
pyfpdb/fpdb_import.py
Executable file → Normal file
24
pyfpdb/fpdb_import.py
Executable file → Normal 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')
|
||||
|
|
|
@ -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
|
|
@ -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
178
utils/pypokertest.py
Normal 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
|
Loading…
Reference in New Issue
Block a user