Class: Pokerstats::HandStatistics

Inherits:
Object
  • Object
show all
Includes:
Pluggable, HandConstants
Defined in:
lib/pokerstats/hand_statistics.rb

Constant Summary

Constants included from HandConstants

Pokerstats::HandConstants::CARDS, Pokerstats::HandConstants::HAND_INFORMATION_KEYS, Pokerstats::HandConstants::HAND_RECORD_INCOMPLETE_MESSAGE, Pokerstats::HandConstants::HAND_REPORT_SPECIFICATION, Pokerstats::HandConstants::MAX_SEATS, Pokerstats::HandConstants::PLAYER_RECORDS_DUPLICATE_PLAYER_NAME, Pokerstats::HandConstants::PLAYER_RECORDS_NO_BUTTON_REGISTERED, Pokerstats::HandConstants::PLAYER_RECORDS_NO_PLAYER_REGISTERED, Pokerstats::HandConstants::PLAYER_RECORDS_OUT_OF_BALANCE, Pokerstats::HandConstants::PLAYER_RECORDS_UNREGISTERED_PLAYER

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeHandStatistics

Returns a new instance of HandStatistics.



13
14
15
16
17
18
19
20
21
22
# File 'lib/pokerstats/hand_statistics.rb', line 13

def initialize
  install_plugins self
  @hand_information = {:number_players => 0, :ante => "0.0".to_d}
  @player_hashes = []
  @button_player_index = nil
  @cached_player_position = nil
  @street_state = nil
  @last_street_state = nil
  street_transition(:prelude)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args) ⇒ Object (private)



237
238
239
# File 'lib/pokerstats/hand_statistics.rb', line 237

def method_missing symbol, *args
  plugins.send symbol, *args
end

Class Method Details

.hand_statistics_migration_dataObject



221
222
223
224
225
# File 'lib/pokerstats/hand_statistics.rb', line 221

def self.hand_statistics_migration_data
  HAND_REPORT_SPECIFICATION.inject("") do |string, each|
    string + "t.#{each[1]}\t#{each[0].inspect}\n"
  end
end

.player_statistics_migration_dataObject



227
228
229
230
231
232
233
234
235
# File 'lib/pokerstats/hand_statistics.rb', line 227

def self.player_statistics_migration_data
  plugin_factory.inject("") do |str, each_plugin|
    tstr = "# from #{each_plugin.inspect}\n"
    each_plugin.report_specification.each do |each_datum|
      tstr += "t.#{each_datum[1]}\t#{each_datum[0].inspect}\n"
    end
    str = str + tstr
  end
end

Instance Method Details

#aggression(description) ⇒ Object

Action Information



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/pokerstats/hand_statistics.rb', line 175

def aggression(description)
  case description
  when /call/
    :passive
  when /raise/
    :aggressive
  when /bet/
    :aggressive
  when /fold/
    :fold
  when /check/
    :check
  else
    :neutral
  end
end

#attacker?(screen_name) ⇒ Boolean

Returns:

  • (Boolean)


168
169
170
# File 'lib/pokerstats/hand_statistics.rb', line 168

def attacker?(screen_name)
  (number_players > 2) && (button?(screen_name) || cutoff?(screen_name))
end

#bbpos?(screen_name) ⇒ Boolean

Returns:

  • (Boolean)


164
165
166
# File 'lib/pokerstats/hand_statistics.rb', line 164

def bbpos?(screen_name)
  (number_players > 2) && position(screen_name) == 2
end

#betting_order?(screen_name_first, screen_name_second) ⇒ Boolean

player screen_name_first goes before player screen_name_second

Returns:

  • (Boolean)


132
133
134
135
136
137
138
139
140
# File 'lib/pokerstats/hand_statistics.rb', line 132

def betting_order?(screen_name_first, screen_name_second)
    if button?(screen_name_first)
        false
    elsif button?(screen_name_second)
        true
    else
        position(screen_name_first) < position(screen_name_second)
    end
