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

This commit is contained in:
Eratosthenes 2011-02-08 18:34:17 -05:00
commit df43e0e6b8
21 changed files with 219 additions and 126 deletions

View File

@ -1514,6 +1514,7 @@ class Database:
c.execute("INSERT INTO Sites (name,code) VALUES ('PKR', 'PK')")
c.execute("INSERT INTO Sites (name,code) VALUES ('iPoker', 'IP')")
c.execute("INSERT INTO Sites (name,code) VALUES ('Winamax', 'WM')")
c.execute("INSERT INTO Sites (name,code) VALUES ('Everest', 'EP')")
#Fill Actions
c.execute("INSERT INTO Actions (name,code) VALUES ('ante', 'A')")
c.execute("INSERT INTO Actions (name,code) VALUES ('small blind', 'SB')")

View File

@ -420,12 +420,15 @@ class Filters(threading.Thread):
self.limits[limit] = w.get_active()
log.debug(_("self.limit[%s] set to %s") %(limit, self.limits[limit]))
if limit.isdigit() or (len(limit) > 2 and (limit[-2:] == 'nl' or limit[-2:] == 'fl' or limit[-2:] == 'pl')):
# turning a leaf limit on with 'None' checked turns 'None' off
if self.limits[limit]:
if self.cbNoLimits is not None:
self.cbNoLimits.set_active(False)
# turning a leaf limit off with 'All' checked turns 'All' off
else:
if self.cbAllLimits is not None:
self.cbAllLimits.set_active(False)
# turning off a leaf limit turns off the corresponding fl. nl, or pl
if not self.limits[limit]:
if limit.isdigit():
if self.cbFL is not None:
@ -438,24 +441,28 @@ class Filters(threading.Thread):
self.cbPL.set_active(False)
elif limit == "all":
if self.limits[limit]:
#for cb in self.cbLimits.values():
# cb.set_active(True)
if self.cbFL is not None:
self.cbFL.set_active(True)
if self.cbNL is not None:
self.cbNL.set_active(True)
if self.cbPL is not None:
self.cbPL.set_active(True)
if self.num_limit_types == 1:
for cb in self.cbLimits.values():
cb.set_active(True)
else:
if self.cbFL is not None:
self.cbFL.set_active(True)
if self.cbNL is not None:
self.cbNL.set_active(True)
if self.cbPL is not None:
self.cbPL.set_active(True)
elif limit == "none":
if self.limits[limit]:
for cb in self.cbLimits.values():
cb.set_active(False)
if self.cbNL is not None:
self.cbNL.set_active(False)
if self.cbFL is not None:
self.cbFL.set_active(False)
if self.cbPL is not None:
self.cbPL.set_active(False)
if self.num_limit_types == 1:
for cb in self.cbLimits.values():
cb.set_active(False)
else:
if self.cbNL is not None:
self.cbNL.set_active(False)
if self.cbFL is not None:
self.cbFL.set_active(False)
if self.cbPL is not None:
self.cbPL.set_active(False)
elif limit == "fl":
if not self.limits[limit]:
# only toggle all fl limits off if they are all currently on
@ -765,11 +772,11 @@ class Filters(threading.Thread):
dest = vbox3 # for ring/tour buttons
if "LimitType" in display and display["LimitType"] == True:
num_limit_types = 0
if self.found['fl']: num_limit_types = num_limit_types + 1
if self.found['pl']: num_limit_types = num_limit_types + 1
if self.found['nl']: num_limit_types = num_limit_types + 1
if num_limit_types > 1:
self.num_limit_types = 0
if self.found['fl']: self.num_limit_types = self.num_limit_types + 1
if self.found['pl']: self.num_limit_types = self.num_limit_types + 1
if self.found['nl']: self.num_limit_types = self.num_limit_types + 1
if self.num_limit_types > 1:
if self.found['fl']:
hbox = gtk.HBox(False, 0)
vbox3.pack_start(hbox, False, False, 0)

View File

