Merge branch 'master' of git://git.assembla.com/mctfpdb
Conflicts: pyfpdb/fpdb.py
This commit is contained in:
commit
d8dffb193f
230
pyfpdb/Hand.py
230
pyfpdb/Hand.py
|
@ -23,11 +23,11 @@ import os
|
|||
import os.path
|
||||
from decimal import Decimal
|
||||
import operator
|
||||
import time
|
||||
import time,datetime
|
||||
from copy import deepcopy
|
||||
from Exceptions import *
|
||||
|
||||
import DerivedStats
|
||||
import Card
|
||||
|
||||
class Hand:
|
||||
UPS = {'a':'A', 't':'T', 'j':'J', 'q':'Q', 'k':'K', 'S':'s', 'C':'c', 'H':'h', 'D':'d'}
|
||||
|
@ -148,7 +148,8 @@ db: a connected fpdb_db object"""
|
|||
|
||||
def select(self, handId):
|
||||
""" Function to create Hand object from database """
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
def addPlayer(self, seat, name, chips):
|
||||
|
@ -408,34 +409,34 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
|||
|
||||
def printActionLine(self, act, fh):
|
||||
if act[1] == 'folds':
|
||||
print >>fh, _("%s: folds " %(act[0]))
|
||||
print >>fh, ("%s: folds " %(act[0]))
|
||||
elif act[1] == 'checks':
|
||||
print >>fh, _("%s: checks " %(act[0]))
|
||||
print >>fh, ("%s: checks " %(act[0]))
|
||||
elif act[1] == 'calls':
|
||||
print >>fh, _("%s: calls $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||
print >>fh, ("%s: calls $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||
elif act[1] == 'bets':
|
||||
print >>fh, _("%s: bets $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||
print >>fh, ("%s: bets $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||
elif act[1] == 'raises':
|
||||
print >>fh, _("%s: raises $%s to $%s%s" %(act[0], act[2], act[3], ' and is all-in' if act[5] else ''))
|
||||
print >>fh, ("%s: raises $%s to $%s%s" %(act[0], act[2], act[3], ' and is all-in' if act[5] else ''))
|
||||
elif act[1] == 'completea':
|
||||
print >>fh, _("%s: completes to $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||
print >>fh, ("%s: completes to $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||
elif act[1] == 'posts':
|
||||
if(act[2] == "small blind"):
|
||||
print >>fh, _("%s: posts small blind $%s%s" %(act[0], act[3], ' and is all-in' if act[4] else ''))
|
||||
print >>fh, ("%s: posts small blind $%s%s" %(act[0], act[3], ' and is all-in' if act[4] else ''))
|
||||
elif(act[2] == "big blind"):
|
||||
print >>fh, _("%s: posts big blind $%s%s" %(act[0], act[3], ' and is all-in' if act[4] else ''))
|
||||
print >>fh, ("%s: posts big blind $%s%s" %(act[0], act[3], ' and is all-in' if act[4] else ''))
|
||||
elif(act[2] == "both"):
|
||||
print >>fh, _("%s: posts small & big blinds $%s%s" %(act[0], act[3], ' and is all-in' if act[4] else ''))
|
||||
print >>fh, ("%s: posts small & big blinds $%s%s" %(act[0], act[3], ' and is all-in' if act[4] else ''))
|
||||
elif act[1] == 'bringin':
|
||||
print >>fh, _("%s: brings in for $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||
print >>fh, ("%s: brings in for $%s%s" %(act[0], act[2], ' and is all-in' if act[3] else ''))
|
||||
elif act[1] == 'discards':
|
||||
print >>fh, _("%s: discards %s %s%s" %(act[0], act[2], 'card' if act[2] == 1 else 'cards' , " [" + " ".join(self.discards[act[0]]['DRAWONE']) + "]" if self.hero == act[0] else ''))
|
||||
print >>fh, ("%s: discards %s %s%s" %(act[0], act[2], 'card' if act[2] == 1 else 'cards' , " [" + " ".join(self.discards[act[0]]['DRAWONE']) + "]" if self.hero == act[0] else ''))
|
||||
elif act[1] == 'stands pat':
|
||||
print >>fh, _("%s: stands pat" %(act[0]))
|
||||
print >>fh, ("%s: stands pat" %(act[0]))
|
||||
|
||||
|
||||
class HoldemOmahaHand(Hand):
|
||||
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC"):
|
||||
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC", handid=None):
|
||||
if gametype['base'] != 'hold':
|
||||
pass # or indeed don't pass and complain instead
|
||||
logging.debug("HoldemOmahaHand")
|
||||
|
@ -470,7 +471,14 @@ class HoldemOmahaHand(Hand):
|
|||
self.totalPot() # finalise it (total the pot)
|
||||
hhc.getRake(self)
|
||||
elif builtFrom == "DB":
|
||||
self.select("dummy") # Will need a handId
|
||||
if handid is not None:
|
||||
self.select(handid) # Will need a handId
|
||||
else:
|
||||
logging.warning("HoldemOmahaHand.__init__:Can't assemble hand from db without a handid")
|
||||
else:
|
||||
logging.warning("HoldemOmahaHand.__init__:Neither HHC nor DB+handid provided")
|
||||
pass
|
||||
|
||||
|
||||
def addHoleCards(self, cards, player, shown=False):
|
||||
"""\
|
||||
|
@ -508,41 +516,41 @@ Card ranks will be uppercased
|
|||
|
||||
def writeHand(self, fh=sys.__stdout__):
|
||||
# PokerStars format.
|
||||
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S ET', self.starttime)))
|
||||
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||
print >>fh, ("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
||||
print >>fh, ("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||
|
||||
players_who_act_preflop = set(([x[0] for x in self.actions['PREFLOP']]+[x[0] for x in self.actions['BLINDSANTES']]))
|
||||
logging.debug(self.actions['PREFLOP'])
|
||||
for player in [x for x in self.players if x[1] in players_who_act_preflop]:
|
||||
#Only print stacks of players who do something preflop
|
||||
print >>fh, _("Seat %s: %s ($%s in chips) " %(player[0], player[1], player[2]))
|
||||
print >>fh, ("Seat %s: %s ($%s in chips) " %(player[0], player[1], player[2]))
|
||||
|
||||
if self.actions['BLINDSANTES']:
|
||||
for act in self.actions['BLINDSANTES']:
|
||||
self.printActionLine(act, fh)
|
||||
|
||||
print >>fh, _("*** HOLE CARDS ***")
|
||||
print >>fh, ("*** HOLE CARDS ***")
|
||||
if self.involved:
|
||||
print >>fh, _("Dealt to %s [%s]" %(self.hero , " ".join(self.holecards[self.hero]['PREFLOP'])))
|
||||
print >>fh, ("Dealt to %s [%s]" %(self.hero , " ".join(self.holecards[self.hero]['PREFLOP'])))
|
||||
|
||||
if self.actions['PREFLOP']:
|
||||
for act in self.actions['PREFLOP']:
|
||||
self.printActionLine(act, fh)
|
||||
|
||||
if self.board['FLOP']:
|
||||
print >>fh, _("*** FLOP *** [%s]" %( " ".join(self.board['FLOP'])))
|
||||
print >>fh, ("*** FLOP *** [%s]" %( " ".join(self.board['FLOP'])))
|
||||
if self.actions['FLOP']:
|
||||
for act in self.actions['FLOP']:
|
||||
self.printActionLine(act, fh)
|
||||
|
||||
if self.board['TURN']:
|
||||
print >>fh, _("*** TURN *** [%s] [%s]" %( " ".join(self.board['FLOP']), " ".join(self.board['TURN'])))
|
||||
print >>fh, ("*** TURN *** [%s] [%s]" %( " ".join(self.board['FLOP']), " ".join(self.board['TURN'])))
|
||||
if self.actions['TURN']:
|
||||
for act in self.actions['TURN']:
|
||||
self.printActionLine(act, fh)
|
||||
|
||||
if self.board['RIVER']:
|
||||
print >>fh, _("*** RIVER *** [%s] [%s]" %(" ".join(self.board['FLOP']+self.board['TURN']), " ".join(self.board['RIVER']) ))
|
||||
print >>fh, ("*** RIVER *** [%s] [%s]" %(" ".join(self.board['FLOP']+self.board['TURN']), " ".join(self.board['RIVER']) ))
|
||||
if self.actions['RIVER']:
|
||||
for act in self.actions['RIVER']:
|
||||
self.printActionLine(act, fh)
|
||||
|
@ -552,7 +560,7 @@ Card ranks will be uppercased
|
|||
# The logic for a showdown is: at the end of river action there are at least two players in the hand
|
||||
# we probably don't need a showdown section in pseudo stars format for our filtering purposes
|
||||
if self.shown:
|
||||
print >>fh, _("*** SHOW DOWN ***")
|
||||
print >>fh, ("*** SHOW DOWN ***")
|
||||
for name in self.shown:
|
||||
# TODO: legacy importer can't handle only one holecard here, make sure there are 2 for holdem, 4 for omaha
|
||||
# TOOD: If HoldHand subclass supports more than omahahi, omahahilo, holdem, add them here
|
||||
|
@ -562,7 +570,7 @@ Card ranks will be uppercased
|
|||
elif self.gametype['category'] in ('holdem'):
|
||||
numOfHoleCardsNeeded = 2
|
||||
if len(self.holecards[name]['PREFLOP']) == numOfHoleCardsNeeded:
|
||||
print >>fh, _("%s shows [%s] (a hand...)" % (name, " ".join(self.holecards[name]['PREFLOP'])))
|
||||
print >>fh, ("%s shows [%s] (a hand...)" % (name, " ".join(self.holecards[name]['PREFLOP'])))
|
||||
|
||||
# Current PS format has the lines:
|
||||
# Uncalled bet ($111.25) returned to s0rrow
|
||||
|
@ -572,35 +580,35 @@ Card ranks will be uppercased
|
|||
# Immediately before the summary.
|
||||
# The current importer uses those lines for importing winning rather than the summary
|
||||
for name in self.pot.returned:
|
||||
print >>fh, _("Uncalled bet ($%s) returned to %s" %(self.pot.returned[name],name))
|
||||
print >>fh, ("Uncalled bet ($%s) returned to %s" %(self.pot.returned[name],name))
|
||||
for entry in self.collected:
|
||||
print >>fh, _("%s collected $%s from x pot" %(entry[0], entry[1]))
|
||||
print >>fh, ("%s collected $%s from x pot" %(entry[0], entry[1]))
|
||||
|
||||
print >>fh, _("*** SUMMARY ***")
|
||||
print >>fh, ("*** SUMMARY ***")
|
||||
print >>fh, "%s | Rake $%.2f" % (self.pot, self.rake)
|
||||
|
||||
board = []
|
||||
for s in self.board.values():
|
||||
board += s
|
||||
if board: # sometimes hand ends preflop without a board
|
||||
print >>fh, _("Board [%s]" % (" ".join(board)))
|
||||
print >>fh, ("Board [%s]" % (" ".join(board)))
|
||||
|
||||
for player in [x for x in self.players if x[1] in players_who_act_preflop]:
|
||||
seatnum = player[0]
|
||||
name = player[1]
|
||||
if name in self.collectees and name in self.shown:
|
||||
print >>fh, _("Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, " ".join(self.holecards[name]['PREFLOP']), self.collectees[name]))
|
||||
print >>fh, ("Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, " ".join(self.holecards[name]['PREFLOP']), self.collectees[name]))
|
||||
elif name in self.collectees:
|
||||
print >>fh, _("Seat %d: %s collected ($%s)" % (seatnum, name, self.collectees[name]))
|
||||
print >>fh, ("Seat %d: %s collected ($%s)" % (seatnum, name, self.collectees[name]))
|
||||
#~ elif name in self.shown:
|
||||
#~ print >>fh, _("Seat %d: %s showed [%s]" % (seatnum, name, " ".join(self.holecards[name]['PREFLOP'])))
|
||||
elif name in self.folded:
|
||||
print >>fh, _("Seat %d: %s folded" % (seatnum, name))
|
||||
print >>fh, ("Seat %d: %s folded" % (seatnum, name))
|
||||
else:
|
||||
if name in self.shown:
|
||||
print >>fh, _("Seat %d: %s showed [%s] and lost with..." % (seatnum, name, " ".join(self.holecards[name]['PREFLOP'])))
|
||||
print >>fh, ("Seat %d: %s showed [%s] and lost with..." % (seatnum, name, " ".join(self.holecards[name]['PREFLOP'])))
|
||||
else:
|
||||
print >>fh, _("Seat %d: %s mucked" % (seatnum, name))
|
||||
print >>fh, ("Seat %d: %s mucked" % (seatnum, name))
|
||||
|
||||
print >>fh, "\n\n"
|
||||
|
||||
|
@ -1086,6 +1094,154 @@ class Pot(object):
|
|||
# no small blind and walk in bb (hopefully)
|
||||
return "Total pot $%.2f" % (self.total,)
|
||||
else:
|
||||
return _("too many pots.. no small blind and walk in bb?. self.pots: %s" %(self.pots))
|
||||
return ("too many pots.. no small blind and walk in bb?. self.pots: %s" %(self.pots))
|
||||
# I don't know stars format for a walk in the bb when sb doesn't post.
|
||||
# The thing to do here is raise a Hand error like fpdb import does and file it into errors.txt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def assemble(cnxn, handid):
|
||||
c = cnxn.cursor()
|
||||
|
||||
# We need the following for the Hand.__init__
|
||||
c.execute("""
|
||||
select
|
||||
s.name,
|
||||
g.category,
|
||||
g.base,
|
||||
g.type,
|
||||
g.limitType,
|
||||
g.hilo,
|
||||
g.smallBlind / 100.0,
|
||||
g.bigBlind / 100.0 ,
|
||||
g.smallBet / 100.0,
|
||||
g.bigBet / 100.0,
|
||||
s.currency,
|
||||
bc.card1value,
|
||||
bc.card1suit,
|
||||
bc.card2value,bc.card2suit,
|
||||
bc.card3value,bc.card3suit,
|
||||
bc.card4value,bc.card4suit,
|
||||
bc.card5value,bc.card5suit
|
||||
from
|
||||
hands as h,
|
||||
boardcards as bc,
|
||||
sites as s,
|
||||
gametypes as g,
|
||||
handsplayers as hp,
|
||||
players as p
|
||||
where
|
||||
h.id = %(handid)s
|
||||
and bc.handid = h.id
|
||||
and g.id = h.gametypeid
|
||||
and hp.handid = h.id
|
||||
and p.id = hp.playerid
|
||||
and s.id = p.siteid
|
||||
limit 1""", {'handid':handid})
|
||||
#TODO: siteid should be in hands table - we took the scenic route through players here.
|
||||
res = c.fetchone()
|
||||
gametype = {'category':res[1],'base':res[2],'type':res[3],'limitType':res[4],'hilo':res[5],'sb':res[6],'bb':res[7], 'currency':res[10]}
|
||||
h = HoldemOmahaHand(hhc = None, sitename=res[0], gametype = gametype, handText=None, builtFrom = "DB", handid=handid)
|
||||
cards = map("".join, zip(map(str,res[11:21:2]), res[12:21:2]))
|
||||
|
||||
if cards[0] != "0x":
|
||||
h.setCommunityCards('FLOP', cards[0:3])
|
||||
if cards[3] != "0x":
|
||||
h.setCommunityCards('TURN', cards[3])
|
||||
if cards[4] != "0x":
|
||||
h.setCommunityCards('RIVER', cards[4])
|
||||
#[Card.valueSuitFromCard(x) for x in cards]
|
||||
|
||||
|
||||
#TODO : doesn't look like this is in the database; don't like the way Hand requires it
|
||||
h.hero = 'mcturnbull'
|
||||
|
||||
# HandInfo : HID, TABLE
|
||||
# BUTTON - why is this treated specially in Hand?
|
||||
# answer: it is written out in hand histories
|
||||
# still, I think we should record all the active seat positions in a seat_order array
|
||||
c.execute("""
|
||||
SELECT
|
||||
h.sitehandno as hid,
|
||||
h.tablename as table,
|
||||
h.handstart as starttime
|
||||
FROM
|
||||
hands as h
|
||||
WHERE h.id = %(handid)s
|
||||
""", {'handid':handid})
|
||||
res = c.fetchone()
|
||||
h.handid = res[0]
|
||||
h.tablename = res[1]
|
||||
h.starttime = res[2] # automatically a datetime
|
||||
|
||||
# PlayerStacks
|
||||
c.execute("""
|
||||
SELECT
|
||||
hp.seatno,
|
||||
p.name,
|
||||
round(hp.startcash / 100.0,2) as chips,
|
||||
(hp.card1,hp.card2) as hole
|
||||
FROM
|
||||
handsplayers as hp,
|
||||
players as p
|
||||
WHERE
|
||||
hp.handid = %(handid)s
|
||||
and p.id = hp.playerid
|
||||
""", {'handid':handid})
|
||||
for (seat, name, chips, cards) in c.fetchall():
|
||||
h.addPlayer(seat,name,chips)
|
||||
h.addHoleCards([Card.valueSuitFromCard(x) for x in cards],name)
|
||||
|
||||
# actions
|
||||
c.execute("""
|
||||
SELECT
|
||||
(ha.street,ha.actionno) as actnum,
|
||||
p.name,
|
||||
ha.street,
|
||||
ha.action,
|
||||
ha.allin,
|
||||
ha.amount / 100.0
|
||||
FROM
|
||||
handsplayers as hp,
|
||||
handsactions as ha,
|
||||
players as p
|
||||
WHERE
|
||||
hp.handid = %(handid)s
|
||||
and ha.handsplayerid = hp.id
|
||||
and p.id = hp.playerid
|
||||
ORDER BY
|
||||
ha.street,ha.actionno
|
||||
""", {'handid':handid})
|
||||
res = c.fetchall()
|
||||
for (actnum,player, streetnum, act, allin, amount) in res:
|
||||
act=act.strip()
|
||||
street = h.streetList[streetnum+2]
|
||||
if act==u'blind':
|
||||
h.addBlind(player, 'big blind', amount)
|
||||
# TODO: The type of blind is not recorded in the DB.
|
||||
# TODO: preflop street name anomalies in Hand
|
||||
elif act==u'fold':
|
||||
h.addFold(street,player)
|
||||
elif act==u'call':
|
||||
h.addCall(street,player,amount)
|
||||
elif act==u'bet':
|
||||
h.addBet(street,player,amount)
|
||||
elif act==u'check':
|
||||
h.addCheck(street,player)
|
||||
elif act==u'unbet':
|
||||
pass
|
||||
else:
|
||||
print act, player, streetnum, allin, amount
|
||||
# TODO : other actions
|
||||
#hhc.readCollectPot(self)
|
||||
#hhc.readShowdownActions(self)
|
||||
#hc.readShownCards(self)
|
||||
h.totalPot()
|
||||
h.rake = h.totalpot - h.totalcollected
|
||||
|
||||
|
||||
return h
|
||||
|
||||
|
|
|
@ -134,8 +134,8 @@ follow : whether to tail -f the input"""
|
|||
#2008/08/17 - 01:14:43 (ET)
|
||||
#2008/09/07 06:23:14 ET
|
||||
m2 = re.search("(?P<Y>[0-9]{4})\/(?P<M>[0-9]{2})\/(?P<D>[0-9]{2})[\- ]+(?P<H>[0-9]+):(?P<MIN>[0-9]+):(?P<S>[0-9]+)", info[key])
|
||||
datetime = "%s/%s/%s %s:%s:%s" % (m2.group('Y'), m2.group('M'),m2.group('D'),m2.group('H'),m2.group('MIN'),m2.group('S'))
|
||||
hand.starttime = time.strptime(datetime, "%Y/%m/%d %H:%M:%S")
|
||||
datetimestr = "%s/%s/%s %s:%s:%s" % (m2.group('Y'), m2.group('M'),m2.group('D'),m2.group('H'),m2.group('MIN'),m2.group('S'))
|
||||
hand.starttime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S")
|
||||
if key == 'HID':
|
||||
hand.handid = info[key]
|
||||
if key == 'TABLE':
|
||||
|
|
|
@ -409,7 +409,7 @@ class fpdb:
|
|||
return self.fdb_lock.get_global_lock()
|
||||
#end def obtain_global_lock
|
||||
|
||||
def quit(self, widget):
|
||||
def quit(self, widget, data):
|
||||
print "Quitting normally"
|
||||
#check if current settings differ from profile, if so offer to save or abort
|
||||
self.db.disconnect()
|
||||
|
|
|
@ -1138,7 +1138,6 @@ def storeActions(cursor, handsPlayersIds, actionTypes, allIns, actionAmounts, ac
|
|||
|
||||
def store_board_cards(cursor, hands_id, board_values, board_suits):
|
||||
#stores into table board_cards
|
||||
return
|
||||
cursor.execute ("""INSERT INTO BoardCards (handId, card1Value, card1Suit,
|
||||
card2Value, card2Suit, card3Value, card3Suit, card4Value, card4Suit,
|
||||
card5Value, card5Suit) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
|
||||
|
@ -2382,7 +2381,7 @@ def storeHudCache2(backend, cursor, base, category, gametypeId, hand_start_time,
|
|||
# Try to do the update first:
|
||||
num = cursor.execute("""UPDATE HudCache
|
||||
SET HDs=HDs+%s, street0VPI=street0VPI+%s, street0Aggr=street0Aggr+%s,
|
||||
street0_3BChance=street0_3BChance+%s, street0_3BDone=street0_3BDone+%s,
|
||||
street0_3B4BChance=street0_3B4BChance+%s, street0_3B4BDone=street0_3B4BDone+%s,
|
||||
street1Seen=street1Seen+%s, street2Seen=street2Seen+%s, street3Seen=street3Seen+%s,
|
||||
street4Seen=street4Seen+%s, sawShowdown=sawShowdown+%s,
|
||||
street1Aggr=street1Aggr+%s, street2Aggr=street2Aggr+%s, street3Aggr=street3Aggr+%s,
|
||||
|
|
Loading…
Reference in New Issue
Block a user