end

#blind?(screen_name) ⇒ Boolean

Returns:

  • (Boolean)


156
157
158
# File 'lib/pokerstats/hand_statistics.rb', line 156

def blind?(screen_name)
  (sbpos?(screen_name) || bbpos?(screen_name)) and !posted(screen_name).zero?
end

#buttonObject



110
111
112
# File 'lib/pokerstats/hand_statistics.rb', line 110

def button
  @button_player_index
end

#button?(screen_name) ⇒ Boolean

Returns:

  • (Boolean)


142
143
144
# File 'lib/pokerstats/hand_statistics.rb', line 142

def button?(screen_name)
  position(screen_name) && position(screen_name).zero?
end

#button_relative_seat(player_hash) ⇒ Object



114
115
116
# File 'lib/pokerstats/hand_statistics.rb', line 114

def button_relative_seat(player_hash)
  (player_hash[:seat] + MAX_SEATS - @button_player_index) % MAX_SEATS
end

#calculate_player_position(screen_name) ⇒ Object

long computation is cached, which cache is cleared every time a new player is registered



119
120
121
122
123
124
125
# File 'lib/pokerstats/hand_statistics.rb', line 119

def calculate_player_position screen_name
  @cached_player_position = {}
  @player_hashes.sort!{|a,b| button_relative_seat(a) <=> button_relative_seat(b)}
  @player_hashes = [@player_hashes.pop] + @player_hashes unless @player_hashes.first[:seat] == @button_player_index
  @player_hashes.each_with_index{|player, index| player[:position] = index, @cached_player_position[player[:screen_name]] = index}
  @cached_player_position[screen_name]
end

#cutoff?(screen_name) ⇒ Boolean

Returns:

  • (Boolean)


152
153
154
# File 'lib/pokerstats/hand_statistics.rb', line 152

def cutoff?(screen_name)
  position(screen_name) == cutoff_position
end

#cutoff_positionObject

The cutoff position is defined as the player to the left of the button if there are three players, otherwise nil



147
148
149
150
# File 'lib/pokerstats/hand_statistics.rb', line 147

def cutoff_position
  # formerly: (number_players > 3) && (-1 % number_players)
  -1 % number_players if number_players > 3
end

#hand_information(field) ⇒ Object



35
36
37
# File 'lib/pokerstats/hand_statistics.rb', line 35

def hand_information(field)
    @hand_information[field]
end

#hand_recordObject

Hand Information



28
29
30
31
32
33
# File 'lib/pokerstats/hand_statistics.rb', line 28

def hand_record
  raise Pokerstats::HandHistoryParseError, "#{HAND_RECORD_INCOMPLETE_MESSAGE}: #{(HAND_INFORMATION_KEYS - @hand_information.keys).inspect}" unless (HAND_INFORMATION_KEYS - @hand_information.keys).empty?
  HAND_INFORMATION_KEYS.inject({}) do |hash, key| 
    hash.merge!(key => @hand_information[key])
  end
end

#last_streetObject



86
87
88
# File 'lib/pokerstats/hand_statistics.rb', line 86

def last_street
    @last_street_state
end

#number_playersObject



64
65
66
# File 'lib/pokerstats/hand_statistics.rb', line 64

def number_players
  @player_hashes.size
end

#player_recordsObject



53
54
55
56
57
58
# File 'lib/pokerstats/hand_statistics.rb', line 53

def player_records
  raise Pokerstats::HandHistoryParseError, PLAYER_RECORDS_NO_PLAYER_REGISTERED if players.empty?
  raise Pokerstats::HandHistoryParseError, PLAYER_RECORDS_NO_BUTTON_REGISTERED if button.nil?
  raise Pokerstats::HandHistoryParseError, PLAYER_RECORDS_OUT_OF_BALANCE if out_of_balance
  self.player_records_without_validation
end

#player_records_without_validationObject

Player Information