@ -49,6 +49,7 @@ class Fulltilt(HandHistoryConverter):
'6.00': ('1.00', '3.00'), '6': ('1.00', '3.00'),
'8.00': ('2.00', '4.00'), '8': ('2.00', '4.00'),
'10.00': ('2.00', '5.00'), '10': ('2.00', '5.00'),
'16.00': ('4.00', '8.00'), '16': ('4.00', '8.00'),
'20.00': ('5.00', '10.00'), '20': ('5.00', '10.00'),
'30.00': ('10.00', '15.00'), '30': ('10.00', '15.00'),
'40.00': ('10.00', '20.00'), '40': ('10.00', '20.00'),
@ -88,7 +89,7 @@ class Fulltilt(HandHistoryConverter):
[%(LS)s]?(?P<CAP>[.0-9]+\sCap\s)?
(?P<GAMETYPE>[-\da-zA-Z\/\'\s]+)\s-\s
(?P<DATETIME>.*$)
(?P<PARTIAL>\(partial\))?\n
(?P<PARTIAL>\(partial\))?\s
(?:.*?\n(?P<CANCELLED>Hand\s\#(?P=HID)\shas\sbeen\scanceled))?
''' % substitutions, re.MULTILINE|re.VERBOSE)
re_TourneyExtraInfo = re.compile('''(((?P<TOURNEY_NAME>[^$]+)?
@ -147,7 +148,7 @@ class Fulltilt(HandHistoryConverter):
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)
# 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)
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}))(?P<PARTIAL>\s\(partial\))?""", re.MULTILINE)
@ -283,10 +284,13 @@ class Fulltilt(HandHistoryConverter):
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")
if a.group('PARTIAL'):
raise FpdbParseError(hid=m.group('HID'))
hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, timezone, "UTC")
if m.group("CANCELLED") or m.group("PARTIAL"):
# It would appear this can't be triggered as DATETIME is a bit greedy
raise FpdbParseError(hid=m.group('HID'))
if m.group('TABLEATTRIBUTES'):
@ -351,7 +355,7 @@ class Fulltilt(HandHistoryConverter):
n = self.re_SummarySitout.finditer(post)
for b in n:
del plist[b.group('PNAME')]
print "DEBUG: Deleting '%s' from player dict" %(b.group('PNAME'))
#print "DEBUG: Deleting '%s' from player dict" %(b.group('PNAME'))
# Add remaining players
for a in plist:

View File

@ -15,6 +15,9 @@
#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()
import threading
import pygtk
pygtk.require('2.0')
@ -22,18 +25,6 @@ import gtk
import os
from time import time, strftime
import locale
lang=locale.getdefaultlocale()[0][0:2]
if lang=="en":
def _(string): return string
else:
import gettext
try:
trans = gettext.translation("fpdb", localedir="locale", languages=[lang])
trans.install()
except IOError:
def _(string): return string
import fpdb_import
import Database
import Filters

View File

@ -15,6 +15,9 @@
#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()
import xml.dom.minidom
from xml.dom.minidom import Node
@ -23,18 +26,6 @@ pygtk.require('2.0')
import gtk
import gobject
import locale
lang=locale.getdefaultlocale()[0][0:2]
if lang=="en":
def _(string): return string
else:
import gettext
try:
trans = gettext.translation("fpdb", localedir="locale", languages=[lang])
trans.install()
except IOError:
def _(string): return string
import Configuration
rewrite = { 'general' : 'General', 'supported_databases' : 'Databases'

View File

@ -339,7 +339,7 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
#end def createStatsTable
def reset_style_render_func(self, treeviewcolumn, cell, model, iter):
cell.set_property('foreground', 'black')
cell.set_property('foreground', None)
#end def reset_style_render_func
def ledger_style_render_func(self, tvcol, cell, model, iter):

View File

@ -434,7 +434,7 @@ class GuiTourneyPlayerStats (GuiPlayerStats.GuiPlayerStats):
#end def refreshStats
def reset_style_render_func(self, treeviewcolumn, cell, model, iter):
cell.set_property('foreground', 'black')
cell.set_property('foreground', None)
#end def reset_style_render_func
def sortCols(self, col, nums):

View File

@ -23,6 +23,9 @@
Main for FreePokerTools HUD.
"""
import L10n
_ = L10n.get_translation()
# Standard Library modules
import sys
import os
@ -51,21 +54,6 @@ elif sys.platform == 'darwin':
else: # This is bad--figure out the values for the various windows flavors
import WinTables as Tables
import locale
lang = locale.getdefaultlocale()[0][0:2]
print "lang:", lang
if lang == "en":
def _(string):
return string
else:
import gettext
try:
trans = gettext.translation("fpdb", localedir="locale", languages=[lang])
trans.install()
except IOError:
def _(string):
return string
# get config and set up logger
c = Configuration.Config(file=options.config, dbname=options.dbname)
log = Configuration.get_logger("logging.conf", "hud", log_dir=c.dir_log, log_file='HUD-log.txt')

View File

@ -1140,7 +1140,7 @@ class DrawHand(Hand):
hhc.markStreets(self)
# markStreets in Draw may match without dealing cards
if self.streets['DEAL'] == None:
raise FpdbParseError(_("DrawHand.__init__: street 'DEAL' is empty. Hand cancelled?"))
raise FpdbParseError(_("DrawHand.__init__: street 'DEAL' is empty. Hand cancelled? '%s'" % self.handid))
hhc.readBlinds(self)
hhc.readAntes(self)
hhc.readButton(self)

View File

@ -49,7 +49,7 @@ class OnGame(HandHistoryConverter):
}
currencies = { u'\u20ac':'EUR', u'\xe2\x82\xac':'EUR', '$':'USD', '':'T$' }
limits = { 'NO_LIMIT':'nl', 'LIMIT':'fl'}
limits = { 'NO_LIMIT':'nl', 'POT_LIMIT':'pl', 'LIMIT':'fl'}
games = { # base, category
"TEXAS_HOLDEM" : ('hold','holdem'),
@ -73,7 +73,7 @@ class OnGame(HandHistoryConverter):
Start\shand:\s(?P<DATETIME>.*)
Table:\s(?P<TABLE>[-\'\w\s]+)\s\[\d+\]\s\(
(
(?P<LIMIT>NO_LIMIT|Limit|LIMIT|Pot\sLimit)\s
(?P<LIMIT>NO_LIMIT|Limit|LIMIT|Pot\sLimit|POT_LIMIT)\s
(?P<GAME>TEXAS_HOLDEM|OMAHA_HI|SEVEN_CARD_STUD|SEVEN_CARD_STUD_HI_LO|RAZZ|FIVE_CARD_DRAW)\s
(?P<CURRENCY>%(LS)s|)?(?P<SB>[.0-9]+)/
(%(LS)s)?(?P<BB>[.0-9]+)
@ -140,6 +140,7 @@ class OnGame(HandHistoryConverter):
def readSupportedGames(self):
return [
["ring", "hold", "fl"],
["ring", "hold", "pl"],
["ring", "hold", "nl"],
["ring", "stud", "fl"],
["ring", "draw", "fl"],
@ -158,6 +159,7 @@ class OnGame(HandHistoryConverter):
raise FpdbParseError(_("Unable to recognise gametype from: '%s'") % tmp)
mg = m.groupdict()
#print "DEBUG: mg: %s" % mg
info['type'] = 'ring'
if 'CURRENCY' in mg:
@ -314,9 +316,9 @@ class OnGame(HandHistoryConverter):
m = self.re_Action.finditer(hand.streets[street])
for action in m:
#acts = action.groupdict()
#log.debug("readaction: acts: %s" %acts)
#print "readaction: acts: %s" %acts
if action.group('ATYPE') == ' raises':
hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') )
hand.addRaiseTo( street, action.group('PNAME'), action.group('BET') )
elif action.group('ATYPE') == ' calls':
hand.addCall( street, action.group('PNAME'), action.group('BET') )
elif action.group('ATYPE') == ' bets':

View File

@ -49,7 +49,8 @@ class PartyPoker(HandHistoryConverter):
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)
'LS' : u"\$|\u20ac|\xe2\x82\xac|", # Currency symbols - Euro(cp1252, utf-8)
'NUM' : u".,\d",
}
# Static regexes
@ -81,7 +82,7 @@ class PartyPoker(HandHistoryConverter):
re_PlayerInfo = re.compile(u"""
Seat\s(?P<SEAT>\d+):\s
(?P<PNAME>.*)\s
\(\s*[%(LS)s]?(?P<CASH>[0-9,.]+)\s*(?:%(LEGAL_ISO)s|)\s*\)
\(\s*[%(LS)s]?(?P<CASH>[%(NUM)s]+)\s*(?:%(LEGAL_ISO)s|)\s*\)
""" % substitutions, re.VERBOSE| re.UNICODE)
re_HandInfo = re.compile("""

View File

@ -84,8 +84,8 @@ class PokerStars(HandHistoryConverter):
# Static regexes
re_GameInfo = re.compile(u"""
PokerStars\sGame\s\#(?P<HID>[0-9]+):\s+
(Tournament\s\# # open paren of tournament info
PokerStars(\sHome)?\sGame\s\#(?P<HID>[0-9]+):\s+
(\{.*\}\s+)?(Tournament\s\# # open paren of tournament info
(?P<TOURNO>\d+),\s
# here's how I plan to use LS
(?P<BUYIN>(?P<BIAMT>[%(LS)s\d\.]+)?\+?(?P<BIRAKE>[%(LS)s\d\.]+)?\+?(?P<BOUNTY>[%(LS)s\d\.]+)?\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)?|Freeroll)\s+)?

View File

@ -109,9 +109,9 @@ class RushNotes(Aux_Window):
notepath = site_params_dict['site_path'] # this is a temporary hijack of site-path
self.heroid = self.hud.db_connection.get_player_id(self.config, sitename, heroname)
self.notefile = notepath + "/" + heroname + ".xml"
self.rushtables = ("Mach 10", "Lightning", "Celerity", "Flash", "Zoom")
self.rushtables = ("Mach 10", "Lightning", "Celerity", "Flash", "Zoom", "Apollo")
if not os.path.isfile(self.notefile):
if not (os.path.isfile(self.notefile)):
self.active = False
return
else:
@ -130,29 +130,34 @@ class RushNotes(Aux_Window):
xmlnotefile.unlink
#
# Create a fresh queue file with skeleton XML
# if queue file does not exist create a fresh queue file with skeleton XML
# This is possibly not totally safe, if multiple threads arrive
# here at the same time, but the consequences are not serious
#
self.queuefile = self.notefile + ".queue"
queuedom = minidom.Document()
if not (os.path.isfile(self.queuefile)):
pld=queuedom.createElement("PLAYERDATA")
queuedom.appendChild(pld)
queuedom = minidom.Document()
nts=queuedom.createElement("NOTES")
pld.appendChild(nts)
pld=queuedom.createElement("PLAYERDATA")
queuedom.appendChild(pld)
nte = queuedom.createElement("NOTE")
nte = queuedom.createTextNode("\n")
nts.insertBefore(nte,None)
nts=queuedom.createElement("NOTES")
pld.appendChild(nts)
outputfile = open(self.queuefile, 'w')
queuedom.writexml(outputfile)
outputfile.close()
queuedom.unlink
nte = queuedom.createElement("NOTE")
nte = queuedom.createTextNode("\n")
nts.insertBefore(nte,None)
outputfile = open(self.queuefile, 'w')
queuedom.writexml(outputfile)
outputfile.close()
queuedom.unlink
if (debugmode):
#initialise logfiles
debugfile=open("~Rushdebug.init", "w")
debugfile=open("~Rushdebug.init", "a")
debugfile.write("conf="+str(config)+"\n")
debugfile.write("spdi="+str(site_params_dict)+"\n")
debugfile.write("para="+str(params)+"\n")
@ -161,8 +166,6 @@ class RushNotes(Aux_Window):
debugfile.write("queu="+self.queuefile+"\n")
debugfile.close()
open("~Rushdebug.data", "w").close()
def update_data(self, new_hand_id, db_connection):
#this method called once for every hand processed
@ -204,16 +207,19 @@ class RushNotes(Aux_Window):
vpip=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'vpip')[3] + " ")
pfr=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'pfr')[3] + " ")
three_B=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'three_B')[3] + " ")
four_B=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'four_B')[3] + " ")
cbet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'cbet')[3] + " ")
fbbsteal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'f_BB_steal')[3] + " ")
f_3bet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'f_3bet')[3] + " ")
f_4bet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'f_4bet')[3] + " ")
steal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'steal')[3] + " ")
ffreq1=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'ffreq1')[3] + " ")
agg_freq=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'agg_freq')[3] + " ")
BBper100=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'BBper100')[3])
if BBper100[6] == "-": BBper100=BBper100[0:6] + "(" + BBper100[7:] + ")"
#
# grab villain known starting hands
# only those where they VPIP'd, so limp in the BB will not be shown
@ -269,10 +275,13 @@ class RushNotes(Aux_Window):
# for later search/replace by Merge module
#
xmlqueuedict[playername] = ("~fpdb~" + "\n" +
n + vpip + pfr + three_B + fbbsteal + "\n" +
steal + cbet + ffreq1 + "\n" +
n + vpip + pfr + "\n" +
steal + cbet + fbbsteal + ffreq1 + "\n" +
three_B + four_B + f_3bet + f_4bet + "\n" +
agg_freq + BBper100 + "\n" +
PFcall+"\n"+PFaggr+"\n"+PFdefend +"\n"
PFcall+"\n"+
PFaggr+"\n"+
PFdefend +"\n"+
"~ends~")
if (debugmode):

