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

This commit is contained in:
sqlcoder 2010-03-15 21:51:50 +00:00
commit c2d05cdfbb
13 changed files with 100 additions and 52 deletions

View File

@ -1,5 +1,5 @@
# Variable definitions
VERSION = 0.12
VERSION = 0.20
DATE = $(shell date +%Y%m%d)
all:

View File

@ -162,7 +162,7 @@ class DerivedStats():
self.handsplayers[player]['wonAtSD'] = 1.0
for player in hand.pot.committed:
self.handsplayers[player]['totalProfit'] = int(self.handsplayers[player]['winnings'] - (100*hand.pot.committed[player]))
self.handsplayers[player]['totalProfit'] = int(self.handsplayers[player]['winnings'] - (100*hand.pot.committed[player])- (100*hand.pot.common[player]))
self.calcCBets(hand)

View File

@ -65,8 +65,8 @@ class Fulltilt(HandHistoryConverter):
(\s\((?P<TURBO>Turbo)\))?)|(?P<UNREADABLE_INFO>.+))
''', re.VERBOSE)
re_Button = re.compile('^The button is in seat #(?P<BUTTON>\d+)', re.MULTILINE)
re_PlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{3,15}) \(\$(?P<CASH>[,.0-9]+)\)$', re.MULTILINE)
re_TourneyPlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{3,15}) \(\$?(?P<CASH>[,.0-9]+)\)(, is sitting out)?$', re.MULTILINE)
re_PlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{2,15}) \(\$(?P<CASH>[,.0-9]+)\)$', re.MULTILINE)
re_TourneyPlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{2,15}) \(\$?(?P<CASH>[,.0-9]+)\)(, is sitting out)?$', re.MULTILINE)
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
#static regex for tourney purpose
@ -128,6 +128,7 @@ class Fulltilt(HandHistoryConverter):
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
logging.debug("player_re: " + player_re)
self.re_PostSB = re.compile(r"^%s posts the small blind of \$?(?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
self.re_PostDead = re.compile(r"^%s posts a dead small blind of \$?(?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
self.re_PostBB = re.compile(r"^%s posts (the big blind of )?\$?(?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
self.re_Antes = re.compile(r"^%s antes \$?(?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE)
self.re_BringIn = re.compile(r"^%s brings in for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
@ -298,6 +299,8 @@ class Fulltilt(HandHistoryConverter):
hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB'))
except: # no small blind
hand.addBlind(None, None, None)
for a in self.re_PostDead.finditer(hand.handText):
hand.addBlind(a.group('PNAME'), 'secondsb', a.group('SB'))
for a in self.re_PostBB.finditer(hand.handText):
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
for a in self.re_PostBoth.finditer(hand.handText):

View File

@ -81,7 +81,7 @@ class GuiPlayerStats (threading.Thread):
self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
self.filters.registerButton1Name("_Filters")
self.filters.registerButton1Callback(self.showDetailFilter)
self.filters.registerButton2Name("_Refresh Stats")
self.filters.registerButton2Name("_Refresh")
self.filters.registerButton2Callback(self.refreshStats)
# ToDo: store in config
@ -92,7 +92,7 @@ class GuiPlayerStats (threading.Thread):
, ["hand", False, "Hand", 0.0, "%s", "str"] # true not allowed for this line
, ["plposition", False, "Posn", 1.0, "%s", "str"] # true not allowed for this line (set in code)
, ["pname", False, "Name", 0.0, "%s", "str"] # true not allowed for this line (set in code)
, ["n", True, "Hds", 1.0, "%d", "str"]
, ["n", True, "Hds", 1.0, "%1.0f", "str"]
, ["avgseats", False, "Seats", 1.0, "%3.1f", "str"]
, ["vpip", True, "VPIP", 1.0, "%3.1f", "str"]
, ["pfr", True, "PFR", 1.0, "%3.1f", "str"]
@ -494,6 +494,22 @@ class GuiPlayerStats (threading.Thread):
gametest = "and gt.category IS NULL"
query = query.replace("<game_test>", gametest)
sitetest = ""
q = []
for m in self.filters.display.items():
if m[0] == 'Sites' and m[1]:
for n in sitenos:
q.append(n)
if len(q) > 0:
sitetest = str(tuple(q))
sitetest = sitetest.replace("L", "")
sitetest = sitetest.replace(",)",")")
sitetest = sitetest.replace("u'","'")
sitetest = "and gt.siteId in %s" % sitetest
else:
sitetest = "and gt.siteId IS NULL"
query = query.replace("<site_test>", sitetest)
if seats:
query = query.replace('<seats_test>', 'between ' + str(seats['from']) + ' and ' + str(seats['to']))
if 'show' in seats and seats['show']:
@ -551,7 +567,7 @@ class GuiPlayerStats (threading.Thread):
query = query.replace("<orderbyhgameTypeId>", "")
groupLevels = "show" not in str(limits)
if groupLevels:
query = query.replace("<hgameTypeId>", "p.name")
query = query.replace("<hgameTypeId>", "-1")
else:
query = query.replace("<hgameTypeId>", "h.gameTypeId")

View File

@ -323,7 +323,9 @@ For sites (currently only Carbon Poker) which record "all in" as a special actio
self.stacks[player] -= Decimal(ante)
act = (player, 'posts', "ante", ante, self.stacks[player]==0)
self.actions['BLINDSANTES'].append(act)
self.pot.addMoney(player, Decimal(ante))
# self.pot.addMoney(player, Decimal(ante))
self.pot.addCommonMoney(player, Decimal(ante))
#I think the antes should be common money, don't have enough hand history to check
def addBlind(self, player, blindtype, amount):
# if player is None, it's a missing small blind.
@ -342,14 +344,16 @@ For sites (currently only Carbon Poker) which record "all in" as a special actio
self.actions['BLINDSANTES'].append(act)
if blindtype == 'both':
# work with the real ammount. limit games are listed as $1, $2, where
# the SB 0.50 and the BB is $1, after the turn the minimum bet amount is $2....
amount = self.bb
self.bets['BLINDSANTES'][player].append(Decimal(self.sb))
self.pot.addCommonMoney(Decimal(self.sb))
self.pot.addCommonMoney(player, Decimal(self.sb))
if blindtype == 'secondsb':
amount = Decimal(0)
self.bets['BLINDSANTES'][player].append(Decimal(self.sb))
self.pot.addCommonMoney(Decimal(self.sb))
self.pot.addCommonMoney(player, Decimal(self.sb))
self.bets['PREFLOP'][player].append(Decimal(amount))
self.pot.addMoney(player, Decimal(amount))
@ -513,9 +517,6 @@ Card ranks will be uppercased
for entry in self.collected:
self.totalcollected += Decimal(entry[1])
def getGameTypeAsString(self):
"""\
Map the tuple self.gametype onto the pokerstars string describing it
@ -994,11 +995,12 @@ class DrawHand(Hand):
self.lastBet['DEAL'] = Decimal(amount)
elif blindtype == 'both':
# extra small blind is 'dead'
self.lastBet['DEAL'] = Decimal(self.bb)
amount = Decimal(amount)/3
amount += amount
self.lastBet['DEAL'] = Decimal(amount)
self.posted = self.posted + [[player,blindtype]]
#print "DEBUG: self.posted: %s" %(self.posted)
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
if player == self.hero: # we have hero's cards just update shown/mucked
if shown: self.shown.add(player)
@ -1413,7 +1415,7 @@ class Pot(object):
self.contenders = set()
self.committed = {}
self.streettotals = {}
self.common = Decimal(0)
self.common = {}
self.total = None
self.returned = {}
self.sym = u'$' # this is the default currency symbol
@ -1423,13 +1425,14 @@ class Pot(object):
def addPlayer(self,player):
self.committed[player] = Decimal(0)
self.common[player] = Decimal(0)
def addFold(self, player):
# addFold must be called when a player folds
self.contenders.discard(player)
def addCommonMoney(self, amount):
self.common += amount
def addCommonMoney(self, player, amount):
self.common[player] += amount
def addMoney(self, player, amount):
# addMoney must be called for any actions that put money in the pot, in the order they occur
@ -1437,7 +1440,7 @@ class Pot(object):
self.committed[player] += amount
def markTotal(self, street):
self.streettotals[street] = sum(self.committed.values()) + self.common
self.streettotals[street] = sum(self.committed.values()) + sum(self.common.values())
def getTotalAtStreet(self, street):
if street in self.streettotals:
@ -1445,7 +1448,7 @@ class Pot(object):
return 0
def end(self):
self.total = sum(self.committed.values()) + self.common
self.total = sum(self.committed.values()) + sum(self.common.values())
# Return any uncalled bet.
committed = sorted([ (v,k) for (k,v) in self.committed.items()])

View File

@ -77,14 +77,15 @@ class PartyPoker(HandHistoryConverter):
re.VERBOSE)
re_HandInfo = re.compile("""
^Table\s+(?P<TTYPE>[$a-zA-Z0-9 ]+)\s+
^Table\s+(?P<TTYPE>[$a-zA-Z0-9 ]+)?\s+
(?: \#|\(|)(?P<TABLE>\d+)\)?\s+
(?:[a-zA-Z0-9 ]+\s+\#(?P<MTTTABLE>\d+).+)?
(\(No\sDP\)\s)?
\((?P<PLAY>Real|Play)\s+Money\)\s+ # FIXME: check if play money is correct
Seat\s+(?P<BUTTON>\d+)\sis\sthe\sbutton
\s+Total\s+number\s+of\s+players\s+\:\s+(?P<PLYRS>\d+)/?(?P<MAX>\d+)?
""",
re.VERBOSE|re.MULTILINE)
re.VERBOSE|re.MULTILINE|re.DOTALL)
re_CountedSeats = re.compile("^Total\s+number\s+of\s+players\s*:\s*(?P<COUNTED_SEATS>\d+)", re.MULTILINE)
re_SplitHands = re.compile('\x00+')
@ -106,7 +107,6 @@ class PartyPoker(HandHistoryConverter):
def guessMaxSeats(self, hand):
"""Return a guess at max_seats when not specified in HH."""
mo = self.maxOccSeat(hand)
if mo == 10: return mo
if mo == 2: return 2
if mo <= 6: return 6
@ -260,6 +260,7 @@ class PartyPoker(HandHistoryConverter):
for i,v in enumerate(self.collected):
if v[0] in self.pot.returned:
self.collected[i][1] = Decimal(v[1]) - self.pot.returned[v[0]]
self.collectees[v[0]] -= self.pot.returned[v[0]]
return origTotalPot()
return totalPot
instancemethod = type(hand.totalPot)
@ -313,6 +314,9 @@ class PartyPoker(HandHistoryConverter):
if key == 'PLAY' and info['PLAY'] != 'Real':
# if realy party doesn's save play money hh
hand.gametype['currency'] = 'play'
if key == 'MAX' and info[key] is not None:
hand.maxseats = int(info[key])
def readButton(self, hand):
m = self.re_Button.search(hand.handText)
@ -465,8 +469,9 @@ class PartyPoker(HandHistoryConverter):
def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
"Returns string to search in windows titles"
if type=="tour":
print 'party', 'getTableTitleRe', "%s.+Table\s#%s" % (table_name, table_number)
return "%s.+Table\s#%s" % (table_name, table_number)
TableName = table_name.split(" ")
print 'party', 'getTableTitleRe', "%s.+Table\s#%s" % (TableName[0], table_number)
return "%s.+Table\s#%s" % (TableName[0], table_number)
else:
print 'party', 'getTableTitleRe', table_number
return table_name

30
pyfpdb/PokerStarsToFpdb.py Executable file → Normal file
View File

@ -141,6 +141,14 @@ class PokerStars(HandHistoryConverter):
mg = m.groupdict()
# translations from captured groups to fpdb info strings
Lim_Blinds = { '0.04': ('0.01', '0.02'), '0.10': ('0.02', '0.05'), '0.20': ('0.05', '0.10'),
'0.50': ('0.10', '0.25'), '1.00': ('0.25', '0.50'), '2.00': ('0.50', '1.00'),
'4.00': ('1.00', '2.00'), '6.00': ('1.00', '3.00'), '10.00': ('2.00', '5.00'),
'20.00': ('5.00', '10.00'), '30.00': ('10.00', '15.00'), '60.00': ('15.00', '30.00'),
'100.00': ('25.00', '50.00'),'200.00': ('50.00', '100.00'),'400.00': ('100.00', '200.00'),
'1000.00': ('250.00', '500.00')}
limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl' }
games = { # base, category
"Hold'em" : ('hold','holdem'),
@ -174,6 +182,10 @@ class PokerStars(HandHistoryConverter):
else:
info['type'] = 'tour'
if info['limitType'] == 'fl' and info['bb'] is not None and info['type'] == 'ring' and info['base'] != 'stud':
info['sb'] = Lim_Blinds[mg['BB']][0]
info['bb'] = Lim_Blinds[mg['BB']][1]
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
return info
@ -292,16 +304,14 @@ class PokerStars(HandHistoryConverter):
hand.addBringIn(m.group('PNAME'), m.group('BRINGIN'))
def readBlinds(self, hand):
try:
count = 0
for a in self.re_PostSB.finditer(hand.handText):
if count == 0:
hand.addBlind(a.group('PNAME'), 'small blind', a.group('SB'))
count = 1
else:
hand.addBlind(a.group('PNAME'), 'secondsb', a.group('SB'))
except: # no small blind
hand.addBlind(None, None, None)
liveBlind = True
for a in self.re_PostSB.finditer(hand.handText):
if liveBlind:
hand.addBlind(a.group('PNAME'), 'small blind', a.group('SB'))
liveBlind = False
else:
# Post dead blinds as ante
hand.addBlind(a.group('PNAME'), 'secondsb', a.group('SB'))
for a in self.re_PostBB.finditer(hand.handText):
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
for a in self.re_PostBoth.finditer(hand.handText):

View File

@ -1916,6 +1916,7 @@ class Sql:
inner join Players p on (p.Id = hp.playerId)
where hp.playerId in <player_test>
<game_test>
<site_test>
/*and hp.tourneysPlayersId IS NULL*/
and h.seats <seats_test>
<flagtest>
@ -2000,6 +2001,7 @@ class Sql:
inner join Players p on (p.Id = hp.playerId)
where hp.playerId in <player_test>
<game_test>
<site_test>
/*and hp.tourneysPlayersId IS NULL*/
and h.seats <seats_test>
<flagtest>
@ -2077,8 +2079,7 @@ class Sql:
,100.0*avg((hp.totalProfit+hp.rake)/(gt.bigBlind+0.0)) AS bb100xr
,avg((hp.totalProfit+hp.rake)/100.0) AS profhndxr
,avg(h.seats+0.0) AS avgseats
/*,variance(hp.totalProfit/100.0) AS variance*/
,0.0 AS variance
,variance(hp.totalProfit/100.0) AS variance
from HandsPlayers hp
inner join Hands h on (h.id = hp.handId)
inner join Gametypes gt on (gt.Id = h.gameTypeId)
@ -2086,6 +2087,7 @@ class Sql:
inner join Players p on (p.Id = hp.playerId)
where hp.playerId in <player_test>
<game_test>
<site_test>
/*and hp.tourneysPlayersId IS NULL*/
and h.seats <seats_test>
<flagtest>

View File

@ -32,12 +32,16 @@ import gtk
import gobject
# fpdb/free poker tools modules
import Configuration
from HandHistoryConverter import getTableTitleRe
# get the correct module for the current os
if os.name == 'posix':
import XTables as Tables
elif os.name == 'nt':
import WinTables as Tables
config = Configuration.Config()
# Main function used for testing
if __name__=="__main__":
# c = Configuration.Config()
@ -82,11 +86,16 @@ if __name__=="__main__":
(tour_no, tab_no) = table_name.split(",", 1)
tour_no = tour_no.rstrip()
tab_no = tab_no.rstrip()
table = Tables.Table(None, tournament = tour_no, table_number = tab_no)
type = "tour"
table_kwargs = dict(tournament = tour_no, table_number = tab_no)
else: # not a tournament
print "cash game"
table_name = table_name.rstrip()
table = Tables.Table(None, table_name = table_name)
type = "cash"
table_kwargs = dict(table_name = table_name)
search_string = getTableTitleRe(config, "Full Tilt Poker", type, **table_kwargs)
table = Tables.Table(search_string, **table_kwargs)
table.gdk_handle = gtk.gdk.window_foreign_new(table.number)
print "table =", table

View File

@ -68,7 +68,7 @@ class Table(Table_Window):
window_number = None
for listing in os.popen('xwininfo -root -tree').readlines():
if re.search(search_string, listing):
print listing
# print listing
mo = re.match('\s+([\dxabcdef]+) (.+):\s\(\"([a-zA-Z.]+)\".+ (\d+)x(\d+)\+\d+\+\d+ \+(\d+)\+(\d+)', listing)
self.number = int( mo.group(1), 0)
self.width = int( mo.group(4) )

View File

@ -152,7 +152,7 @@ setup(
},
# files in 2nd value in tuple are moved to dir named in 1st value
data_files = [('', ['HUD_config.xml.example', 'Cards01.png', 'logging.conf'])
data_files = [('', ['HUD_config.xml.example', 'Cards01.png', 'logging.conf', '../docs/readme.txt'])
,(dist_dir, [r'..\run_fpdb.bat'])
,( dist_dir + r'\gfx', glob.glob(r'..\gfx\*.*') )
# line below has problem with fonts subdir ('not a regular file')

0
run_fpdb.py Executable file → Normal file
View File