49
50
51
# File 'lib/pokerstats/hand_statistics.rb', line 49

def player_records_without_validation
  @player_hashes
end

#playersObject



60
61
62
# File 'lib/pokerstats/hand_statistics.rb', line 60

def players
  @player_hashes.sort{|a, b| a[:seat] <=> b[:seat]}.collect{|each| each[:screen_name]}
end

#position(screen_name) ⇒ Object



127
128
129
# File 'lib/pokerstats/hand_statistics.rb', line 127

def position screen_name
  (@cached_player_position && @cached_player_position[screen_name]) || calculate_player_position(screen_name)
end

#register_action(screen_name, description, options = {}) ⇒ Object



192
193
194
195
196
197
198
199
# File 'lib/pokerstats/hand_statistics.rb', line 192

def register_action(screen_name, description, options={})
  raise Pokerstats::HandHistoryParseError, "#{PLAYER_RECORDS_UNREGISTERED_PLAYER}: #{screen_name.inspect}" unless players.member?(screen_name)
  plugins.each do |each|
    each.apply_action(
      {:screen_name => screen_name, :description => description, :aggression => aggression(description)}.update(options), 
      @street_state)
  end
end

#register_button(button_index) ⇒ Object

Button and Position Information



105
106
107
108
# File 'lib/pokerstats/hand_statistics.rb', line 105

def register_button button_index
  @cached_player_position = nil
  @button_player_index = button_index
end

#register_player(player) ⇒ Object



68
69
70
71
72
73
74
75
76
# File 'lib/pokerstats/hand_statistics.rb', line 68

def register_player player
  screen_name = player[:screen_name]
  raise Pokerstats::HandHistoryParseError, "#{PLAYER_RECORDS_DUPLICATE_PLAYER_NAME}: #{screen_name.inspect}" if players.member?(screen_name)
  @cached_player_position = nil
  @player_hashes << player
  @hand_information[:number_players]+=1
  plugins.each{|each| each.register_player(screen_name, @street_state, player)}  #why the second parameter?
  street_transition_for_player(@street_state, screen_name)
end

#report_hand_informationObject



217
218
219
# File 'lib/pokerstats/hand_statistics.rb', line 217

def report_hand_information
  @hand_information
end

#report_player(player) ⇒ Object

Reporting Information



205
206
207
208
209
# File 'lib/pokerstats/hand_statistics.rb', line 205

def report_player(player)
  result = {}
  plugins.each {|each| result.merge!(each.report(player))}
  result
end

#reportsObject



211
212
213
214
215
# File 'lib/pokerstats/hand_statistics.rb', line 211

def reports
  result = {}
  players.each{|each| result[each] = report_player(each)}
  result
end

#sbpos?(screen_name) ⇒ Boolean

Returns:

  • (Boolean)


160
161
162
# File 'lib/pokerstats/hand_statistics.rb', line 160

def sbpos?(screen_name)
  (number_players > 2) && position(screen_name) == 1
end

#streetObject

Street state information



82
83
84
# File 'lib/pokerstats/hand_statistics.rb', line 82

def street
  @street_state
end

#street_transition(street) ⇒ Object



90
91
92
93
94
95
# File 'lib/pokerstats/hand_statistics.rb', line 90

def street_transition street
  @last_street_state = @street_state
  @street_state = street
  plugins.each{|each| each.street_transition(street)}
  players.each {|player| street_transition_for_player(street, player)}
end

#street_transition_for_player(street, screen_name) ⇒ Object



97
98
99
# File 'lib/pokerstats/hand_statistics.rb', line 97

def street_transition_for_player street, screen_name
  plugins.each{|each| each.street_transition_for_player(street, screen_name)}
end

#update_hand(update) ⇒ Object



39
40
41
42
43
# File 'lib/pokerstats/hand_statistics.rb', line 39

def update_hand update
  street_transition(update[:street]) unless update[:street] == @street_state
  @hand_information.update(update)
  self
end