Use debian 2.7 only
[fpbd-bostik.git] / pyfpdb / MergeToFpdb.py
blobfec79aeb041fd9eb74e8f9c9d31259bfc5655d8e
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 # Copyright 2010-2011, Matthew Boss
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 ########################################################################
22 import L10n
23 _ = L10n.get_translation()
25 # TODO:
27 # -- Assumes that the currency of ring games is USD
28 # -- Only accepts 'realmoney="true"'
29 # -- A hand's time-stamp does not record seconds past the minute (a limitation of the history format)
30 # -- hand.maxseats can only be guessed at
31 # -- Cannot parse tables that run it twice
32 # -- Cannot parse hands in which someone is all in in one of the blinds.
34 import sys
35 from HandHistoryConverter import *
36 from decimal_wrapper import Decimal
39 class Merge(HandHistoryConverter):
40 sitename = "Merge"
41 filetype = "text"
42 codepage = ("cp1252", "utf8")
43 siteId = 11
44 copyGameHeader = True
46 limits = { 'No Limit':'nl', 'No Limit ':'nl', 'Limit':'fl', 'Pot Limit':'pl', 'Pot Limit ':'pl', 'Half Pot Limit':'hp'}
47 games = { # base, category
48 'Holdem' : ('hold','holdem'),
49 'Omaha' : ('hold','omahahi'),
50 'Omaha H/L8' : ('hold','omahahilo'),
51 '2-7 Lowball' : ('draw','27_3draw'),
52 'A-5 Lowball' : ('draw','a5_3draw'),
53 'Badugi' : ('draw','badugi'),
54 '5-Draw w/Joker' : ('draw','fivedraw'),
55 '5-Draw' : ('draw','fivedraw'),
56 '7-Stud' : ('stud','studhi'),
57 '7-Stud H/L8' : ('stud','studhilo'),
58 '5-Stud' : ('stud','5studhi'),
59 'Razz' : ('stud','razz'),
61 Lim_Blinds = { '0.04': ('0.01', '0.02'), '0.10': ('0.02', '0.05'),
62 '0.20': ('0.05', '0.10'),
63 '0.25': ('0.05', '0.10'), '0.50': ('0.10', '0.25'),
64 '1.00': ('0.25', '0.50'), '1': ('0.25', '0.50'),
65 '2.00': ('0.50', '1.00'), '2': ('0.50', '1.00'),
66 '4.00': ('1.00', '2.00'), '4': ('1.00', '2.00'),
67 '6.00': ('1.50', '3.00'), '6': ('1.50', '3.00'),
68 '8.00': ('2.00', '4.00'), '8': ('2.00', '4.00'),
69 '10.00': ('2.00', '5.00'), '10': ('2.00', '5.00'),
70 '20.00': ('5.00', '10.00'), '20': ('5.00', '10.00'),
71 '30.00': ('10.00', '15.00'), '30': ('10.00', '15.00'),
72 '40.00': ('10.00', '20.00'), '40': ('10.00', '20.00'),
73 '50.00': ('10.00', '25.00'), '50': ('10.00', '25.00'),
74 '60.00': ('15.00', '30.00'), '60': ('15.00', '30.00'),
75 '100.00': ('25.00', '50.00'), '100': ('25.00', '50.00'),
78 Multigametypes = { '2': ('hold','holdem'),
79 '4': ('hold','omahahi'),
80 '47': ('stud','razz'),
81 '39': ('stud','studhi'),
82 '43': ('stud','studhilo'),
86 SnG_Structures = { '$1 NL Holdem Double Up - 10 Handed' : {'buyIn': 1, 'fee': 0.08, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (2,2,2,2,2)},
87 '$10 Bounty SnG - 10 Handed' : {'buyIn': 5, 'fee': 1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (25, 15, 10)},
88 '$10 NL Holdem Double Up - 10 Handed' : {'buyIn': 10, 'fee': 0.8, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,20,20,20,20)},
89 '$10 PL Omaha Double Up - 10 Handed' : {'buyIn': 10, 'fee': 0.8, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,20,20,20,20)},
90 '$10 Winner Takes All - $60 Coupon' : {'buyIn': 10, 'fee': 0.8, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (60,)},
91 '$100 Bounty SnG - 6 Handed' : {'buyIn': 100, 'fee': 9, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (315, 135)},
92 '$100 NL Holdem Double Up - 10 Handed' : {'buyIn': 100, 'fee': 8, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (200,200,200,200,200)},
93 '$100 PL Omaha Double Up - 10 Handed' : {'buyIn': 100, 'fee': 8, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (200,200,200,200,200)},
94 '$100,000 Guaranteed - Super Turbo Satellite' : {'buyIn': 38.8, 'fee': 0.8, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (109,109,11,3.8)},
95 '$10 Bounty SnG - 6 Handed' : {'buyIn': 5, ' fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (25, 15, 10)},
96 '$10 Satellite' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (60,)},
97 '$100 Bounty SnG - 6 Handed' : {'buyIn': 100, 'fee': 9, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (315, 135)},
98 '$2 Bounty SnG - 10 Handed' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,6,4)},
99 '$2 Bounty SnG - 6 Handed' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (7, 3, 2)},
100 '$2 NL Holdem All-In or Fold 10 - Handed' : {'buyIn': 2, 'fee': 0.16, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,6,4)},
101 '$2 NL Holdem Double Up - 10 Handed' : {'buyIn': 2, 'fee': 0.16, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (4,4,4,4,4)},
102 '$2 Satellite' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 5, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (11,)},
103 '$20 Bounty SnG - 10 Handed' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (50, 30, 30)},
104 '$20 Bounty SnG - 6 Handed' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (50, 30, 30)},
105 '$20 Daily Deep Stack Satellite' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (109, 11)},
106 '$20 NL Holdem Double Up - 10 Handed' : {'buyIn': 20, 'fee': 1.6, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (40,40,40,40,40)},
107 '$3 NL Holdem Double Up - 10 Handed' : {'buyIn': 3, 'fee': 0.24, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (6,6,6,6,6)},
108 '$30 Bounty SnG - 6 Handed' : {'buyIn': 30, 'fee': 3, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (84, 36)},
109 '$5 Bounty SnG - 10 Handed' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (12.50, 7.50, 5)},
110 '$5 Bounty SnG - 6 Handed' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (14, 6)},
111 '$5 NL Holdem Double Up - 6 Handed' : {'buyIn': 5, 'fee': 0.4, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,10,10)},
112 '$5 NL Holdem Double Up - 10 Handed' : {'buyIn': 5, 'fee': 0.4, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,10,10,10,10)},
113 '$5 PL Omaha Double Up - 10 Handed' : {'buyIn': 5, 'fee': 0.4, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,10,10,10,10)},
114 '$50 NL Holdem Double Up - 10 Handed' : {'buyIn': 50, 'fee': 4, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,10,10,10,10)},
115 '$50 PL Omaha Double Up - 10 Handed' : {'buyIn': 50, 'fee': 4, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,10,10,10,10)},
116 '$55 Turbo - 6 Max' : {'buyIn': 50, 'fee': 4, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (210, 90)},
117 '$60 Daily High Roller SnG Satellite' : {'buyIn': 55, 'fee': 5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (215, 115)},
118 '$75 Bounty SnG - 6 Handed' : {'buyIn': 75, 'fee': 7.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (210, 90)},
119 '$82 Turbo - 6 Max' : {'buyIn': 75, 'fee': 7, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (315, 135)},
120 '100 VIP Point SnG' : {'buyIn': 1, 'fee': 0.05, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (0,0)},
121 '250 VIP Point SnG' : {'buyIn': 2.5, 'fee': 0.15, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (0,0)},
122 '500 VIP Point SnG' : {'buyIn': 5, 'fee': 0.25, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (0,0)},
123 'Aardvark Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 9, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (45,27,18)},
124 'Alligator Room - Heads Up' : {'buyIn': 100, 'fee': 4.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (200,)},
125 'Alligator Room - Turbo Heads Up' : {'buyIn': 110, 'fee': 4.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (220,)},
126 'Alpaca Room - Turbo' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42, 18)},
127 'Anaconda Room - Heads Up' : {'buyIn': 100, 'fee': 4.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (200,)},
128 'Anaconda Room - Turbo Heads Up' : {'buyIn': 110, 'fee': 4.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (220,)},
129 'Anteater Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42, 18)},
130 'Antelope Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
131 'Arctic Fox Room - Heads Up' : {'buyIn': 2, 'fee': 0.1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (4,)},
132 'Armadillo Room' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (100, 60, 40)},
133 'Aussie Millions - Super Turbo Satelite': {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (60,)},
134 'Axolotyl Room - Heads Up' : {'buyIn': 30, 'fee': 1.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (60,)},
135 'Axolotyl Room - Turbo Heads Up' : {'buyIn': 33, 'fee': 1.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (66,)},
136 'Badger Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (50, 30, 20)},
137 'Bandicoot Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (8.40, 3.60)},
138 'Bear Room' : {'buyIn': 50, 'fee': 5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (210, 90)},
139 'Bear Room - Heads Up' : {'buyIn': 200, 'fee': 9, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (400,)},
140 'Bear Room - Turbo Heads Up' : {'buyIn': 220, 'fee': 9, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (440,)},
141 'Beaver Room' : {'buyIn': 5, ' fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
142 'Beaver Room 12 min levels' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
143 'Beaver Room 12 min levels Short Handed' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
144 'Bilby Room - Heads Up' : {'buyIn': 5, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,)},
145 'Bilby Room - Turbo Heads Up' : {'buyIn': 7, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (14,)},
146 'Bison Room - Heads Up' : {'buyIn': 50, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (100,)},
147 'Bison Room - Turbo Heads Up' : {'buyIn': 55, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (110,)},
148 'Black Bear Room Turbo Heads Up (4 players)' : {'buyIn': 4, 'fee': 0.6, 'currency': 'USD', 'seats': 4, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (48,)},
149 'Black Mamba Room - Super Turbo' : {'buyIn': 12, 'fee': 52, 'currency': 'USD', 'seats': 2, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (312, 187.2, 124.8)},
150 'Boar Room - Heads Up' : {'buyIn': 20, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (40,)},
151 'Boar Room - Turbo Heads Up' : {'buyIn': 22, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (44,)},
152 'Bobcat Room' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (84, 36)},
153 'Botfly Room - Super Turbo HU' : {'buyIn': 8, 'fee': 0.2, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (16,)},
154 'Buffalo Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42, 18)},
155 'Buffalo Room - Heads Up' : {'buyIn': 300, 'fee': 12, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (600,)},
156 'Buffalo Room - Turbo Heads Up' : {'buyIn': 330, 'fee': 12, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (660,)},
157 'Bumblebee Room - Super Turbo' : {'buyIn': 0.1, 'fee': 0.01, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (0.42, 0.18)},
158 'Bunyip Room - Heads Up' : {'buyIn': 100, 'fee': 4.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (200,)},
159 'Bushmaster Room Super Turbo HU' : {'buyIn': 250, 'fee': 4, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (500,)},
160 'Caiman Room' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (84, 36)},
161 'Camel Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42, 18)},
162 'Cape Hunting Dog Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 45, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (27.90, 19.35, 14.85, 11.25, 8.10, 5.40, 3.15)},
163 'Capra room - Heads Up' : {'buyIn': 5, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,)},
164 'Capybara Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
165 'Cassowary Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (25, 15, 10)},
166 'Cobra Room - Heads Up' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,)},
167 'Cobra Room - Turbo Heads Up' : {'buyIn': 11, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (22,)},
168 'Condor Room - Heads Up' : {'buyIn': 30, 'fee': 1.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (60,)},
169 'Condor Room - Turbo Heads Up' : {'buyIn': 33, 'fee': 1.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (66,)},
170 'Conga Eel Room - Super Turbo HU' : {'buyIn': 120, 'fee': 2.3, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (240,)},
171 'Cougar Room - Heads Up' : {'buyIn': 20, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (40,)},
172 'Cougar Room - Turbo Heads Up' : {'buyIn': 22, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (44,)},
173 'Coyote Room - Super Turbo' : {'buyIn': 50, 'fee': 2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (210, 90)},
174 'Cricket Room - Super Turbo 6 Max' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 18, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (14.40, 10.8, 7.2, 3.6)},
175 'Crocodile Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 18, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (36, 27, 18, 9)},
176 'Daily High Roller - Super Turbo Satellite' : {'buyIn': 72, 'fee': 1.3, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (215, 215, 2)},
177 'Dingo Room - Heads Up' : {'buyIn': 50, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (100,)},
178 'Dingo Room - Turbo Heads Up' : {'buyIn': 55, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (110,)},
179 'Dollar Dazzler Turbo' : {'buyIn': 1, 'fee': 0.1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (5, 3, 2)},
180 'Dolphin Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10, 6, 4)},
181 'Dragon Room' : {'buyIn': 100, 'fee': 9, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (420, 180)},
182 'Dragonfly Room - Super Turbo' : {'buyIn': 2, 'fee': 0.12, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (8.40, 3.60)},
183 'Dugong Room' : {'buyIn': 50, 'fee': 5, 'currency': 'USD', 'seats': 9, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (225, 135, 90)},
184 'Eagle Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42, 18)},
185 'Eagle Room 12 min levels' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (50, 30, 20)},
186 'Eagle Room 12 min levels Short Handed' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42, 18)},
187 'Echidna Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
188 'Elephant Room - Heads Up' : {'buyIn': 100, 'fee': 4.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (200,)},
189 'Elephant Room - Turbo Heads Up' : {'buyIn': 110, 'fee': 4.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (220,)},
190 'Elephant Shrew Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 9, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (9, 5.40, 3.60)},
191 'Elk Room' : {'buyIn': 50, 'fee': 5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (210, 90)},
192 'Emu Room - Heads Up' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,)},
193 'Emu Room - Turbo Heads Up' : {'buyIn': 11, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (22,)},
194 'Falcon Room' : {'buyIn': 50, 'fee': 5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (250, 150, 100)},
195 'Falcon Room Turbo' : {'buyIn': 50, 'fee': 5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (250, 150, 100)},
196 'Fast Fifty SnG' : {'buyIn': 0.5, 'fee': 0.1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (2.50, 1.50, 1)},
197 'Fast Fifty Turbo' : {'buyIn': 0.5, 'fee': 0.1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (2.50, 1.50, 1)},
198 'Ferret Room - Turbo' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (50, 30, 20)},
199 'Fox Room - Heads Up' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,)},
200 'Fox Room - Turbo Heads Up' : {'buyIn': 11, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (22,)},
201 'Frigate Bird Room Super Turbo HU' : {'buyIn': 2, 'fee': 0.1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (4,)},
202 'Fruit Fly Room - Super Turbo' : {'buyIn': 1, 'fee': 0.06, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (4.20, 1.80)},
203 'Fusilier Room Turbo' : {'buyIn': 1, 'fee': 0.1, 'currency': 'USD', 'seats': 45, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (13.96, 9.68, 7.42, 5.62, 4.05, 2.70, 1.57)},
204 'Fun Step 1' : {'buyIn': 0, 'fee': 0, 'currency': 'FREE', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (0, 0, 0)},
205 'Fun Step 2' : {'buyIn': 0, 'fee': 0, 'currency': 'FREE', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (0, 0, 0)},
206 'Fun Step 3' : {'buyIn': 0, 'fee': 0, 'currency': 'FREE', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1, 0, 0)},
207 'Gazelle Room - Super Turbo' : {'buyIn': 100, 'fee': 3.7, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (420, 180)},
208 'Gecko Room' : {'buyIn': 30, 'fee': 3, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (150, 90, 60)},
209 'Gecko Room Turbo' : {'buyIn': 30, 'fee': 3, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (150, 90, 60)},
210 'Gibbon Room' : {'buyIn': 200, 'fee': 15, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (840, 360)},
211 'Giraffe Room' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (84, 36)},
212 'Goldfish Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (8.40, 3.60)},
213 'Gopher Room - Turbo' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (8.40, 3.60)},
214 'Gorilla Room - Heads Up' : {'buyIn': 20, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (40,)},
215 'Gnat Room - Super Turbo HU' : {'buyIn': 4, 'fee': 0.15, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (8,)},
216 'Goblin Shark Room' : {'buyIn': 150, 'fee': 2.75, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (300,)},
217 'Golden Eagle Turbo HU' : {'buyIn': 22, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (44,)},
218 'Goldfish Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (8.40, 3.60)},
219 'Great White Shark Room - Heads Up' : {'buyIn': 2000, 'fee': 40, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (4000,)},
220 'Great White Shark Room - Turbo Heads Up' : {'buyIn': 2200, 'fee': 40, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (4400,)},
221 'Grey Wolf Room Turbo HU (4 players)' : {'buyIn': 18, 'fee': 0.9, 'currency': 'USD', 'seats': 4, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (72,)},
222 'Greyhound Room - Super Turbo' : {'buyIn': 35, 'fee': 1.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (147, 63)},
223 'Grizzly Room' : {'buyIn': 30, 'fee': 3, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (126, 54)},
224 'Guinea Pig Room - Super Turbo' : {'buyIn': 5, 'fee': 0.3, 'currency': 'USD', 'seats': 12, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (30, 18, 12)},
225 'Hairy Frog Room - Super Turbo HU' : {'buyIn': 28, 'fee': 0.7, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (56,)},
226 'Hare Room - Super Turbo' : {'buyIn': 20, 'fee': 0.9, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (84, 36)},
227 'Hedgehog Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 9, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (22.50, 13.50, 9)},
228 'Heron Room' : {'buyIn': 300, 'fee': 20, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1260, 540)},
229 'Hippo Room - Heads Up' : {'buyIn': 50, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (100,)},
230 'Hippo Room - Turbo Heads Up' : {'buyIn': 55, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (110,)},
231 'Honey Badger Room' : {'buyIn': 5, 'fee': 5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
232 'Howler Monkey Room - Super Turbo' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 12, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (60, 36, 24)},
233 'Hummingbird Room - Super Turbo' : {'buyIn': 5, 'fee': 0.3, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
234 'Hyena Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10, 6, 4)},
235 'Ibex Room - Super Turbo HU' : {'buyIn': 180, 'fee': 3.1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (360,)},
236 'Iguana Room - Heads Up' : {'buyIn': 20, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (40,)},
237 'Iguana Room - Turbo Heads Up' : {'buyIn': 22, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (44,)},
238 'Impala Room' : {'buyIn': 30, 'fee': 3, 'currency': 'USD', 'seats': 9, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (135, 81, 54)},
239 'Jaguar Room' : {'buyIn': 50, 'fee': 5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (210, 90)},
240 'Killer Whale Room - Super Turbo' : {'buyIn': 500, 'fee': 12, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (2100, 900)},
241 'King Cobra Room - Super Turbo HU' : {'buyIn': 500, 'fee': 7.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1000,)},
242 'Komodo Room' : {'buyIn': 50, 'fee': 5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (210, 90)},
243 'Kookaburra Room - Heads Up' : {'buyIn': 20, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (40,)},
244 'Kookaburra Room - Turbo Heads Up' : {'buyIn': 22, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (44,)},
245 'Lemming Room - Super Turbo HU' : {'buyIn': 40, 'fee': 0.8, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (80,)},
246 'Lemur Room - Super Turbo HU' : {'buyIn': 55, 'fee': 1.1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (110,)},
247 'Leopard Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
248 'Leopard Seal Room - Heads Up' : {'buyIn': 30, 'fee': 1.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (60,)},
249 'Lizard Room - Turbo' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (84, 36)},
250 'Lynx Room' : {'buyIn': 110, 'fee': 9, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (462, 198)},
251 'Mako Room' : {'buyIn': 75, 'fee': 7, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (375, 225, 150)},
252 'Mako Room Turbo' : {'buyIn': 75, 'fee': 7, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (375, 225, 150)},
253 'Marlin Room - Super Turbo' : {'buyIn': 350, 'fee': 10, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1470, 630)},
254 'Meerkat Room - Turbo' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (8.40, 3.60)},
255 'Mink Room - Heads Up' : {'buyIn': 5, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,)},
256 'Mink Room - Turbo Heads Up' : {'buyIn': 7, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (14,)},
257 'Mountain Goat Room Turbo HU (4 players)' : {'buyIn': 6, 'fee': 0.3, 'currency': 'USD', 'seats': 4, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (24,)},
258 'Mongoose Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10, 6, 4)},
259 'Monkey Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 9, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (90, 54, 36)},
260 'Mountain Lion Turbo HU' : {'buyIn': 75, 'fee': 3.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (150,)},
261 'Mouse Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10, 6, 4)},
262 'Musk Rat Room ' : {'buyIn': 3, 'fee': 0.3, 'currency': 'USD', 'seats': 8, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (16.80, 7.20)},
263 'Ocelot Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 8, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (56, 24)},
264 'Orangutan Room' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (84, 36)},
265 'Otter Room - Turbo' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (21, 9)},
266 'Ox Room - Turbo' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (100, 60, 40)},
267 'Panda Room - Heads Up' : {'buyIn': 100, 'fee': 4.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (200,)},
268 'Panda Room - Turbo Heads Up' : {'buyIn': 110, 'fee': 4.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (220,)},
269 'Panther Room - Heads Up' : {'buyIn': 500, 'fee': 20, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1000,)},
270 'Panther Room - Turbo Heads Up' : {'buyIn': 550, 'fee': 20, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1100,)},
271 'Peregrine Room' : {'buyIn': 330, 'fee': 20, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1386, 594)},
272 'Pilchard Room Turbo' : {'buyIn': 1, 'fee': 0.1, 'currency': 'USD', 'seats': 18, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (7.20, 5.40, 3.60, 1.80)},
273 'Piranha Room - Heads Up' : {'buyIn': 50, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (100,)},
274 'Piranha Room - Turbo Heads Up' : {'buyIn': 55, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (110,)},
275 'Pond Skater Room - Super Turbo HU' : {'buyIn': 15, 'fee': 0.3, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (30,)},
276 'Platypus Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (25, 15, 10)},
277 'Pronghorn Antelope Room - Super Turbo HU' : {'buyIn': 1000, 'fee': 15, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (2000,)},
278 'Puffin Room - Super Turbo HU' : {'buyIn': 70, 'fee': 1.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (140,)},
279 'Puma Room - Heads Up' : {'buyIn': 20, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (40,)},
280 'Puma Room - Turbo Heads Up' : {'buyIn': 22, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (44,)},
281 'Rabbit Room - Turbo' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10, 6, 4)},
282 'Racoon Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (25, 15, 10)},
283 'Rattlesnake Room - Heads Up' : {'buyIn': 5, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,)},
284 'Raven Room' : {'buyIn': 180, 'fee': 14, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (756, 324)},
285 'Razorback Room' : {'buyIn': 100, 'fee': 9, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (420, 180)},
286 'Red Kangaroo Room - Heads Up' : {'buyIn': 20, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (40,)},
287 'Rhino Room - Heads Up' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,)},
288 'Rhino Room - Turbo Heads Up' : {'buyIn': 11, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (22,)},
289 'Sailfish Room - Super Turbo' : {'buyIn': 209, 'fee': 7, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (877.80, 376.20)},
290 'Salmon Room' : {'buyIn': 5, 'fee': 0.5, 'currency': 'USD', 'seats': 45, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (69.76, 48.38, 37.12, 28.12, 20.25, 13.50, 7.87)},
291 'Sardine Room Turbo' : {'buyIn': 1, 'fee': 0.1, 'currency': 'USD', 'seats': 27, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (10.27, 7.02, 4.59, 2.75, 2.37)},
292 'Sea Eagle Room Turbo HU (4 players)' : {'buyIn': 24, 'fee': 1.2, 'currency': 'USD', 'seats': 4, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (96,)},
293 'Secretary Bird Room - Super Turbo HU' : {'buyIn': 90, 'fee': 1.8, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (180,)},
294 'Shrew Room - Heads Up' : {'buyIn': 5, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,)},
295 'Shrew Room - Turbo Heads Up' : {'buyIn': 7, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (14,)},
296 "Snakes'n'Ladders Step 1" : {'buyIn': 1, 'fee': 0.1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (3.30, 3.30, 1.10, 1.10, 1.10, 0.10)},
297 "Snakes'n'Ladders Step 2" : {'buyIn': 3, 'fee': 0.3, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (11, 11, 3.30, 3.30, 1.10, 0.30)},
298 "Snakes'n'Ladders Step 3" : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (32.50, 32.50, 11, 11, 3.30, 3.30, 3.30, 1.10, 1.10, 0.90)},
299 "Snakes'n'Ladders Step 4" : {'buyIn': 30, 'fee': 2.5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (80, 80, 80, 32.50, 11, 11, 3.30, 1.10, 1.10)},
300 "Snakes'n'Ladders Step 5" : {'buyIn': 75, 'fee': 5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (265, 265, 80, 80, 32.50, 11, 11, 3.30, 1.10, 1.10)},
301 "Snakes'n'Ladders Step 6" : {'buyIn': 255, 'fee': 10, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (530, 530, 530, 265, 265, 265, 80, 80, 3.30, 1.70)},
302 "Snakes'n'Ladders Step 7" : {'buyIn': 510, 'fee': 20, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (2000, 1250, 750, 499.50, 295, 220, 80, 3.30, 1.10, 1.10)},
303 'Snow Goose Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 45, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (139.50, 96.75, 74.25, 56.25, 40.50, 27, 15.75)},
304 'Springbok Room - Super Turbo' : {'buyIn': 20, 'fee': 0.9, 'currency': 'USD', 'seats': 12, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (120, 72, 48)},
305 'Squirrel Room - Turbo' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (8.40, 3.60)},
306 'Stag Room Turbo HU (4 players)' : {'buyIn': 3, 'fee': 0.15, 'currency': 'USD', 'seats': 4, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (12,)},
307 'Starling Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 180, 'multi': True, 'payoutCurrency': 'USD', 'payouts': (108, 72, 36, 28.80, 21.60, 18, 14.40, 10.80, 8.10, 6.30, 3.60, 3.60, 3.60, 3.60, 3.60, 3.60, 3.60, 3.60, 3.60, 3.60) },
308 'STEP 1 AIOF Sng' : {'buyIn': 1, 'fee': 0.1, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (5.50, 1.10, 1.10, 1.10, 0.20)},
309 'STEP 10 AIOF Final Sng' : {'buyIn': 1170, 'fee': 10, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (2250, 90)},
310 'STEP 2 AIOF Sng' : {'buyIn': 5.25, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10.50,)},
311 'STEP 3 AIOF Sng' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,)},
312 'STEP 4 AIOF Sng' : {'buyIn': 19.5, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (39,)},
313 'STEP 5 AIOF Sng' : {'buyIn': 38.5, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (77,)},
314 'STEP 6 AIOF Sng' : {'buyIn': 76, 'fee': 1, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (152,)},
315 'STEP 7 AIOF Sng' : {'buyIn': 150, 'fee': 2, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (300,)},
316 'STEP 8 AIOF Sng' : {'buyIn': 297, 'fee': 3, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (594,)},
317 'STEP 9 AIOF Sng' : {'buyIn': 590, 'fee': 4, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1180,)},
318 'Sun Bear Room' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 8, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (112, 48)},
319 'Swift Room - Super Turbo' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42, 18)},
320 'Swordfish Room' : {'buyIn': 220, 'fee': 15, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (924, 396)},
321 'Tapir Room' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 8, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (112, 48)},
322 'Termite Room' : {'buyIn': 3, 'fee': 0.3, 'currency': 'USD', 'seats': 8, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (16.80, 7.20)},
323 'Tiger Fish Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 8, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (56, 24,)},
324 'Tiger Room - Heads Up' : {'buyIn': 50, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (100,)},
325 'Tiger Room - Turbo Heads Up' : {'buyIn': 55, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (100,)},
326 'Timber Wolf Room' : {'buyIn': 400, 'fee': 22, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1680, 720)},
327 'Toucan Room - Heads Up' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,)},
328 'Toucan Room - Heads Up' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,)},
329 'Toucan Room - Turbo Heads Up' : {'buyIn': 11, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (22,)},
330 'Tsetse Fly Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (8.4,3.6)},
331 'Turkey Room - Heads Up' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,)},
332 'Turkey Room - Turbo Heads Up' : {'buyIn': 11, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (22,)},
333 'Viper Room - Heads Up' : {'buyIn': 1000, 'fee': 40, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (2000,)},
334 'Vulture Room' : {'buyIn': 20, 'fee': 2, 'currency': 'USD', 'seats': 9, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (90,54,36)},
335 'Wallaby Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42, 18)},
336 'Walrus Room' : {'buyIn': 50, 'fee': 5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (250, 150, 100)},
337 'Warthog Room' : {'buyIn': 2, 'fee': 0.2, 'currency': 'USD', 'seats': 9, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (18, 10.80, 7.20)},
338 'Waterbuck room - Heads Up' : {'buyIn': 10, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (20,)},
339 'Whale Room - Heads Up' : {'buyIn': 500, 'fee': 20, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (1000,)},
340 'Wildebeest Room' : {'buyIn': 10, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42, 18)},
341 'Wolf Spider Room - Super Turbo HU' : {'buyIn': 21, 'fee': 0.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (42,)},
342 'Wolverine Room' : {'buyIn': 50, 'fee': 0.5, 'currency': 'USD', 'seats': 10, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (25, 15, 10)},
343 'Wombat Room' : {'buyIn': 20, 'fee': 1, 'currency': 'USD', 'seats': 6, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (84, 36)},
344 'Yak Room - Heads Up' : {'buyIn': 50, 'fee': 2.5, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (100,)},
345 'Zebra Room - Heads Up' : {'buyIn': 5, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (10,)},
346 'Zebra Room - Turbo Heads Up' : {'buyIn': 7, 'fee': 0.25, 'currency': 'USD', 'seats': 2, 'multi': False, 'payoutCurrency': 'USD', 'payouts': (14,)},
349 # Static regexes
350 re_SplitHands = re.compile(r'</game>\n+(?=<game)')
351 re_TailSplitHands = re.compile(r'(</game>)')
352 re_GameInfo = re.compile(r'<description type="(?P<GAME>Holdem|Omaha|Omaha|Omaha\sH/L8|2\-7\sLowball|A\-5\sLowball|Badugi|5\-Draw\sw/Joker|5\-Draw|7\-Stud|7\-Stud\sH/L8|5\-Stud|Razz|HORSE)(?P<TYPE>\sTournament)?" stakes="(?P<LIMIT>[a-zA-Z ]+)(\s\(?\$?(?P<SB>[.0-9]+)?/?\$?(?P<BB>[.0-9]+)?(?P<blah>.*)\)?)?"/>', re.MULTILINE)
353 # <game id="46154255-645" starttime="20111230232051" numholecards="2" gametype="1" seats="9" realmoney="false" data="20111230|Play Money (46154255)|46154255|46154255-645|false">
354 # <game id="46165919-1" starttime="20111230161824" numholecards="2" gametype="23" seats="10" realmoney="true" data="20111230|Fun Step 1|46165833-1|46165919-1|true">
355 # <game id="46289039-1" starttime="20120101200100" numholecards="2" gametype="23" seats="9" realmoney="true" data="20120101|$200 Freeroll - NL Holdem - 20%3A00|46245544-1|46289039-1|true">
356 re_HandInfo = re.compile(r'<game id="(?P<HID1>[0-9]+)-(?P<HID2>[0-9]+)" starttime="(?P<DATETIME>[0-9]+)" numholecards="[0-9]+" gametype="[0-9]+" (multigametype="(?P<MULTIGAMETYPE>\d+)" )?(seats="(?P<SEATS>[0-9]+)" )?realmoney="(?P<REALMONEY>(true|false))" data="[0-9]+\|(?P<TABLENAME>[^|]+)\|(?P<TDATA>[^|]+)\|?.*>', re.MULTILINE)
357 re_Button = re.compile(r'<players dealer="(?P<BUTTON>[0-9]+)">')
358 re_PlayerInfo = re.compile(r'<player seat="(?P<SEAT>[0-9]+)" nickname="(?P<PNAME>.+)" balance="\$(?P<CASH>[.0-9]+)" dealtin="(?P<DEALTIN>(true|false))" />', re.MULTILINE)
359 re_Board = re.compile(r'<cards type="COMMUNITY" cards="(?P<CARDS>[^"]+)"', re.MULTILINE)
360 re_Buyin = re.compile(r'\$(?P<BUYIN>[.,0-9]+)\s(?P<TYPE>Freeroll|Satellite|Guaranteed)?', re.MULTILINE)
362 # The following are also static regexes: there is no need to call
363 # compilePlayerRegexes (which does nothing), since players are identified
364 # not by name but by seat number
365 re_PostSB = re.compile(r'<event sequence="[0-9]+" type="(SMALL_BLIND|RETURN_BLIND)" (?P<TIMESTAMP>timestamp="[0-9]+" )?player="(?P<PSEAT>[0-9])" amount="(?P<SB>[.0-9]+)"/>', re.MULTILINE)
366 re_PostBB = re.compile(r'<event sequence="[0-9]+" type="(BIG_BLIND|INITIAL_BLIND)" (?P<TIMESTAMP>timestamp="[0-9]+" )?player="(?P<PSEAT>[0-9])" amount="(?P<BB>[.0-9]+)"/>', re.MULTILINE)
367 re_PostBoth = re.compile(r'<event sequence="[0-9]+" type="(RETURN_BLIND)" player="(?P<PSEAT>[0-9])" amount="(?P<SBBB>[.0-9]+)"/>', re.MULTILINE)
368 re_Antes = re.compile(r'<event sequence="[0-9]+" type="ANTE" (?P<TIMESTAMP>timestamp="\d+" )?player="(?P<PSEAT>[0-9])" amount="(?P<ANTE>[.0-9]+)"/>', re.MULTILINE)
369 re_BringIn = re.compile(r'<event sequence="[0-9]+" type="BRING_IN" (?P<TIMESTAMP>timestamp="\d+" )?player="(?P<PSEAT>[0-9])" amount="(?P<BRINGIN>[.0-9]+)"/>', re.MULTILINE)
370 re_HeroCards = re.compile(r'<cards type="(HOLE|DRAW_DRAWN_CARDS)" cards="(?P<CARDS>.+)" player="(?P<PSEAT>[0-9])"', re.MULTILINE)
371 re_Action = re.compile(r'<event sequence="[0-9]+" type="(?P<ATYPE>FOLD|CHECK|CALL|BET|RAISE|ALL_IN|SIT_OUT|DRAW|COMPLETE)"( timestamp="(?P<TIMESTAMP>[0-9]+)")? player="(?P<PSEAT>[0-9])"( amount="(?P<BET>[.0-9]+)")?( text="(?P<TXT>.+)")?/>', re.MULTILINE)
372 re_AllActions = re.compile(r'<event sequence="[0-9]+" type="(?P<ATYPE>FOLD|CHECK|CALL|BET|RAISE|ALL_IN|SIT_OUT|DRAW|COMPLETE|BIG_BLIND|INITIAL_BLIND|SMALL_BLIND|RETURN_BLIND|BRING_IN|ANTE)"( timestamp="(?P<TIMESTAMP>[0-9]+)")? player="(?P<PSEAT>[0-9])"( amount="(?P<BET>[.0-9]+)")?( text="(?P<TXT>.+)")?/>', re.MULTILINE)
373 re_CollectPot = re.compile(r'<winner amount="(?P<POT>[.0-9]+)" uncalled="(?P<UNCALLED>false|true)" potnumber="[0-9]+" player="(?P<PSEAT>[0-9])"', re.MULTILINE)
374 re_SitsOut = re.compile(r'<event sequence="[0-9]+" type="SIT_OUT" player="(?P<PSEAT>[0-9])"/>', re.MULTILINE)
375 re_ShownCards = re.compile(r'<cards type="(?P<SHOWED>SHOWN|MUCKED)" cards="(?P<CARDS>.+)" player="(?P<PSEAT>[0-9])"/>', re.MULTILINE)
376 re_Connection = re.compile(r'<event sequence="[0-9]+" type="(?P<TYPE>RECONNECTED|DISCONNECTED)" timestamp="[0-9]+" player="[0-9]"/>', re.MULTILINE)
377 re_Cancelled = re.compile(r'<event sequence="\d+" type="GAME_CANCELLED" timestamp="\d+"/>', re.MULTILINE)
378 re_LeaveTable = re.compile(r'<event sequence="\d+" type="LEAVE" timestamp="\d+" player="\d"/>', re.MULTILINE)
379 re_PlayerOut = re.compile(r'<event sequence="\d+" type="PLAYER_OUT" timestamp="\d+" player="(?P<PSEAT>[0-9])"/>', re.MULTILINE)
380 re_EndOfHand = re.compile(r'<round id="END_OF_GAME"', re.MULTILINE)
382 def compilePlayerRegexs(self, hand):
383 pass
385 def playerNameFromSeatNo(self, seatNo, hand):
386 # This special function is required because Merge Poker records
387 # actions by seat number (0 based), not by the player's name
388 for p in hand.players:
389 if p[0] == int(seatNo)+1:
390 return p[1]
392 def readSupportedGames(self):
393 return [["ring", "hold", "nl"],
394 ["ring", "hold", "pl"],
395 ["ring", "hold", "fl"],
396 ["ring", "hold", "hp"],
398 ["ring", "stud", "fl"],
399 ["ring", "stud", "pl"],
401 ["ring", "draw", "fl"],
402 ["ring", "draw", "pl"],
403 ["ring", "draw", "nl"],
404 ["ring", "draw", "hp"],
406 ["tour", "hold", "nl"],
407 ["tour", "hold", "pl"],
408 ["tour", "hold", "fl"],
410 ["tour", "stud", "fl"],
411 ["tour", "stud", "pl"],
413 ["tour", "draw", "fl"],
414 ["tour", "draw", "pl"],
415 ["tour", "draw", "nl"],
418 def determineGameType(self, handText):
419 """return dict with keys/values:
420 'type' in ('ring', 'tour')
421 'limitType' in ('nl', 'cn', 'pl', 'cp', 'fl', 'hp')
422 'base' in ('hold', 'stud', 'draw')
423 'category' in ('holdem', 'omahahi', omahahilo', 'razz', 'studhi', 'studhilo', 'fivedraw', '27_1draw', '27_3draw', 'badugi')
424 'hilo' in ('h','l','s')
425 'smallBlind' int?
426 'bigBlind' int?
427 'smallBet'
428 'bigBet'
429 'currency' in ('USD', 'EUR', 'T$', <countrycode>)
430 or None if we fail to get the info """
432 m = self.re_GameInfo.search(handText)
433 if not m:
434 # Information about the game type appears only at the beginning of
435 # a hand history file; hence it is not supplied with the second
436 # and subsequent hands. In these cases we use the value previously
437 # stored.
438 try:
439 return self.info
440 except AttributeError:
441 tmp = handText[0:200]
442 log.error(_("MergeToFpdb.determineGameType: '%s'") % tmp)
443 raise FpdbParseError
445 self.info = {}
446 mg = m.groupdict()
447 #print "DEBUG: mg: %s" % mg
449 if 'LIMIT' in mg:
450 self.info['limitType'] = self.limits[mg['LIMIT']]
451 if 'GAME' in mg:
452 if mg['GAME'] == "HORSE":
453 log.error(_("MergeToFpdb.determineGameType: HORSE found, unsupported"))
454 raise FpdbParseError
455 #(self.info['base'], self.info['category']) = self.Multigametypes[m2.group('MULTIGAMETYPE')]
456 else:
457 (self.info['base'], self.info['category']) = self.games[mg['GAME']]
458 if 'SB' in mg:
459 self.info['sb'] = mg['SB']
460 if 'BB' in mg:
461 self.info['bb'] = mg['BB']
462 if ' Tournament' == mg['TYPE']:
463 self.info['type'] = 'tour'
464 self.info['currency'] = 'T$'
465 else:
466 self.info['type'] = 'ring'
467 self.info['currency'] = 'USD'
469 if self.info['limitType'] == 'fl' and self.info['bb'] is not None and self.info['type'] == 'ring':
470 try:
471 self.info['sb'] = self.Lim_Blinds[mg['BB']][0]
472 self.info['bb'] = self.Lim_Blinds[mg['BB']][1]
473 except KeyError:
474 tmp = handText[0:200]
475 log.error(_("MergeToFpdb.determineGameType: Lim_Blinds has no lookup for '%s' - '%s'") % (mg['BB'], tmp))
476 raise FpdbParseError
478 return self.info
480 def readHandInfo(self, hand):
481 m = self.re_HandInfo.search(hand.handText)
482 if m is None:
483 tmp = hand.handText[0:200]
484 log.error(_("MergeToFpdb.readHandInfo: '%s'") % tmp)
485 raise FpdbParseError
487 #mg = m.groupdict()
488 #print "DEBUG: mg: %s" % mg
490 hand.handid = m.group('HID1') + m.group('HID2')
492 if hand.gametype['type'] == 'tour':
493 tid, table = re.split('-', m.group('TDATA'))
494 self.info['tablename'] = m.group('TABLENAME').strip()
495 self.info['tourNo'] = tid
496 hand.tourNo = tid
497 hand.tablename = table
498 if self.info['tablename'] in self.SnG_Structures:
499 hand.buyin = int(100*self.SnG_Structures[self.info['tablename']]['buyIn'])
500 hand.fee = int(100*self.SnG_Structures[self.info['tablename']]['fee'])
501 hand.buyinCurrency=self.SnG_Structures[self.info['tablename']]['currency']
502 hand.maxseats = self.SnG_Structures[self.info['tablename']]['seats']
503 hand.isSng = True
504 self.summaryInFile = True
505 #elif self.info['tablename'] in self.MTT_Structures:
506 # hand.buyin = int(100*self.MTT_Structures[self.info['tablename']]['buyIn'])
507 # hand.fee = int(100*self.MTT_Structures[self.info['tablename']]['fee'])
508 # hand.buyinCurrency=self.MTT_Structures[self.info['tablename']]['currency']
509 else:
510 #print 'DEBUG', 'no match for tourney %s tourNo %s' % (self.info['tablename'], tid)
511 hand.buyin = 0
512 hand.fee = 0
513 hand.buyinCurrency="NA"
514 hand.maxseats = None
515 else:
516 #log.debug("HID %s-%s, Table %s" % (m.group('HID1'), m.group('HID2'), m.group('TABLENAME')))
517 hand.tablename = m.group('TABLENAME')
518 hand.maxseats = None
520 hand.startTime = datetime.datetime.strptime(m.group('DATETIME')[:12],'%Y%m%d%H%M')
521 hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, "ET", "UTC")
522 # Check that the hand is complete up to the awarding of the pot; if
523 # not, the hand is unparseable
524 if self.re_EndOfHand.search(hand.handText) is None:
525 self.determineErrorType(hand, "readHandInfo")
527 def readPlayerStacks(self, hand):
528 acted = {}
529 seated = {}
530 m = self.re_PlayerInfo.finditer(hand.handText)
531 for a in m:
532 seatno = a.group('SEAT')
533 seated[seatno] = [a.group('PNAME'), a.group('CASH')]
535 if hand.gametype['type'] == "ring" :
536 # We can't 100% trust the 'dealtin' field. So read the actions and see if the players acted
537 m2 = self.re_AllActions.finditer(hand.handText)
538 fulltable = False
539 for action in m2:
540 acted[action.group('PSEAT')] = True
541 if len(seated) == len(acted): # We've faound all players
542 fulltable = True
543 break
544 if fulltable != True:
545 for seatno in seated.keys():
546 if seatno not in acted:
547 del seated[seatno]
549 for seatno in acted.keys():
550 if seatno not in seated:
551 log.error(_("MergeToFpdb.readPlayerStacks: '%s' Seat:%s acts but not listed") % (hand.handid, seatno))
552 raise FpdbParseError
554 for seat in seated:
555 name, stack = seated[seat]
556 # Merge indexes seats from 0. Add 1 so we don't have to add corner cases everywhere else.
557 hand.addPlayer(int(seat) + 1, name, stack)
559 # No players found at all.
560 if not hand.players:
561 self.determineErrorType(hand, "readPlayerStacks")
563 def markStreets(self, hand):
564 if hand.gametype['base'] == 'hold':
565 m = re.search(r'<round id="PREFLOP" sequence="[0-9]+">(?P<PREFLOP>.+(?=<round id="POSTFLOP")|.+)'
566 r'(<round id="POSTFLOP" sequence="[0-9]+">(?P<FLOP>.+(?=<round id="POSTTURN")|.+))?'
567 r'(<round id="POSTTURN" sequence="[0-9]+">(?P<TURN>.+(?=<round id="POSTRIVER")|.+))?'
568 r'(<round id="POSTRIVER" sequence="[0-9]+">(?P<RIVER>.+))?', hand.handText, re.DOTALL)
569 elif hand.gametype['base'] == 'draw':
570 if hand.gametype['category'] in ('27_3draw','badugi','a5_3draw'):
571 m = re.search(r'(?P<PREDEAL>.+(?=<round id="PRE_FIRST_DRAW" sequence="[0-9]+">)|.+)'
572 r'(<round id="PRE_FIRST_DRAW" sequence="[0-9]+">(?P<DEAL>.+(?=<round id="FIRST_DRAW" sequence="[0-9]+">)|.+))?'
573 r'(<round id="FIRST_DRAW" sequence="[0-9]+">(?P<DRAWONE>.+(?=<round id="SECOND_DRAW" sequence="[0-9]+">)|.+))?'
574 r'(<round id="SECOND_DRAW" sequence="[0-9]+">(?P<DRAWTWO>.+(?=<round id="THIRD_DRAW" sequence="[0-9]+">)|.+))?'
575 r'(<round id="THIRD_DRAW" sequence="[0-9]+">(?P<DRAWTHREE>.+))?', hand.handText,re.DOTALL)
576 else:
577 m = re.search(r'(?P<PREDEAL>.+(?=<round id="PRE_FIRST_DRAW" sequence="[0-9]+">)|.+)'
578 r'(<round id="PRE_FIRST_DRAW" sequence="[0-9]+">(?P<DEAL>.+(?=<round id="FIRST_DRAW" sequence="[0-9]+">)|.+))?'
579 r'(<round id="FIRST_DRAW" sequence="[0-9]+">(?P<DRAWONE>.+(?=<round id="SECOND_DRAW" sequence="[0-9]+">)|.+))?', hand.handText,re.DOTALL)
580 elif hand.gametype['base'] == 'stud':
581 m = re.search(r'(?P<ANTES>.+(?=<round id="BRING_IN" sequence="[0-9]+">)|.+)'
582 r'(<round id="BRING_IN" sequence="[0-9]+">(?P<THIRD>.+(?=<round id="FOURTH_STREET" sequence="[0-9]+">)|.+))?'
583 r'(<round id="FOURTH_STREET" sequence="[0-9]+">(?P<FOURTH>.+(?=<round id="FIFTH_STREET" sequence="[0-9]+">)|.+))?'
584 r'(<round id="FIFTH_STREET" sequence="[0-9]+">(?P<FIFTH>.+(?=<round id="SIXTH_STREET" sequence="[0-9]+">)|.+))?'
585 r'(<round id="SIXTH_STREET" sequence="[0-9]+">(?P<SIXTH>.+(?=<round id="SEVENTH_STREET" sequence="[0-9]+">)|.+))?'
586 r'(<round id="SEVENTH_STREET" sequence="[0-9]+">(?P<SEVENTH>.+))?', hand.handText,re.DOTALL)
587 if m == None:
588 self.determineErrorType(hand, "markStreets")
589 hand.addStreets(m)
591 def readCommunityCards(self, hand, street):
592 m = self.re_Board.search(hand.streets[street])
593 if m and street in ('FLOP','TURN','RIVER'):
594 if street == 'FLOP':
595 hand.setCommunityCards(street, m.group('CARDS').split(','))
596 elif street in ('TURN','RIVER'):
597 hand.setCommunityCards(street, [m.group('CARDS').split(',')[-1]])
598 else:
599 self.determineErrorType(hand, "readCommunityCards")
601 def readAntes(self, hand):
602 for player in self.re_Antes.finditer(hand.handText):
603 pname = self.playerNameFromSeatNo(player.group('PSEAT'), hand)
604 #print "DEBUG: hand.addAnte(%s,%s)" %(pname, player.group('ANTE'))
605 self.adjustMergeTourneyStack(hand, pname, player.group('ANTE'))
606 hand.addAnte(pname, player.group('ANTE'))
608 def readBringIn(self, hand):
609 m = self.re_BringIn.search(hand.handText)
610 if m:
611 pname = self.playerNameFromSeatNo(m.group('PSEAT'), hand)
612 #print "DEBUG: hand.addBringIn(%s,%s)" %(pname, m.group('BRINGIN'))
613 self.adjustMergeTourneyStack(hand, pname, m.group('BRINGIN'))
614 hand.addBringIn(pname, m.group('BRINGIN'))
616 def readBlinds(self, hand):
617 for a in self.re_PostSB.finditer(hand.handText):
618 #print "DEBUG: found sb: '%s' '%s'" %(self.playerNameFromSeatNo(a.group('PSEAT'), hand), a.group('SB'))
619 player = self.playerNameFromSeatNo(a.group('PSEAT'), hand)
620 self.adjustMergeTourneyStack(hand, player, a.group('SB'))
621 hand.addBlind(player,'small blind', a.group('SB'))
622 if not hand.gametype['sb']:
623 hand.gametype['sb'] = a.group('SB')
624 for a in self.re_PostBB.finditer(hand.handText):
625 #print "DEBUG: found bb: '%s' '%s'" %(self.playerNameFromSeatNo(a.group('PSEAT'), hand), a.group('BB'))
626 player = self.playerNameFromSeatNo(a.group('PSEAT'), hand)
627 self.adjustMergeTourneyStack(hand, player, a.group('BB'))
628 hand.addBlind(player, 'big blind', a.group('BB'))
629 if not hand.gametype['bb']:
630 hand.gametype['bb'] = a.group('BB')
631 for a in self.re_PostBoth.finditer(hand.handText):
632 bb = Decimal(self.info['bb'])
633 amount = Decimal(a.group('SBBB'))
634 player = self.playerNameFromSeatNo(a.group('PSEAT'), hand)
635 self.adjustMergeTourneyStack(hand, player, a.group('SBBB'))
636 if amount < bb:
637 hand.addBlind(player, 'small blind', a.group('SBBB'))
638 elif amount == bb:
639 hand.addBlind(player, 'big blind', a.group('SBBB'))
640 else:
641 hand.addBlind(player, 'both', a.group('SBBB'))
643 # FIXME
644 # The following should only trigger when a small blind is missing in a tournament, or the sb/bb is ALL_IN
645 # see http://sourceforge.net/apps/mantisbt/fpdb/view.php?id=115
646 if hand.gametype['type'] == 'tour':
647 if hand.gametype['sb'] == None and hand.gametype['bb'] == None:
648 hand.gametype['sb'] = "1"
649 hand.gametype['bb'] = "2"
650 elif hand.gametype['sb'] == None:
651 hand.gametype['sb'] = str(int(Decimal(hand.gametype['bb']))/2)
652 elif hand.gametype['bb'] == None:
653 hand.gametype['bb'] = str(int(Decimal(hand.gametype['sb']))*2)
654 if int(Decimal(hand.gametype['bb']))/2 != int(Decimal(hand.gametype['sb'])):
655 if int(Decimal(hand.gametype['bb']))/2 < int(Decimal(hand.gametype['sb'])):
656 hand.gametype['bb'] = str(int(Decimal(hand.gametype['sb']))*2)
657 else:
658 hand.gametype['sb'] = str(int(Decimal(hand.gametype['bb']))/2)
660 def adjustMergeTourneyStack(self, hand, player, amount):
661 amount = Decimal(amount)
662 if hand.gametype['type'] == 'tour':
663 for p in hand.players:
664 if p[1]==player:
665 stack = Decimal(p[2])
666 stack += amount
667 p[2] = str(stack)
668 hand.stacks[player] += amount
670 def readButton(self, hand):
671 hand.buttonpos = int(self.re_Button.search(hand.handText).group('BUTTON'))
673 def readHeroCards(self, hand):
674 # streets PREFLOP, PREDRAW, and THIRD are special cases beacause
675 # we need to grab hero's cards
676 herocards = []
677 for street in ('PREFLOP', 'DEAL'):
678 if street in hand.streets.keys():
679 m = self.re_HeroCards.finditer(hand.streets[street])
680 for found in m:
681 # if m == None:
682 # hand.involved = False
683 # else:
684 hand.hero = self.playerNameFromSeatNo(found.group('PSEAT'), hand)
685 cards = found.group('CARDS').split(',')
686 hand.addHoleCards(street, hand.hero, closed=cards, shown=False, mucked=False, dealt=True)
688 for street in hand.holeStreets:
689 if hand.streets.has_key(street):
690 if not hand.streets[street] or street in ('PREFLOP', 'DEAL') or hand.gametype['base'] == 'hold': continue # already done these
691 m = self.re_HeroCards.finditer(hand.streets[street])
692 for found in m:
693 player = self.playerNameFromSeatNo(found.group('PSEAT'), hand)
694 if player in hand.stacks:
695 if found.group('CARDS') is None:
696 cards = []
697 newcards = []
698 oldcards = []
699 else:
700 if hand.gametype['base'] == 'stud':
701 cards = found.group('CARDS').replace('null,', '').replace(',null','').split(',')
702 oldcards = cards[:-1]
703 newcards = [cards[-1]]
704 else:
705 cards = found.group('CARDS').split(',')
706 oldcards = cards
707 newcards = []
708 if street == 'THIRD' and len(cards) == 3: # hero in stud game
709 hand.hero = player
710 herocards = cards
711 hand.dealt.add(hand.hero) # need this for stud??
712 hand.addHoleCards(street, player, closed=oldcards, open=newcards, shown=False, mucked=False, dealt=False)
713 elif (cards != herocards and hand.gametype['base'] == 'stud'):
714 if hand.hero == player:
715 herocards = cards
716 hand.addHoleCards(street, player, closed=oldcards, open=newcards, shown=False, mucked=False, dealt=False)
717 elif (len(cards)<5):
718 if street == 'SEVENTH':
719 oldcards = []
720 newcards = []
721 hand.addHoleCards(street, player, closed=oldcards, open=newcards, shown=False, mucked=False, dealt=False)
722 elif (len(cards)==7):
723 for street in hand.holeStreets:
724 hand.holecards[street][player] = [[], []]
725 hand.addHoleCards(street, player, closed=cards, open=[], shown=False, mucked=False, dealt=False)
726 elif (hand.gametype['base'] == 'draw'):
727 hand.addHoleCards(street, player, closed=oldcards, open=newcards, shown=False, mucked=False, dealt=False)
729 def readAction(self, hand, street):
730 #log.debug("readAction (%s)" % street)
731 m = self.re_Action.finditer(hand.streets[street])
732 for action in m:
733 player = self.playerNameFromSeatNo(action.group('PSEAT'), hand)
734 if player in hand.stacks:
735 if action.group('ATYPE') in ('FOLD', 'SIT_OUT'):
736 hand.addFold(street, player)
737 elif action.group('ATYPE') == 'CHECK':
738 hand.addCheck(street, player)
739 elif action.group('ATYPE') == 'CALL':
740 hand.addCall(street, player, action.group('BET'))
741 elif action.group('ATYPE') == 'RAISE':
742 hand.addRaiseTo(street, player, action.group('BET'))
743 elif action.group('ATYPE') == 'BET':
744 hand.addBet(street, player, action.group('BET'))
745 elif action.group('ATYPE') == 'ALL_IN':
746 hand.addAllIn(street, player, action.group('BET'))
747 elif action.group('ATYPE') == 'DRAW':
748 hand.addDiscard(street, player, action.group('TXT'))
749 elif action.group('ATYPE') == 'COMPLETE':
750 if hand.gametype['base'] != 'stud':
751 hand.addRaiseTo(street, player, action.group('BET'))
752 else:
753 hand.addComplete( street, player, action.group('BET') )
754 else:
755 log.debug(_("Unimplemented %s: '%s' '%s'") % ("readAction", action.group('PSEAT'), action.group('ATYPE')))
757 def readShowdownActions(self, hand):
758 pass
760 def readCollectPot(self, hand):
761 hand.setUncalledBets(True)
762 for m in self.re_CollectPot.finditer(hand.handText):
763 pname = self.playerNameFromSeatNo(m.group('PSEAT'), hand)
764 pot = m.group('POT')
765 hand.addCollectPot(player=pname, pot=pot)
767 def readShownCards(self, hand):
768 for m in self.re_ShownCards.finditer(hand.handText):
769 if m.group('CARDS') is not None:
770 cards = m.group('CARDS')
771 cards = m.group('CARDS').split(',')
773 (shown, mucked) = (False, False)
774 if m.group('SHOWED') == "SHOWN": shown = True
775 elif m.group('SHOWED') == "MUCKED": mucked = True
777 #print "DEBUG: hand.addShownCards(%s, %s, %s, %s)" %(cards, m.group('PNAME'), shown, mucked)
778 hand.addShownCards(cards=cards, player=self.playerNameFromSeatNo(m.group('PSEAT'),hand), shown=shown, mucked=mucked)
780 def determineErrorType(self, hand, function):
781 message = False
782 m = self.re_Connection.search(hand.handText)
783 if m:
784 message = _("Found %s. Hand missing information." % m.group('TYPE'))
785 m = self.re_LeaveTable.search(hand.handText)
786 if m:
787 message = _("Found LEAVE. Player left table before hand completed")
788 m = self.re_Cancelled.search(hand.handText)
789 if m:
790 message = _("Found CANCELLED")
791 if message == False and function == "markStreets":
792 message = _("Failed to identify all streets")
793 if message == False and function == "readHandInfo":
794 message = _("END_OF_HAND not found. No obvious reason")
796 raise FpdbHandPartial("Partial hand history: %s '%s' %s" % (function, hand.handid, message))
798 @staticmethod
799 def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
800 "Returns string to search in windows titles"
801 if type=="tour":
802 # Ignoring table number as it doesn't appear to be in the window title
803 # "$200 Freeroll - NL Holdem - 20:00 (46302299) - Table 1" -- the table number doesn't matter, it seems to always be 1 in the HH.
804 # "Fun Step 1 (4358174) - Table 1"
805 return ( "\(" + re.escape(str(tournament)) + "\)")
806 else:
807 # "Play Money (4631994)"
808 return re.escape(table_name)