Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for All-In or Fold #1

Open
wants to merge 28 commits into
base: Mudr0x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
76c722b
Added support for All-In or Fold
ChazDazzle Apr 28, 2023
0510322
Fix for draw games
ChazDazzle Apr 29, 2023
b9c7714
888Poker fixed the uncalled bets problem for walks. Unclear at this t…
ChazDazzle Jun 27, 2023
d8aebe1
Updated for new INR symbol
ChazDazzle Jun 27, 2023
c7f7251
Fixed PLO8 support for iPoker
ChazDazzle Sep 6, 2023
ea2244e
Fix PP ante
ChazDazzle Sep 21, 2023
60ee953
Fix Winamax fast fold
ChazDazzle Sep 21, 2023
a362d10
First attempt at All in or Fold
ChazDazzle Oct 2, 2023
1130edc
Fix for identifying AOF hands
ChazDazzle Oct 2, 2023
a422e8c
Added support for PokerMaster 6 card omaha h/l
ChazDazzle Oct 3, 2023
6d20ec0
Completed error handling for pokereval
ChazDazzle Oct 3, 2023
8a58c05
Added support for converted SupremaPoker hands
ChazDazzle Oct 6, 2023
4dec83f
Added a few commits where needed
ChazDazzle Oct 11, 2023
352bb15
Added kr support
ChazDazzle Oct 17, 2023
5d7c55e
changed kr to SEK
ChazDazzle Oct 17, 2023
43868c7
Added support for MPLPoker
ChazDazzle Oct 17, 2023
2ff3052
Added support for MPL 5/6 Card PLO
ChazDazzle Oct 18, 2023
3414e05
Fix for Winning
ChazDazzle Nov 3, 2023
a239c00
ACR Reshuffle added
ChazDazzle Nov 3, 2023
7350a56
Added space as a thousand delimiter for iPoker
ChazDazzle Nov 13, 2023
24b1fbc
Updated for new ps.it ADM ID
ChazDazzle Jan 7, 2024
605701f
Fix for rake/ev calculations with cash out hands
ChazDazzle Feb 7, 2024
a0d3f9e
Fixed support for 888 tourney summaries
ChazDazzle Feb 21, 2024
b6ff060
Fixed AOF support for RIT games
ChazDazzle Apr 9, 2024
e67df6e
Fixed an issue where RIT and regular street community cards would show
ChazDazzle Apr 10, 2024
89d6ccf
Stud needs award pots calculations too
ChazDazzle Apr 10, 2024
588dabf
allowed pokerstars formatted HHs to omit a level number
ChazDazzle Apr 21, 2024
c8a0f99
add regression file for tourney with bad all-in ante
ChazDazzle Apr 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pyfpdb/Card.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@
'irish' : ('hold', None,'h', {'PREFLOP':0,'FLOP':1,'TURN':2,'RIVER':3}, 'RIVER', [(0,4)]),
'5_omahahi' : ('hold','omaha','h', {'PREFLOP':0,'FLOP':1,'TURN':2,'RIVER':3}, 'RIVER', [(0,5)]),
'6_omahahi' : ('hold','omaha','h', {'PREFLOP':0,'FLOP':1,'TURN':2,'RIVER':3}, 'RIVER', [(0,6)]),
'6_omaha8' : ('hold','omaha8','s', {'PREFLOP':0,'FLOP':1,'TURN':2,'RIVER':3}, 'RIVER', [(0,6)]),
'5_omaha8' : ('hold','omaha8','s', {'PREFLOP':0,'FLOP':1,'TURN':2,'RIVER':3}, 'RIVER', [(0,5)]),
'cour_hi' : ('hold','omaha','h', {'PREFLOP':0,'FLOP':1,'TURN':2,'RIVER':3}, 'RIVER', [(0,5)]),
'cour_hilo' : ('hold','omaha8','s', {'PREFLOP':0,'FLOP':1,'TURN':2,'RIVER':3}, 'RIVER', [(0,5)]),
'aof_omaha' : ('hold','omaha','h', {'FLOP':0,'TURN':1,'RIVER':2}, 'RIVER', [(0,4)]),
'5_studhi' : ('stud','holdem', 'h', {'SECOND': 0, 'THIRD': 1,'FOURTH': 2,'FIFTH': 3}, 'FIFTH', [(0,2),(0,3),(0,4),(0,5)]),
'razz' : ('stud', None, 'l', {'THIRD': 0,'FOURTH': 1,'FIFTH': 2,'SIXTH': 3,'SEVENTH': 4}, 'SEVENTH', [(0,3),(0,4),(0,5),(0,6),(0,7)]),
'studhi' : ('stud','7stud', 'h', {'THIRD': 0,'FOURTH': 1,'FIFTH': 2,'SIXTH': 3,'SEVENTH': 4}, 'SEVENTH', [(0,3),(0,4),(0,5),(0,6),(0,7)]),
Expand Down
2 changes: 2 additions & 0 deletions pyfpdb/Database.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,11 +878,13 @@ def connect(self, backend=None, host=None, database=None,
self.cursor = self.connection.cursor()
self.cursor.execute(self.sql.query['set tx level'])
self.check_version(database=database, create=create)
self.commit()

def get_sites(self):
self.cursor.execute("SELECT name,id FROM Sites")
sites = self.cursor.fetchall()
self.config.set_site_ids(sites)
self.commit()

def check_version(self, database, create):
self.wrongDbVersion = False
Expand Down
53 changes: 33 additions & 20 deletions pyfpdb/DerivedStats.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,13 +425,17 @@ def assembleHandsStove(self, hand):
maxcards = (base!='hold' and len(cards)>=5)
if notnull and (postflop or maxcards):
for hl, side in hiLoKey[hilo]:
value, rank = pokereval.best(side, cards, bcards)
rankId = Card.hands[rank[0]][0]
if rank!=None and rank[0] != 'Nothing':
_cards = ''.join([pokereval.card2string(i)[0] for i in rank[1:]])
else:
_cards = None
self.handsstove.append( [hand.dbid_hands, hand.dbid_pids[pname], streetId, boardId, hl, rankId, value, _cards, 0] )
try:
value, rank = pokereval.best(side, cards, bcards)
rankId = Card.hands[rank[0]][0]
if rank!=None and rank[0] != 'Nothing':
_cards = ''.join([pokereval.card2string(i)[0] for i in rank[1:]])
else:
_cards = None
self.handsstove.append( [hand.dbid_hands, hand.dbid_pids[pname], streetId, boardId, hl, rankId, value, _cards, 0] )
except RuntimeError:
log.error("assembleHandsStove: error determining value and rank for hand %s %s" % (hand.handid, hand.in_path))
self.handsstove.append( [hand.dbid_hands, hand.dbid_pids[pname], streetId, boardId, 'n', 1, 0, None, 0] )
else:
self.handsstove.append( [hand.dbid_hands, hand.dbid_pids[pname], streetId, boardId, 'n', 1, 0, None, 0] )
else:
Expand Down Expand Up @@ -467,14 +471,18 @@ def getAllInEV(self, hand, evalgame, holeplayers, boards, streets, holecards):
if len(players) == len(valid) and (board['allin'] or hand.publicDB):
if board['allin'] and not startstreet: startstreet = street
if len(valid) > 1:
evs = pokereval.poker_eval(
game = evalgame,
iterations = Card.iter[streetId],
pockets = [holecards[p]['hole'] for p in valid],
dead = deadcards,
board = [str(b) for b in board['board'][n]] + (5 - len(board['board'][n])) * ['__']
)
equities = [e['ev'] for e in evs['eval']]
try:
evs = pokereval.poker_eval(
game = evalgame,
iterations = Card.iter[streetId],
pockets = [holecards[p]['hole'] for p in valid],
dead = deadcards,
board = [str(b) for b in board['board'][n]] + (5 - len(board['board'][n])) * ['__']
)
equities = [e['ev'] for e in evs['eval']]
except RuntimeError:
log.error("getAllInEV: error running poker_eval for hand %s %s" % (hand.handid, hand.in_path))
equities = [1000]
else:
equities = [1000]
remainder = (1000 - sum(equities)) / Decimal(len(equities))
Expand All @@ -483,7 +491,7 @@ def getAllInEV(self, hand, evalgame, holeplayers, boards, streets, holecards):
p = valid[i]
pid = hand.dbid_pids[p]
if street == startstreet:
rake = Decimal(0) if hand.cashedOut else (hand.rake * (Decimal(pot)/Decimal(hand.totalpot)))
rake = hand.rake * (Decimal(pot)/Decimal(hand.totalpot))
holecards[p]['eq'] += ((pot - rake) * equities[i])/Decimal(10)
holecards[p]['committed'] = 100*hand.pot.committed[p] + 100*hand.pot.common[p]
for j in self.handsstove:
Expand Down Expand Up @@ -534,7 +542,7 @@ def getBoardsDict(self, hand, base, streets):
runitcards += hand.board[street_i]
sId = len(boardcards + runitcards) - 3
boardStreets[sId].append(boardcards + runitcards)
for i in range(len(boardStreets)):
for i in range(len([b for b in boardStreets if len(b)>0])):
if boardStreets[i]:
boards[allInStreets[i+1]]['board'] = boardStreets[i]
else:
Expand Down Expand Up @@ -652,6 +660,10 @@ def assembleHandsPots(self, hand):
):
#print 'DEBUG hand.collected', hand.collected
#print 'DEBUG hand.collectees', hand.collectees
if not hand.cashedOut:
for p in hand.players:
self.handsplayers[p[1]]['rake'] = 0
hand.rake = 0
rakes, totrake, potId = {}, 0, 0
for pot, players in hand.pot.pots:
if potId ==0: pot += (sum(hand.pot.common.values()) + hand.pot.stp)
Expand Down Expand Up @@ -704,7 +716,6 @@ def assembleHandsPots(self, hand):
potFound[pname][0] += ppot
data = {'potId': potId, 'boardId': boardId, 'hiLo': hl,'ppot':ppot, 'winners': [m for m in pnames if pname!=n], 'mod': ppot>potSplit}
playersPots[pname][1].append(data)
self.handsplayers[pname]['rake'] = 0