View File

@ -105,8 +105,6 @@ if not os.path.isfile(sys.argv[1]):
if not os.path.isfile((sys.argv[1]+".queue")):
print "Nothing found to merge, quitting"
print "Did the HUD not get started during the last session?"
print "Has the HUD been stopped and started without merging?"
quit()
print "***************************************************************"
@ -117,7 +115,7 @@ print "has stopped completely"
print "***************************************************************"
print
print "read from: ", sys.argv[1]
print "merge with: ", sys.argv[1]+".queue"
print "updated with: ", sys.argv[1]+".queue"
#read queue and turn into a dict
queuedict = {}
@ -172,7 +170,7 @@ mergednotes.close()
xmlnotefile.unlink
print "Merged file has been written to: ", sys.argv[1]+".merged"
print "written to: ", sys.argv[1]+".merged"
print ""
print "number in queue: ", statqueue
print "existing players updated: ", statupdated
@ -180,5 +178,7 @@ print "new players added: ", statadded
print "\n"
print "Use a viewer to check the contents of the merge file."
print "If you are happy, carry out the following steps:"
print "1 Rename or delete the existing notes file (normally <heroname>.xml"
print "1 Rename or delete the existing notes file (normally <heroname>.xml)"
print "2 Rename the .merged file to become the new notes file"
print "3 Delete the .queue file (it will be created at the next rush autoimport)"

