pokerstats 2.0.13 → 2.0.14
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/pokerstats/hand_classification.rb +23 -5
- data/lib/pokerstats/hand_constants.rb +8 -2
- data/lib/pokerstats/hand_statistics.rb +25 -4
- data/lib/pokerstats/hand_statistics_api.rb +1 -1
- data/lib/pokerstats/plugins/aggression_statistics.rb +1 -1
- data/lib/pokerstats/plugins/cash_statistics.rb +74 -16
- data/lib/pokerstats/plugins/street_bet_statistics.rb +219 -0
- data/lib/pokerstats/plugins/street_statistics.rb +94 -0
- data/lib/pokerstats/pokerstars_hand_history_parser.rb +76 -13
- data/pokerstats.gemspec +4 -2
- data/spec/hand_statistics_spec.rb +1770 -774
- data/spec/hand_statistics_spec_helper.rb +14 -3
- data/spec/pokerstars_hand_history_parser_spec.rb +77 -10
- data/spec/zpokerstars_hand_history_parser_integration.rb.txt +28 -28
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.
|
1
|
+
2.0.14
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/hand_constants")
|
2
|
-
module Pokerstats
|
3
|
-
|
2
|
+
module Pokerstats
|
4
3
|
def class_index_from_hand_string(hand_string)
|
5
4
|
return class_index_from_hand_string!(hand_string)
|
6
5
|
rescue ArgumentError
|
@@ -8,10 +7,16 @@ module Pokerstats
|
|
8
7
|
end
|
9
8
|
|
10
9
|
def class_index_from_hand_string!(hand_string)
|
11
|
-
class_index_from_class_string(class_string_from_hand_string(hand_string))
|
10
|
+
class_index_from_class_string!(class_string_from_hand_string!(hand_string))
|
12
11
|
end
|
13
12
|
|
14
13
|
def class_string_from_hand_string(hand_string)
|
14
|
+
class_string_from_hand_string!(hand_string)
|
15
|
+
rescue
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def class_string_from_hand_string!(hand_string)
|
15
20
|
raise ArgumentError, "hand_string '#{hand_string}' must be a String" unless hand_string.kind_of?(String)
|
16
21
|
hand_string = hand_string.gsub(/ /,'')
|
17
22
|
hand_string = hand_string.upcase
|
@@ -37,6 +42,12 @@ module Pokerstats
|
|
37
42
|
end
|
38
43
|
|
39
44
|
def class_index_from_class_string(class_string)
|
45
|
+
class_index_from_class_string!(class_string)
|
46
|
+
rescue
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def class_index_from_class_string!(class_string)
|
40
51
|
raise ArgumentError, "class_string #{class_string.inspect} must be a String" unless class_string.kind_of?(String)
|
41
52
|
class_string.upcase!
|
42
53
|
first = Pokerstats::HandConstants::CARDS.index(class_string[0..0])
|
@@ -52,8 +63,15 @@ module Pokerstats
|
|
52
63
|
end
|
53
64
|
end
|
54
65
|
|
55
|
-
def class_string_from_class_index(
|
56
|
-
|
66
|
+
def class_string_from_class_index(class_index)
|
67
|
+
class_string_from_class_index!(class_index)
|
68
|
+
rescue ArgumentError
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
def class_string_from_class_index!(class_index)
|
73
|
+
raise ArgumentError, "class_index must be an integer" unless class_index.kind_of? Integer
|
74
|
+
row, col = row_from_class_index(class_index), col_from_class_index(class_index)
|
57
75
|
case row <=> col
|
58
76
|
when 1
|
59
77
|
Pokerstats::HandConstants::CARDS[col..col] + Pokerstats::HandConstants::CARDS[row..row] + "o"
|
@@ -1,18 +1,24 @@
|
|
1
1
|
module Pokerstats
|
2
2
|
module HandConstants
|
3
3
|
HAND_REPORT_SPECIFICATION = [
|
4
|
-
# [key, sql_type, function]
|
5
4
|
[:session_filename, 'string'],
|
6
5
|
[:starting_at, 'datetime'],
|
7
6
|
[:name, 'string'],
|
7
|
+
[:table_name, 'string'],
|
8
8
|
[:description, 'string'],
|
9
|
+
[:ante, 'decimal'],
|
9
10
|
[:sb, 'decimal'],
|
10
11
|
[:bb, 'decimal'],
|
11
12
|
[:board, 'string'],
|
12
13
|
[:total_pot, 'decimal'],
|
13
14
|
[:rake, 'decimal'],
|
14
15
|
[:played_at, 'datetime'],
|
15
|
-
[:tournament, 'string']
|
16
|
+
[:tournament, 'string'],
|
17
|
+
[:max_players, 'integer'],
|
18
|
+
[:number_players, 'integer'],
|
19
|
+
[:game_type, 'string'],
|
20
|
+
[:limit_type, 'string'],
|
21
|
+
[:stakes_type, 'decimal']
|
16
22
|
]
|
17
23
|
HAND_INFORMATION_KEYS = HAND_REPORT_SPECIFICATION.map{|each| each.first}
|
18
24
|
HAND_RECORD_INCOMPLETE_MESSAGE = "hand record is incomplete"
|
@@ -12,11 +12,12 @@ module Pokerstats
|
|
12
12
|
plugin_include_module HandStatisticsAPI
|
13
13
|
def initialize
|
14
14
|
install_plugins self
|
15
|
-
@hand_information = {}
|
15
|
+
@hand_information = {:number_players => 0, :ante => "0.0".to_d}
|
16
16
|
@player_hashes = []
|
17
17
|
@button_player_index = nil
|
18
18
|
@cached_player_position = nil
|
19
19
|
@street_state = nil
|
20
|
+
@last_street_state = nil
|
20
21
|
street_transition(:prelude)
|
21
22
|
end
|
22
23
|
|
@@ -30,6 +31,10 @@ module Pokerstats
|
|
30
31
|
hash.merge!(key => @hand_information[key])
|
31
32
|
end
|
32
33
|
end
|
34
|
+
|
35
|
+
def hand_information(field)
|
36
|
+
@hand_information[field]
|
37
|
+
end
|
33
38
|
|
34
39
|
def update_hand update
|
35
40
|
street_transition(update[:street]) unless update[:street] == @street_state
|
@@ -65,7 +70,8 @@ module Pokerstats
|
|
65
70
|
raise Pokerstats::HandHistoryParseError, "#{PLAYER_RECORDS_DUPLICATE_PLAYER_NAME}: #{screen_name.inspect}" if players.member?(screen_name)
|
66
71
|
@cached_player_position = nil
|
67
72
|
@player_hashes << player
|
68
|
-
|
73
|
+
@hand_information[:number_players]+=1
|
74
|
+
plugins.each{|each| each.register_player(screen_name, @street_state, player)} #why the second parameter?
|
69
75
|
street_transition_for_player(@street_state, screen_name)
|
70
76
|
end
|
71
77
|
|
@@ -76,8 +82,13 @@ module Pokerstats
|
|
76
82
|
def street
|
77
83
|
@street_state
|
78
84
|
end
|
85
|
+
|
86
|
+
def last_street
|
87
|
+
@last_street_state
|
88
|
+
end
|
79
89
|
|
80
90
|
def street_transition street
|
91
|
+
@last_street_state = @street_state
|
81
92
|
@street_state = street
|
82
93
|
plugins.each{|each| each.street_transition(street)}
|
83
94
|
players.each {|player| street_transition_for_player(street, player)}
|
@@ -116,6 +127,17 @@ module Pokerstats
|
|
116
127
|
def position screen_name
|
117
128
|
(@cached_player_position && @cached_player_position[screen_name]) || calculate_player_position(screen_name)
|
118
129
|
end
|
130
|
+
|
131
|
+
# player screen_name_first goes before player screen_name_second
|
132
|
+
def betting_order?(screen_name_first, screen_name_second)
|
133
|
+
if button?(screen_name_first)
|
134
|
+
false
|
135
|
+
elsif button?(screen_name_second)
|
136
|
+
true
|
137
|
+
else
|
138
|
+
position(screen_name_first) < position(screen_name_second)
|
139
|
+
end
|
140
|
+
end
|
119
141
|
|
120
142
|
def button?(screen_name)
|
121
143
|
position(screen_name) && position(screen_name).zero?
|
@@ -146,8 +168,7 @@ module Pokerstats
|
|
146
168
|
def attacker?(screen_name)
|
147
169
|
(number_players > 2) && (button?(screen_name) || cutoff?(screen_name))
|
148
170
|
end
|
149
|
-
|
150
|
-
|
171
|
+
|
151
172
|
##
|
152
173
|
# Action Information
|
153
174
|
##
|
@@ -35,7 +35,7 @@ module Pokerstats
|
|
35
35
|
@postflop_aggressive[screen_name]
|
36
36
|
end
|
37
37
|
|
38
|
-
def register_player screen_name, street
|
38
|
+
def register_player screen_name, street, player
|
39
39
|
@preflop_passive[screen_name] = 0
|
40
40
|
@preflop_aggressive[screen_name] = 0
|
41
41
|
@postflop_passive[screen_name] = 0
|
@@ -2,14 +2,25 @@ module Pokerstats
|
|
2
2
|
class CashStatistics < HandStatistics::Plugin
|
3
3
|
def initialize handstatistics
|
4
4
|
super handstatistics
|
5
|
+
@seat = {}
|
5
6
|
@posted = {}
|
6
7
|
@paid = {}
|
7
8
|
@paid_this_round = {}
|
8
9
|
@won = {}
|
9
10
|
@cards = {}
|
11
|
+
@starting_stack = {}
|
10
12
|
@stats = {:posted => @posted, :paid => @paid, :won => @won, :cards => @cards}
|
11
13
|
end
|
12
14
|
|
15
|
+
|
16
|
+
def position(player)
|
17
|
+
@hand_statistics.position player
|
18
|
+
end
|
19
|
+
|
20
|
+
def seat(player)
|
21
|
+
@seat[player]
|
22
|
+
end
|
23
|
+
|
13
24
|
def profit(player)
|
14
25
|
return nil unless won(player) && posted(player) && paid(player)
|
15
26
|
won(player) - posted(player) - paid(player)
|
@@ -34,7 +45,7 @@ module Pokerstats
|
|
34
45
|
def divided_by_bb(value)
|
35
46
|
bb = @hand_statistics.report_hand_information[:bb]
|
36
47
|
return nil if bb.nil? || bb.zero?
|
37
|
-
value / bb
|
48
|
+
value / (2 * bb)
|
38
49
|
end
|
39
50
|
|
40
51
|
def profit_in_bb(player)
|
@@ -54,7 +65,45 @@ module Pokerstats
|
|
54
65
|
end
|
55
66
|
|
56
67
|
def cards(player)
|
57
|
-
|
68
|
+
@cards[player]
|
69
|
+
end
|
70
|
+
|
71
|
+
def starting_stack(player)
|
72
|
+
@starting_stack[player]
|
73
|
+
end
|
74
|
+
|
75
|
+
def starting_stack_in_bb(player)
|
76
|
+
divided_by_bb(starting_stack(player))
|
77
|
+
end
|
78
|
+
|
79
|
+
def starting_pot
|
80
|
+
sb = @hand_statistics.report_hand_information[:sb]
|
81
|
+
bb = @hand_statistics.report_hand_information[:bb]
|
82
|
+
ante = @hand_statistics.report_hand_information[:ante]
|
83
|
+
number_players = @hand_statistics.report_hand_information[:number_players]
|
84
|
+
sb && bb && ante && number_players &&
|
85
|
+
(sb + bb + ante * number_players)
|
86
|
+
end
|
87
|
+
|
88
|
+
def starting_stack_as_M(player)
|
89
|
+
starting_stack(player) && starting_pot && (starting_pot > 0) &&
|
90
|
+
("1.0".to_d * starting_stack(player) / starting_pot)
|
91
|
+
end
|
92
|
+
|
93
|
+
def starting_stack_as_M_class(player)
|
94
|
+
starting_stack_as_M(player) &&
|
95
|
+
case starting_stack_as_M(player)
|
96
|
+
when 0 .. 2.99
|
97
|
+
"darkred"
|
98
|
+
when 2.99 .. 5.99
|
99
|
+
"red"
|
100
|
+
when 5.99 .. 9.99
|
101
|
+
"orange"
|
102
|
+
when 9.99 .. 19.99
|
103
|
+
"yellow"
|
104
|
+
else
|
105
|
+
"green"
|
106
|
+
end
|
58
107
|
end
|
59
108
|
|
60
109
|
def card_category_index(player)
|
@@ -62,29 +111,38 @@ module Pokerstats
|
|
62
111
|
end
|
63
112
|
|
64
113
|
def self.report_specification
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
114
|
+
[
|
115
|
+
# [key, sql_type, function]
|
116
|
+
[:seat, 'integer', :seat],
|
117
|
+
[:position, 'integer', :position],
|
118
|
+
[:posted, 'decimal', :posted],
|
119
|
+
[:paid, 'decimal', :paid],
|
120
|
+
[:won, 'decimal', :won],
|
121
|
+
[:profit, 'decimal', :profit],
|
122
|
+
[:posted_in_bb, 'decimal', :posted_in_bb],
|
123
|
+
[:paid_in_bb, 'decimal', :paid_in_bb],
|
124
|
+
[:won_in_bb, 'decimal', :won_in_bb],
|
125
|
+
[:profit_in_bb, 'decimal', :profit_in_bb],
|
126
|
+
[:cards, 'string', :cards],
|
127
|
+
[:card_category_index, 'integer', :card_category_index],
|
128
|
+
[:starting_stack, 'decimal', :starting_stack],
|
129
|
+
[:starting_stack_in_bb, 'decimal', :starting_stack_in_bb],
|
130
|
+
[:starting_stack_as_M, 'decimal', :starting_stack_as_M],
|
131
|
+
[:starting_stack_as_M_class, 'decimal', :starting_stack_as_M_class]
|
132
|
+
]
|
78
133
|
end
|
79
134
|
|
80
135
|
def stats(player=nil)
|
81
136
|
return @stats unless player
|
82
137
|
end
|
83
138
|
|
84
|
-
def register_player(screen_name, street)
|
139
|
+
def register_player(screen_name, street, player_hash)
|
140
|
+
# puts "register_player(#{screen_name.inspect}, #{street.inspect}, #{player_hash.inspect})"
|
85
141
|
@posted[screen_name] = 0
|
86
142
|
@paid[screen_name] = 0
|
87
143
|
@won[screen_name] = 0
|
144
|
+
@starting_stack[screen_name] = player_hash[:starting_stack]
|
145
|
+
@seat[screen_name] = player_hash[:seat]
|
88
146
|
end
|
89
147
|
|
90
148
|
def street_transition_for_player street, player
|
@@ -0,0 +1,219 @@
|
|
1
|
+
module Pokerstats
|
2
|
+
class StreetBetStatistics < HandStatistics::Plugin
|
3
|
+
def self.report_specification
|
4
|
+
[
|
5
|
+
[:preflop_2bet, "boolean", :preflop_2bet],
|
6
|
+
[:preflop_3bet, "boolean", :preflop_3bet],
|
7
|
+
[:preflop_4bet, "boolean", :preflop_4bet],
|
8
|
+
[:flop_1bet, "boolean", :flop_1bet],
|
9
|
+
[:flop_2bet, "boolean", :flop_2bet],
|
10
|
+
[:flop_3bet, "boolean", :flop_3bet],
|
11
|
+
[:flop_4bet, "boolean", :flop_4bet],
|
12
|
+
[:turn_1bet, "boolean", :turn_1bet],
|
13
|
+
[:turn_2bet, "boolean", :turn_2bet],
|
14
|
+
[:turn_3bet, "boolean", :turn_3bet],
|
15
|
+
[:turn_4bet, "boolean", :turn_4bet],
|
16
|
+
[:river_1bet, "boolean", :river_1bet],
|
17
|
+
[:river_2bet, "boolean", :river_2bet],
|
18
|
+
[:river_3bet, "boolean", :river_3bet],
|
19
|
+
[:river_4bet, "boolean", :river_4bet],
|
20
|
+
|
21
|
+
[:fold_to_preflop_1bet, "boolean", :fold_to_preflop_1bet],
|
22
|
+
[:fold_to_preflop_2bet, "boolean", :fold_to_preflop_2bet],
|
23
|
+
[:fold_to_preflop_3bet, "boolean", :fold_to_preflop_3bet],
|
24
|
+
[:fold_to_preflop_4bet, "boolean", :fold_to_preflop_4bet],
|
25
|
+
[:fold_to_flop_1bet, "boolean", :fold_to_flop_1bet],
|
26
|
+
[:fold_to_flop_2bet, "boolean", :fold_to_flop_2bet],
|
27
|
+
[:fold_to_flop_3bet, "boolean", :fold_to_flop_3bet],
|
28
|
+
[:fold_to_flop_4bet, "boolean", :fold_to_flop_4bet],
|
29
|
+
[:fold_to_turn_1bet, "boolean", :fold_to_turn_1bet],
|
30
|
+
[:fold_to_turn_2bet, "boolean", :fold_to_turn_2bet],
|
31
|
+
[:fold_to_turn_3bet, "boolean", :fold_to_turn_3bet],
|
32
|
+
[:fold_to_turn_4bet, "boolean", :fold_to_turn_4bet],
|
33
|
+
[:fold_to_river_1bet, "boolean", :fold_to_river_1bet],
|
34
|
+
[:fold_to_river_2bet, "boolean", :fold_to_river_2bet],
|
35
|
+
[:fold_to_river_3bet, "boolean", :fold_to_river_3bet],
|
36
|
+
[:fold_to_river_4bet, "boolean", :fold_to_river_4bet],
|
37
|
+
|
38
|
+
[:call_preflop_1bet, "boolean", :call_preflop_1bet],
|
39
|
+
[:call_preflop_2bet, "boolean", :call_preflop_2bet],
|
40
|
+
[:call_preflop_3bet, "boolean", :call_preflop_3bet],
|
41
|
+
[:call_preflop_4bet, "boolean", :call_preflop_4bet],
|
42
|
+
[:call_flop_1bet, "boolean", :call_flop_1bet],
|
43
|
+
[:call_flop_2bet, "boolean", :call_flop_2bet],
|
44
|
+
[:call_flop_3bet, "boolean", :call_flop_3bet],
|
45
|
+
[:call_flop_4bet, "boolean", :call_flop_4bet],
|
46
|
+
[:call_turn_1bet, "boolean", :call_turn_1bet],
|
47
|
+
[:call_turn_2bet, "boolean", :call_turn_2bet],
|
48
|
+
[:call_turn_3bet, "boolean", :call_turn_3bet],
|
49
|
+
[:call_turn_4bet, "boolean", :call_turn_4bet],
|
50
|
+
[:call_river_1bet, "boolean", :call_river_1bet],
|
51
|
+
[:call_river_2bet, "boolean", :call_river_2bet],
|
52
|
+
[:call_river_3bet, "boolean", :call_river_3bet],
|
53
|
+
[:call_river_4bet, "boolean", :call_river_4bet],
|
54
|
+
|
55
|
+
[:last_aggr_preflop, 'boolean', :last_aggr_preflop],
|
56
|
+
[:last_aggr_flop, 'boolean', :last_aggr_flop],
|
57
|
+
[:last_aggr_turn, 'boolean', :last_aggr_turn],
|
58
|
+
[:last_aggr_river, 'boolean', :last_aggr_river],
|
59
|
+
|
60
|
+
[:cbet_flop, 'boolean', :cbet_flop],
|
61
|
+
[:cbet_turn, 'boolean', :cbet_turn],
|
62
|
+
[:cbet_river, 'boolean', :cbet_river],
|
63
|
+
[:fold_to_cbet_flop, 'boolean', :fold_to_cbet_flop],
|
64
|
+
[:fold_to_cbet_turn, 'boolean', :fold_to_cbet_turn],
|
65
|
+
[:fold_to_cbet_river, 'boolean', :fold_to_cbet_river],
|
66
|
+
|
67
|
+
[:dbet_flop, 'boolean', :dbet_flop],
|
68
|
+
[:dbet_turn, 'boolean', :dbet_turn],
|
69
|
+
[:dbet_river, 'boolean', :dbet_river],
|
70
|
+
[:fold_to_dbet_flop, 'boolean', :fold_to_dbet_flop],
|
71
|
+
[:fold_to_dbet_turn, 'boolean', :fold_to_dbet_turn],
|
72
|
+
[:fold_to_dbet_river, 'boolean', :fold_to_dbet_river]
|
73
|
+
]
|
74
|
+
end
|
75
|
+
|
76
|
+
attr_accessor :street_bets, :fold_to_street_bets, :last_aggr_player
|
77
|
+
|
78
|
+
#
|
79
|
+
# These functions return one of three, not two values, and hence do not end with a "?".
|
80
|
+
# A nil value indicates that the player had no opportunity to make the described bet.
|
81
|
+
# For example:
|
82
|
+
# cbet_flop(player)
|
83
|
+
# nil -- player did not have an opportunity to make a cbet on the flop
|
84
|
+
# true -- player made a cbet on the flop
|
85
|
+
# false -- player had an opportunity to make a cbet on the flop, but did not
|
86
|
+
#
|
87
|
+
# fold_to_flop_2bet(player)
|
88
|
+
# nil -- player did not have an opportunity to fold to a 2bet on the flop
|
89
|
+
# true -- player folded to a 2bet on the flop
|
90
|
+
# false -- player had an opportunity to fold to a 2bet on the flop, but did not
|
91
|
+
#
|
92
|
+
# Some care must be taken in the code and testing to assure the consistency of the nil/false dichotomy
|
93
|
+
#
|
94
|
+
# They are defined dynamically due to their number and similarities
|
95
|
+
#
|
96
|
+
|
97
|
+
for street in [:preflop, :flop, :turn, :river]
|
98
|
+
|
99
|
+
#
|
100
|
+
# last agresssion functions
|
101
|
+
# true only if player made the last aggressive move on the street
|
102
|
+
# nil otherwise
|
103
|
+
# never false
|
104
|
+
#
|
105
|
+
class_eval <<-LAST_AGGR_FUNCTIONS
|
106
|
+
def last_aggr_#{street} player
|
107
|
+
@last_aggr_player[:#{street}] && (player==@last_aggr_player[:#{street}] ? true : nil)
|
108
|
+
end
|
109
|
+
LAST_AGGR_FUNCTIONS
|
110
|
+
|
111
|
+
#
|
112
|
+
# make_, call_, and fold_to_ functions, by bet and street street
|
113
|
+
#
|
114
|
+
for bet in 1..4
|
115
|
+
class_eval <<-STREET_AND_BET_FUNCTIONS
|
116
|
+
def #{street}_#{bet}bet(player)
|
117
|
+
@street_bets[#{street.inspect}] && @street_bets[#{street.inspect}][#{bet}][player]
|
118
|
+
end
|
119
|
+
def call_#{street}_#{bet}bet(player)
|
120
|
+
@call_street_bets[#{street.inspect}] && @call_street_bets[#{street.inspect}][#{bet}][player]
|
121
|
+
end
|
122
|
+
def fold_to_#{street}_#{bet}bet(player)
|
123
|
+
@fold_to_street_bets[#{street.inspect}] && @fold_to_street_bets[#{street.inspect}][#{bet}][player]
|
124
|
+
end
|
125
|
+
STREET_AND_BET_FUNCTIONS
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
for street in [:flop, :turn, :river]
|
130
|
+
last_street = case street
|
131
|
+
when :flop then :preflop
|
132
|
+
when :turn then :flop
|
133
|
+
when :river then :turn
|
134
|
+
end
|
135
|
+
|
136
|
+
#
|
137
|
+
# make, call_ and fold_to_ cbet and dbet functions, by street
|
138
|
+
#
|
139
|
+
# cbets (continuation bets) are first-in bets after making last agression on the previous street
|
140
|
+
#
|
141
|
+
# dbets (donk bets) are first-in bets, made after calling another player's aggression out of position on the previous street
|
142
|
+
#
|
143
|
+
|
144
|
+
class_eval <<-FTR_FUNCTIONS
|
145
|
+
def cbet_#{street}(player)
|
146
|
+
last_aggr_#{last_street}(player) && #{street}_1bet(player)
|
147
|
+
end
|
148
|
+
def fold_to_cbet_#{street}(player)
|
149
|
+
@first_aggr_player[:#{street}] && cbet_#{street}(@first_aggr_player[:#{street}]) && fold_to_#{street}_1bet(player)
|
150
|
+
# fold_to_#{street}_1bet(player) && @last_aggr_player[:#{last_street}] && cbet_#{street}(@last_aggr_player[:#{last_street}])
|
151
|
+
end
|
152
|
+
def call_cbet_#{street}(player)
|
153
|
+
@first_aggr_player[:#{street}] && cbet_#{street}(@first_aggr_player[:#{street}]) && call_#{street}_1bet(player)
|
154
|
+
end
|
155
|
+
def dbet_#{street}(player)
|
156
|
+
return nil unless @last_aggr_player[:#{last_street}] && @hand_statistics.betting_order?(player, @last_aggr_player[:#{last_street}])
|
157
|
+
#{street}_1bet(player)
|
158
|
+
end
|
159
|
+
def fold_to_dbet_#{street}(player)
|
160
|
+
return nil unless @first_aggr_player[:#{street}] && dbet_#{street}(@first_aggr_player[:#{street}])
|
161
|
+
fold_to_#{street}_1bet(player)
|
162
|
+
end
|
163
|
+
def call_dbet_#{street}(player)
|
164
|
+
return nil unless @first_aggr_player[:#{street}] && dbet_#{street}(@first_aggr_player[:#{street}])
|
165
|
+
call_#{street}_1bet(player)
|
166
|
+
end
|
167
|
+
FTR_FUNCTIONS
|
168
|
+
end
|
169
|
+
|
170
|
+
def initialize handstatistics
|
171
|
+
@street_bets = {}
|
172
|
+
@call_street_bets = {}
|
173
|
+
@fold_to_street_bets = {}
|
174
|
+
@first_aggr_player = {}
|
175
|
+
@last_aggr_player = {}
|
176
|
+
[:preflop, :flop, :turn, :river].each do|each|
|
177
|
+
@street_bets[each] = [{}, {}, {}, {}, {}]
|
178
|
+
@call_street_bets[each] = [{}, {}, {}, {}, {}]
|
179
|
+
@fold_to_street_bets[each] = [{}, {}, {}, {}, {}]
|
180
|
+
end
|
181
|
+
super handstatistics
|
182
|
+
end
|
183
|
+
|
184
|
+
def register_player screen_name, street, player
|
185
|
+
end
|
186
|
+
|
187
|
+
def street_transition street
|
188
|
+
case street
|
189
|
+
when :preflop
|
190
|
+
@last_bet = 1
|
191
|
+
when :flop, :turn, :river
|
192
|
+
@last_bet = 0
|
193
|
+
else
|
194
|
+
@last_bet = nil
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def street_transition_for_player street, player
|
199
|
+
end
|
200
|
+
|
201
|
+
def apply_action action, street
|
202
|
+
unless @last_bet.nil?
|
203
|
+
# puts "apply_action(#{action[:aggression]}, #{street}) with @last_bet == #{@last_bet}"
|
204
|
+
if @last_bet.between?(0,4)
|
205
|
+
@fold_to_street_bets[street][@last_bet][action[:screen_name]] = action[:description] == "folds"
|
206
|
+
@call_street_bets[street][@last_bet][action[:screen_name]] = action[:description] == "calls"
|
207
|
+
end
|
208
|
+
if @last_bet.between?(0,3)
|
209
|
+
@street_bets[street][@last_bet+1][action[:screen_name]] = action[:aggression] == :aggressive
|
210
|
+
end
|
211
|
+
if action[:aggression] == :aggressive
|
212
|
+
@last_bet+=1
|
213
|
+
@first_aggr_player[street] ||= action[:screen_name]
|
214
|
+
@last_aggr_player[street] = action[:screen_name]
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|