pokerstats 2.0.13 → 2.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|