View File

@ -15,11 +15,6 @@ Important info:
The Merge process can only be run when ftp client is shutdown
- otherwise ftp overwrites the xml on exit.
Restarting the autoimport will empty the notes"queue" so avoid restarting
autoimport until the previous notes "queue" has been merged. You will
lose all the queued notes, but these will be regenerated the next time
the villian is at your table, so it isn't the end of the world.
Existing ftp notes _SHOULD_ be preserved, but this isn't guaranteed,
you have been warned!
@ -27,7 +22,8 @@ Existing colour codings should be preserved,
this process does not change or set colourcodings.
Copies of the live ftp notes file should be preserved everytime
RushNotesAux (i.e. the HUD is started)
RushNotesAux (i.e. the HUD is started). If you play at different
rush tables, the backup will be created several times.
The AW is hard-coded with just the table names of Micro Rush Poker,
and should ignore all other hands.
@ -35,7 +31,7 @@ The AW is hard-coded with just the table names of Micro Rush Poker,
What might not work?
--------------------
This isn't tested with Windows, and probably won't work, feedback welcome.
This should work with windows sourcecode version, but will not work with the exe download.
Hasn't been tested for co-existance with other sites, feedback welcome.
Whenever FTP change their notes file format, this will all break rather spectacularly,
you have been warned!
@ -77,7 +73,7 @@ execute the following:
./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myname.xml"
A revised notes file (blah.merge) should automagically appear in the full tilt root directory.
If you are happy with it, replace the existing (myname.xml file)
If you are happy with it, replace the existing (myname.xml file) and delete the .queue file.
Since the updates aren't real time, it would be ok to play the rush
@ -176,7 +172,7 @@ Process overview
----------------
1/ The HUD process is started.
1.1/ when the first hand is received, h fresh holding file is created, and
1.1/ when the first hand is received, a queue file is created if not already there, and
a copy of the current live xml note file is created as a security backup.
2/ For every hand played, the auxillary window is called
3/ Based upon the players in the hand, fpdb will be interrogated
@ -191,4 +187,4 @@ existing notes, but this cannot be guaranteed.
they replace the existing note file.
9/ Note that this process never updates the live notes file in situ, but
there is a risk that something goes wrong, and that existing notes could be destroyed.
10/ the queue file can be deleted to reduce re-processing next time.