for p, (total, info) in playersPots.iteritems():
#log.error((p, (total, info)))
Expand Down Expand Up @@ -733,7 +744,9 @@ def assembleHandsPots(self, hand):
potFound[p][1] -= collected
insert = [None, item['potId'], item['boardId'], item['hiLo'][0], hand.dbid_pids[p], int(item['ppot']*100), int(collected*100), int(rake*100)]
self.handspots.append(insert)
self.handsplayers[p]['rake'] += int(rake*100)
if not hand.cashedOut:
self.handsplayers[p]['rake'] += int(rake*100)
hand.rake += rake

def setPositions(self, hand):
"""Sets the position for each player in HandsPlayers
Expand Down Expand Up @@ -1289,7 +1302,7 @@ def foldTofirstsBetOrRaiser(self, actions, street, aggressor):
players[act[0]] = False
if act[1] == 'raises' or act[1] == 'completes':
break
elif act[1]!='discards':
elif act[1] not in ('discards','stands pat'):
i+=1
return players

Expand Down
10 changes: 9 additions & 1 deletion pyfpdb/GGPokerToFpdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ class GGPoker(HandHistoryConverter):
and\stheir\sown\sbounty\sincreases\sby\s%(CUR)s(?P<INCREASE>[\.0-9]+)\sto\s%(CUR)s(?P<ENDAMT>[\.0-9]+)$"""
% substitutions, re.MULTILINE|re.VERBOSE)
re_Rake = re.compile(u"""
Total\spot\s%(CUR)s(?P<POT>[,\.0-9]+)(.+?)?\s\|\sRake\s%(CUR)s(?P<RAKE>[,\.0-9]+)"""
Total\spot\s%(CUR)s(?P<POT>[,\.0-9]+)(.+?)?\s\|\sRake\s%(CUR)s(?P<RAKE>[,\.0-9]+)(\s\|\sJackpot\s%(CUR)s(?P<JACKPOT>[,\.0-9]+))?(\s\|\ssBingo\s%(CUR)s(?P<BINGO>[,\.0-9]+))?"""
% substitutions, re.MULTILINE|re.VERBOSE)

re_STP = re.compile(u"""
Expand Down Expand Up @@ -683,6 +683,14 @@ def readCollectPot(self,hand):
for m in self.re_CollectPot4.finditer(pre):
pot = '-' + self.clearMoneyString(m.group('POT'))
hand.addCollectPot(player=m.group('PNAME'),pot=pot)
if hand.cashedOut:
m = self.re_Rake.search(post)
if m:
hand.rake = Decimal(m.group('RAKE'))
if m.group('JACKPOT'):
hand.rake += Decimal(m.group('JACKPOT'))
if m.group('BINGO'):
hand.rake += Decimal(m.group('BINGO'))

def readShownCards(self,hand):
for m in self.re_ShownCards.finditer(hand.handText):
Expand Down
13 changes: 11 additions & 2 deletions pyfpdb/Hand.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,9 @@ def addBlind(self, player, blindtype, amount):

street = 'BLAH'

if self.gametype['base'] == 'hold':
if self.gametype['category'] == 'aof_omaha':
street = 'FLOP'
elif self.gametype['base'] == 'hold':
street = 'PREFLOP'
elif self.gametype['base'] == 'draw':
street = 'DEAL'
Expand Down Expand Up @@ -1098,6 +1100,11 @@ def __init__(self, config, hhc, sitename, gametype, handText, builtFrom = "HHC",
self.discardStreets = ['PREFLOP']
self.communityStreets = ['FLOP', 'TURN', 'RIVER']
self.actionStreets = ['BLINDSANTES','PREFLOP','FLOP','TURN','RIVER']
if gametype['category']=='aof_omaha':
self.allStreets = ['BLINDSANTES','FLOP','TURN','RIVER']
self.holeStreets = ['FLOP']
self.communityStreets = ['FLOP', 'TURN', 'RIVER']
self.actionStreets = ['BLINDSANTES','FLOP','TURN','RIVER']
Hand.__init__(self, self.config, sitename, gametype, handText, builtFrom = "HHC")
self.sb = gametype['sb']
self.bb = gametype['bb']
Expand Down Expand Up @@ -1157,7 +1164,9 @@ def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False, st
if shown: self.shown.add(player)
if mucked: self.mucked.add(player)
else:
if len(cards) in (2, 3, 4, 6) or self.gametype['category'] in ('5_omahahi', '5_omaha8', 'cour_hi', 'cour_hilo'): # avoid adding board by mistake (Everleaf problem)
if self.gametype['category'] == 'aof_omaha':
self.addHoleCards('FLOP', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
elif len(cards) in (2, 3, 4, 6) or self.gametype['category'] in ('5_omahahi', '5_omaha8', 'cour_hi', 'cour_hilo'): # avoid adding board by mistake (Everleaf problem)
self.addHoleCards('PREFLOP', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
elif len(cards) == 5: # cards holds a winning hand, not hole cards
# filter( lambda x: x not in b, a ) # calcs a - b where a and b are lists
Expand Down
3 changes: 2 additions & 1 deletion pyfpdb/HandHistoryConverter.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,8 @@ def readOther(self, hand): pass
# Some sites don't report the rake. This will be called at the end of the hand after the pot total has been calculated
# an inheriting class can calculate it for the specific site if need be.
def getRake(self, hand):
hand.rake = hand.totalpot - hand.totalcollected # * Decimal('0.05') # probably not quite right
if hand.rake is None:
hand.rake = hand.totalpot - hand.totalcollected # * Decimal('0.05') # probably not quite right
if self.siteId == 9 and hand.gametype['type'] == "tour":
round = -5 #round up to 10
elif hand.gametype['type'] == "tour":
Expand Down
20 changes: 14 additions & 6 deletions pyfpdb/KingsClubToFpdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class KingsClub(HandHistoryConverter):

re_Rake = re.compile(r"^Rake\s(?P<RAKE>[,.0-9]+)$", re.MULTILINE)
re_Split = re.compile(r"\*\*\* BOARD 1 - FLOP \*\*\*")
re_Table = re.compile(r"^\s?Table\s(ID\s)?\'(?P<TABLE>.+?)\'\s", re.MULTILINE|re.VERBOSE)

def compilePlayerRegexs(self, hand):
players = set([player[1] for player in hand.players])
Expand Down Expand Up @@ -266,9 +267,13 @@ def determineGameType(self, handText):

m2 = self.re_Split.search(handText)
if m2:
info['split'] = True
info['split'] = True
else:
info['split'] = False

m3 = self.re_Table.search(handText)
if m3 and 'AOF' in m3.group('TABLE'):
info['category'] = 'aof_omaha'

if info['limitType'] == 'fl' and info['bb'] is not None:
if info['type'] == 'ring':
Expand Down Expand Up @@ -432,11 +437,14 @@ def markStreets(self, hand):
r"(\*\*\* BOARD 1 - RIVER \*\*\* \[(?P<FLOP1>\S\S \S\S \S\S) (?P<TURN1>\S\S)] (?P<RIVER1>\[\S\S\].+(?=\*\*\* BOARD 2 - RIVER \*\*\*)|.+))"
r"(\*\*\* BOARD 2 - RIVER \*\*\* \[(?P<FLOP2>(\S\S|\-) (\S\S|\-) (\S\S|\-)) (?P<TURN2>(\S\S|\-))] (?P<RIVER2>\[\S\S\].+))", post,re.DOTALL)
if m1:
if hand.streets.get('FLOP') is None:
if hand.streets.get('FLOP') is None or re.search(r"\*\*\* BOARD 1 - FLOP \*\*\*", post,re.DOTALL):
hand.streets.update({'FLOP1': m1.group('FLOP1'),'FLOP2': m1.group('FLOP2')})
if hand.streets.get('TURN') is None:
hand.streets['FLOP'] = []
if hand.streets.get('TURN') is None or re.search(r"\*\*\* BOARD 1 - TURN \*\*\*", post,re.DOTALL):
hand.streets.update({'TURN1': m1.group('TURN1'),'TURN2': m1.group('TURN2')})
hand.streets['TURN'] = []
hand.streets.update({'RIVER1': m1.group('RIVER1'),'RIVER2': m1.group('RIVER2')})
hand.streets['RIVER'] = []
else:
m2 = re.search(
r"(\*\*\* RIVER \*\*\* \[(?P<FLOP>\S\S \S\S \S\S) (?P<TURN>\S\S)] (?P<RIVER>\[\S\S\].+(?=\*\*\* SUMMARY \*\s?\*\*)|.+))", post,re.DOTALL)
Expand Down Expand Up @@ -534,7 +542,8 @@ def readHoleCards(self, hand):
newcards = [x for x in found.group('NEWCARDS').split(' ') if x != 'X']
if len(newcards)>0:
hand.hero = found.group('PNAME')
hand.addHoleCards(street, hand.hero, closed=newcards, shown=False, mucked=False, dealt=True)
_street = 'FLOP' if hand.gametype['category'] == 'aof_omaha' else street
hand.addHoleCards(_street, hand.hero, closed=newcards, shown=False, mucked=False, dealt=True)

for street, text in hand.streets.iteritems():
if not text or street in ('PREFLOP', 'DEAL'): continue # already done these
Expand Down Expand Up @@ -628,8 +637,7 @@ def readShowdownActions(self, hand):
pass

def readCollectPot(self,hand):
if ((hand.gametype['category'] == '27_1draw' and hand.gametype['limitType'] == 'nl') or
hand.gametype['base'] == 'stud'):
if ((hand.gametype['category'] == '27_1draw' and hand.gametype['limitType'] == 'nl')):
hand.adjustCollected = False
else:
hand.adjustCollected = True
Expand Down
2 changes: 1 addition & 1 deletion pyfpdb/PacificPokerSummary.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class PacificPokerSummary(TourneySummary):
'NUM' : u".,\d\xa0" # legal characters in number format
}

re_Identify = re.compile(u'\*{5}\s(Cassava|888poker|888)(\.[a-z]{2})?(\-[a-z]{2})? Tournament Summary\s\*{5}')
re_Identify = re.compile(u'\*{5}\s(Cassava|888poker|888)?(\.[a-z]{2})?(\-[a-z]{2})? ?Tournament Summary\s\*{5}')

re_TourneyInfo = re.compile(u"""
Tournament\sID:\s(?P<TOURNO>[0-9]+)\s+
Expand Down
5 changes: 4 additions & 1 deletion pyfpdb/PacificPokerToFpdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ def readHandInfo(self, hand):
datetimestr = "%s/%s/%s %s:%s:%s" % (a.group('Y'), a.group('M'),a.group('D'),a.group('H'),a.group('MIN'),a.group('S'))
hand.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S")
hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, "ET", "UTC")
hand.newFormat = datetime.datetime.strptime('20220908000000','%Y%m%d%H%M%S') #this is a guess
hand.newFormat = HandHistoryConverter.changeTimezone(hand.newFormat, "ET", "UTC")
if key == 'HID':
hand.handid = info[key]
if key == 'TOURNO' and info['TOURNO'] != None:
Expand Down Expand Up @@ -350,7 +352,8 @@ def readBringIn(self, hand):
hand.addBringIn(m.group('PNAME'), m.group('BRINGIN'))

def readBlinds(self, hand):
hand.setUncalledBets(True)
if hand.startTime < hand.newFormat:
hand.setUncalledBets(True)
liveBlind, hand.allInBlind = True, False
for a in self.re_PostSB.finditer(hand.handText):
if a.group('PNAME') in hand.stacks:
Expand Down
2 changes: 1 addition & 1 deletion pyfpdb/PartyPokerToFpdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def compilePlayerRegexs(self, hand):
r"%(PLYR)s posts button blind ?[%(BRAX)s]?%(CUR_SYM)s?(?P<BUB>[.,0-9]+)\s*%(CUR)s?[%(BRAX)s]?\.?\s*$" % subst,
re.MULTILINE)
self.re_Antes = re.compile(
r"%(PLYR)s posts ante( of)? [%(BRAX)s]?%(CUR_SYM)s(?P<ANTE>[.,0-9]+)\s*%(CUR)s[%(BRAX)s]?\.?\s*$" % subst,
r"%(PLYR)s posts ante( of)? [%(BRAX)s]?%(CUR_SYM)s?(?P<ANTE>[.,0-9]+)\s*(%(CUR)s)?[%(BRAX)s]?\.?\s*$" % subst,
re.MULTILINE)
self.re_HeroCards = re.compile(
r"Dealt to %(PLYR)s \[\s*(?P<NEWCARDS>.+)\s*\]" % subst,
Expand Down
Loading