View File

@ -2294,7 +2294,7 @@ class Sql:
end AS pofafq
,case when sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)) = 0 then -999
else (sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
/(sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
/(0.0+sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
end AS aggfac
,100.0*(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
/ ((sum(cast(hp.foldToOtherRaisedStreet1 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet2 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet3 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet4 as <signed>integer))) +
@ -2415,7 +2415,7 @@ class Sql:
end AS pofafq
,case when sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)) = 0 then -999
else (sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
/(sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
/(0.0+sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
end AS aggfac
,100.0*(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
/ ((sum(cast(hp.foldToOtherRaisedStreet1 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet2 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet3 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet4 as <signed>integer))) +
@ -2537,7 +2537,7 @@ class Sql:
end AS pofafq
,case when sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)) = 0 then -999
else (sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
/(sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
/(0.0+sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer)))
end AS aggfac
,100.0*(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer)))
/ ((sum(cast(hp.foldToOtherRaisedStreet1 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet2 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet3 as <signed>integer))+ sum(cast(hp.foldToOtherRaisedStreet4 as <signed>integer))) +

View File

@ -15,10 +15,13 @@ import L10n
_ = L10n.get_translation()
import sys, random
import re
import pokereval
SUITS = ['h', 'd', 's', 'c']
CONNECTORS = ['32', '43', '54', '65', '76', '87', '98', 'T9', 'JT', 'QJ', 'KQ', 'AK']
ANY = 0
SUITED = 1
OFFSUIT = 2
@ -65,14 +68,7 @@ class Stove:
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))
h_range.expand(expand_hands(_h, self.hand, self.board))
self.h_range = h_range
@ -83,7 +79,7 @@ class Cards:
self.c2 = c2
def get(self):
return [c1, c2]
return [self.c1, self.c2]
class Board:
def __init__(self, b1=None, b2=None, b3=None, b4=None, b5=None):
@ -127,7 +123,7 @@ class Range:
def get(self):
return sorted(self.__hands)
class EV:
def __init__(self, plays, win, tie, lose):
@ -175,6 +171,35 @@ def expand_hands(abbrev, hand, board):
known_cards.update(set([hand.c2, hand.c2]))
known_cards.update(set([board.b1, board.b2, board.b3, board.b4, board.b5]))
re.search('[2-9TJQKA]{2}(s|o)',abbrev)
if re.search('^[2-9TJQKA]{2}(s|o)$',abbrev): #AKs or AKo
return standard_expand(abbrev, hand, known_cards)
elif re.search('^[2-9TJQKA]{2}(s|o)\+$',abbrev): #76s+ or 76o+
return iterative_expand(abbrev, hand, known_cards)
#elif: AhXh
#elif: Ah6h+A
def iterative_expand(abbrev, hand, known_cards):
r1 = abbrev[0]
r2 = abbrev[1]
h_range = []
considered = set()
idx = CONNECTORS.index('%s%s' % (r1, r2))
ltr = abbrev[2]
h_range = []
for h in CONNECTORS[idx:]:
abr = "%s%s" % (h, ltr)
h_range += standard_expand(abr, hand, known_cards)
return h_range
def standard_expand(abbrev, hand, known_cards):
# Card ranks may be different
r1 = abbrev[0]
r2 = abbrev[1]
@ -228,7 +253,7 @@ def odds_for_hand(hand1, hand2, board, iterations):
board = board,
iterations = iterations
)
plays = int(res['info'][0])
eval = res['eval'][0]

View File

@ -0,0 +1,44 @@
***** History for hand R5-21973400-50 *****
Start hand: Mon Feb 7 15:22:00 GMT+0100 2011
Table: Oullins [21973414] (POT_LIMIT OMAHA_HI €1/€1, Real money)
User: Hero
Button: seat 7
Players in round: 6
Seat 8: Player8 (€89)
Seat 10: Hero (€100)
Seat 2: Player2 (€50)
Seat 3: Player3 (€93.50)
Seat 5: Player5 (€86.15)
Seat 7: Player7 (€149.40)
Player8 posts small blind (€0.50)
Hero posts big blind (€1)
---
Dealing pocket cards
Dealing to Hero: [3c, 7c, 4c, 5h]
Player2 calls €1
Player3 raises €4.50 to €4.50
Player5 folds
Player7 calls €4.50
Player8 calls €4
Hero calls €3.50
Player2 folds
--- Dealing flop [7s, 4d, 3h]
Player8 checks
Hero bets €12
Player3 calls €12
Player7 folds
Player8 folds
--- Dealing turn [6d]
Hero bets €21.50
Player3 folds
---
Summary:
Main pot: €43 won by Hero (€40.85)
Rake taken: €2.15
Seat 8: Player8 (€84.50), net: -€4.50
Seat 10: Hero (€124.35), net: +€24.35
Seat 2: Player2 (€49), net: -€1
Seat 3: Player3 (€77), net: -€16.50
Seat 5: Player5 (€86.15)
Seat 7: Player7 (€144.90), net: -€4.50
***** End of hand R5-21973414-50 *****

View File

@ -0,0 +1,16 @@
Full Tilt Poker Tournament Summary $2 + $0.25 Sit & Go (214900008) Hold'em No Limit
Buy-In: $2 + $0.25
Buy-In Chips: 1500
6 Entries
Total Prize Pool: $12
Tournament started: 2011/01/27 07:21:00 ET
Tournament finished: 2011/01/27 08:38:00 ET
1: Hero, $7.80
2: Player2, $4.20
3: Player3
4: Player4
5: Player5
6: Player6
Hero finished in 1st place

View File

@ -0,0 +1,18 @@
Full Tilt Poker Tournament Summary $2 + $0.25 Sit & Go (214976900) Hold'em No Limit
Buy-In: $2 + $0.25
Buy-In Chips: 1500
9 Entries
Total Prize Pool: $18
Tournament started: 2011/01/27 14:35:00 ET
Tournament finished: 2011/01/27 15:25:00 ET
1: Player1, $9
2: Player2, $5.40
3: Hero, $3.60
4: Player4
5: Player5
6: Player6
7: Player7
8: Player8
9: Player9
Hero finished in 3rd place