Class: AcpcTableManager::Match
- Inherits:
-
Object
- Object
- AcpcTableManager::Match
- Includes:
- Mongoid::Document, Mongoid::Timestamps::Updated
- Defined in:
- lib/acpc_table_manager/match.rb
Constant Summary collapse
- UNIQUENESS_GUARANTEE_CHARACTER =
'_'
Class Method Summary collapse
- .create_with_defaults(user_name: 'Guest', game_definition_key: :two_player_limit, port_numbers: []) ⇒ Object
- .default_opponent_names(num_players) ⇒ Object
- .delete_finished_matches! ⇒ Object
- .delete_match!(match_id) ⇒ Object
-
.delete_matches_older_than!(lifespan) ⇒ Object
Deletion.
-
.finished ⇒ Object
Almost scopes.
- .id_exists?(match_id) ⇒ Boolean
- .include_game_definition ⇒ Object
-
.include_name ⇒ Object
Schema.
- .include_name_from_user ⇒ Object
- .include_number_of_hands ⇒ Object
- .include_opponent_names ⇒ Object
- .include_seat ⇒ Object
- .include_user_name ⇒ Object
-
.new_name(user_name, game_def_key: nil, num_hands: nil, seed: nil, seat: nil, time: true) ⇒ Object
Generators.
- .new_random_seat(num_players) ⇒ Object
- .new_random_seed ⇒ Object
- .started_and_unfinished ⇒ Object
- .unfinished(matches = all) ⇒ Object
Instance Method Summary collapse
- #all_slices_up_to_hand_end_viewed? ⇒ Boolean
- #all_slices_viewed? ⇒ Boolean
- #bot_special_port_requirements ⇒ Object
- #bots(dealer_host) ⇒ Object
- #copy? ⇒ Boolean
- #copy_for_next_human_player(next_user_name, next_seat) ⇒ Object
- #finish_starting! ⇒ Object
- #finished? ⇒ Boolean
- #game_def ⇒ Object
- #game_def_file_name_from_key ⇒ Object
- #game_def_hash_from_key ⇒ Object
-
#game_info ⇒ Object
Convenience accessors.
- #hand_number ⇒ Object
- #no_limit? ⇒ Boolean
- #opponent_ports ⇒ Object
- #opponent_ports_with_condition ⇒ Object
- #opponent_ports_without_condition ⇒ Object
- #opponent_seats(opponent_name) ⇒ Object
- #opponent_seats_with_condition ⇒ Object
- #player_names ⇒ Object
- #rejoinable_seats(user_name) ⇒ Object
- #running? ⇒ Boolean
- #set_game_definition_file_name!(file_name = ) ⇒ Object
- #set_game_definition_hash!(hash = self.game_def_hash) ⇒ Object
-
#set_name!(name_ = self.name_from_user) ⇒ Object
Initializers.
- #set_seat!(seat_ = self.seat) ⇒ Object
- #started? ⇒ Boolean
- #users_port ⇒ Object
Class Method Details
.create_with_defaults(user_name: 'Guest', game_definition_key: :two_player_limit, port_numbers: []) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/acpc_table_manager/match.rb', line 127 def create_with_defaults( user_name: 'Guest', game_definition_key: :two_player_limit, port_numbers: [] ) new( name_from_user: new_name(user_name), user_name: user_name, port_numbers: port_numbers, game_definition_key: game_definition_key ).finish_starting! end |
.default_opponent_names(num_players) ⇒ Object
123 124 125 |
# File 'lib/acpc_table_manager/match.rb', line 123 def default_opponent_names(num_players) (num_players - 1).times.map { |i| "Tester" } end |
.delete_finished_matches! ⇒ Object
145 146 147 148 149 150 |
# File 'lib/acpc_table_manager/match.rb', line 145 def delete_finished_matches! finished.each do |m| m.delete if m.all_slices_viewed? end self end |
.delete_match!(match_id) ⇒ Object
151 152 153 154 155 156 157 158 159 |
# File 'lib/acpc_table_manager/match.rb', line 151 def delete_match!(match_id) begin match = find match_id rescue Mongoid::Errors::DocumentNotFound else match.delete end self end |
.delete_matches_older_than!(lifespan) ⇒ Object
Deletion
141 142 143 144 |
# File 'lib/acpc_table_manager/match.rb', line 141 def delete_matches_older_than!(lifespan) old(lifespan).delete_all self end |
.finished ⇒ Object
Almost scopes
53 54 55 |
# File 'lib/acpc_table_manager/match.rb', line 53 def finished all.select { |match| match.finished? } end |
.id_exists?(match_id) ⇒ Boolean
48 49 50 |
# File 'lib/acpc_table_manager/match.rb', line 48 def id_exists?(match_id) where(id: match_id).exists? end |
.include_game_definition ⇒ Object
75 76 77 78 79 80 |
# File 'lib/acpc_table_manager/match.rb', line 75 def include_game_definition field :game_definition_key, type: Symbol validates_presence_of :game_definition_key field :game_definition_file_name field :game_def_hash, type: Hash end |
.include_name ⇒ Object
Schema
64 65 66 67 68 |
# File 'lib/acpc_table_manager/match.rb', line 64 def include_name field :name validates_presence_of :name validates_format_of :name, without: /\A\s*\z/ end |
.include_name_from_user ⇒ Object
69 70 71 72 73 74 |
# File 'lib/acpc_table_manager/match.rb', line 69 def include_name_from_user field :name_from_user validates_presence_of :name_from_user validates_format_of :name_from_user, without: /\A\s*\z/ validates_uniqueness_of :name_from_user end |
.include_number_of_hands ⇒ Object
81 82 83 84 85 |
# File 'lib/acpc_table_manager/match.rb', line 81 def include_number_of_hands field :number_of_hands, type: Integer validates_presence_of :number_of_hands validates_numericality_of :number_of_hands, greater_than: 0, only_integer: true end |
.include_opponent_names ⇒ Object
86 87 88 89 |
# File 'lib/acpc_table_manager/match.rb', line 86 def include_opponent_names field :opponent_names, type: Array validates_presence_of :opponent_names end |
.include_seat ⇒ Object
90 91 92 |
# File 'lib/acpc_table_manager/match.rb', line 90 def include_seat field :seat, type: Integer end |
.include_user_name ⇒ Object
93 94 95 96 97 |
# File 'lib/acpc_table_manager/match.rb', line 93 def include_user_name field :user_name validates_presence_of :user_name validates_format_of :user_name, without: /\A\s*\z/ end |
.new_name(user_name, game_def_key: nil, num_hands: nil, seed: nil, seat: nil, time: true) ⇒ Object
Generators
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/acpc_table_manager/match.rb', line 100 def new_name( user_name, game_def_key: nil, num_hands: nil, seed: nil, seat: nil, time: true ) name = "match.#{user_name}" name += ".#{game_def_key}" if game_def_key name += ".#{num_hands}h" if num_hands name += ".#{seat}s" if seat name += ".#{seed}r" if seed name += ".#{Time.now_as_string}" if time name end |
.new_random_seat(num_players) ⇒ Object
120 121 122 |
# File 'lib/acpc_table_manager/match.rb', line 120 def new_random_seat(num_players) rand(num_players) + 1 end |
.new_random_seed ⇒ Object
116 117 118 119 |
# File 'lib/acpc_table_manager/match.rb', line 116 def new_random_seed # The ACPC dealer requires 32 bit random seeds rand(2**33 - 1) end |
.started_and_unfinished ⇒ Object
59 60 61 |
# File 'lib/acpc_table_manager/match.rb', line 59 def started_and_unfinished() started.to_a.select { |match| !match.finished? } end |
.unfinished(matches = all) ⇒ Object
56 57 58 |
# File 'lib/acpc_table_manager/match.rb', line 56 def unfinished(matches=all) matches.select { |match| !match.finished? } end |
Instance Method Details
#all_slices_up_to_hand_end_viewed? ⇒ Boolean
293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/acpc_table_manager/match.rb', line 293 def all_slices_up_to_hand_end_viewed? (self.slices.length - 1).downto(0).each do |slice_index| slice = self.slices[slice_index] if slice.hand_has_ended if self.last_slice_viewed >= slice_index return true else return false end end end return all_slices_viewed? end |
#all_slices_viewed? ⇒ Boolean
290 291 292 |
# File 'lib/acpc_table_manager/match.rb', line 290 def all_slices_viewed? self.last_slice_viewed >= (self.slices.length - 1) end |
#bot_special_port_requirements ⇒ Object
309 310 311 312 313 |
# File 'lib/acpc_table_manager/match.rb', line 309 def bot_special_port_requirements ::AcpcTableManager.exhibition_config.bots(game_definition_key, *opponent_names).values.map do |bot| bot['requires_special_port'] end end |
#bots(dealer_host) ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/acpc_table_manager/match.rb', line 184 def bots(dealer_host) bot_info_from_config_that_match_opponents = ::AcpcTableManager.exhibition_config.bots(game_definition_key, *opponent_names) bot_opponent_ports = opponent_ports_with_condition do |name| bot_info_from_config_that_match_opponents.keys.include? name end raise unless ( port_numbers.length == player_names.length || bot_opponent_ports.length == bot_info_from_config_that_match_opponents.length ) bot_opponent_ports.zip( bot_info_from_config_that_match_opponents.keys, bot_info_from_config_that_match_opponents.values ).reduce({}) do |map, args| port_num, name, info = args map[name] = { runner: (if info['runner'] then info['runner'] else info end), host: dealer_host, port: port_num } map end end |
#copy? ⇒ Boolean
255 256 257 |
# File 'lib/acpc_table_manager/match.rb', line 255 def copy? self.name_from_user.match(/^#{UNIQUENESS_GUARANTEE_CHARACTER}+$/) end |
#copy_for_next_human_player(next_user_name, next_seat) ⇒ Object
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/acpc_table_manager/match.rb', line 238 def copy_for_next_human_player(next_user_name, next_seat) match = dup # This match was not given a name from the user, # so set this parameter to an arbitrary character match.name_from_user = UNIQUENESS_GUARANTEE_CHARACTER while !match.save do match.name_from_user << UNIQUENESS_GUARANTEE_CHARACTER end match.user_name = next_user_name # Swap seat match.seat = next_seat match.opponent_names.insert(seat - 1, user_name) match.opponent_names.delete_at(seat - 1) match.save!(validate: false) match end |
#finish_starting! ⇒ Object
229 230 231 232 233 234 235 |
# File 'lib/acpc_table_manager/match.rb', line 229 def finish_starting! set_name!.set_seat!.set_game_definition_file_name!.set_game_definition_hash! self.opponent_names ||= self.class().default_opponent_names(game_info['num_players']) self.number_of_hands ||= 1 save! self end |
#finished? ⇒ Boolean
284 285 286 |
# File 'lib/acpc_table_manager/match.rb', line 284 def finished? started? && self.slices.last.match_ended? end |
#game_def ⇒ Object
268 269 270 |
# File 'lib/acpc_table_manager/match.rb', line 268 def game_def @game_def ||= AcpcPokerTypes::GameDefinition.new(game_def_hash_from_key) end |
#game_def_file_name_from_key ⇒ Object
264 |
# File 'lib/acpc_table_manager/match.rb', line 264 def game_def_file_name_from_key() game_info['file'] end |
#game_def_hash_from_key ⇒ Object
265 266 267 |
# File 'lib/acpc_table_manager/match.rb', line 265 def game_def_hash_from_key() @game_def_hash_from_key ||= AcpcPokerTypes::GameDefinition.parse_file(game_def_file_name_from_key).to_h end |
#game_info ⇒ Object
Convenience accessors
260 261 262 |
# File 'lib/acpc_table_manager/match.rb', line 260 def game_info @game_info ||= AcpcTableManager.exhibition_config.games[self.game_definition_key.to_s] end |
#hand_number ⇒ Object
271 272 273 274 275 276 277 |
# File 'lib/acpc_table_manager/match.rb', line 271 def hand_number return nil if slices.last.nil? state = AcpcPokerTypes::MatchState.parse( slices.last.state_string ) if state then state.hand_number else nil end end |
#no_limit? ⇒ Boolean
278 279 280 |
# File 'lib/acpc_table_manager/match.rb', line 278 def no_limit? @is_no_limit ||= game_def.betting_type == AcpcPokerTypes::GameDefinition::BETTING_TYPES[:nolimit] end |
#opponent_ports ⇒ Object
317 318 319 320 321 |
# File 'lib/acpc_table_manager/match.rb', line 317 def opponent_ports port_numbers_ = port_numbers.dup users_port_ = port_numbers_.delete_at(seat - 1) port_numbers_ end |
#opponent_ports_with_condition ⇒ Object
330 331 332 333 334 |
# File 'lib/acpc_table_manager/match.rb', line 330 def opponent_ports_with_condition opponent_seats_with_condition { |player_name| yield player_name }.map do |opp_seat| port_numbers[opp_seat - 1] end end |
#opponent_ports_without_condition ⇒ Object
335 336 337 338 339 340 341 |
# File 'lib/acpc_table_manager/match.rb', line 335 def opponent_ports_without_condition local_opponent_ports = opponent_ports opponent_ports_with_condition { |player_name| yield player_name }.each do |port| local_opponent_ports.delete port end local_opponent_ports end |
#opponent_seats(opponent_name) ⇒ Object
327 328 329 |
# File 'lib/acpc_table_manager/match.rb', line 327 def opponent_seats(opponent_name) opponent_seats_with_condition { |player_name| player_name == opponent_name } end |
#opponent_seats_with_condition ⇒ Object
322 323 324 325 326 |
# File 'lib/acpc_table_manager/match.rb', line 322 def opponent_seats_with_condition player_names.each_index.select do |i| yield player_names[i] end.map { |s| s + 1 } - [self.seat] end |
#player_names ⇒ Object
306 307 308 |
# File 'lib/acpc_table_manager/match.rb', line 306 def player_names opponent_names.dup.insert seat-1, self.user_name end |
#rejoinable_seats(user_name) ⇒ Object
342 343 344 345 346 347 348 |
# File 'lib/acpc_table_manager/match.rb', line 342 def rejoinable_seats(user_name) ( opponent_seats(user_name) - # Remove seats already taken by players who have already joined this match self.class().where(name: self.name).ne(name_from_user: self.name).map { |m| m.seat } ) end |
#running? ⇒ Boolean
287 288 289 |
# File 'lib/acpc_table_manager/match.rb', line 287 def running? self.is_running end |
#set_game_definition_file_name!(file_name = ) ⇒ Object
222 223 224 225 |
# File 'lib/acpc_table_manager/match.rb', line 222 def set_game_definition_file_name!(file_name = game_info['file']) self.game_definition_file_name = file_name self end |
#set_game_definition_hash!(hash = self.game_def_hash) ⇒ Object
226 227 228 |
# File 'lib/acpc_table_manager/match.rb', line 226 def set_game_definition_hash!(hash = self.game_def_hash) self.game_def_hash = hash || game_def_hash_from_key end |
#set_name!(name_ = self.name_from_user) ⇒ Object
Initializers
209 210 211 212 213 214 |
# File 'lib/acpc_table_manager/match.rb', line 209 def set_name!(name_ = self.name_from_user) name_from_user_ = name_.strip self.name = name_from_user_ self.name_from_user = name_from_user_ self end |
#set_seat!(seat_ = self.seat) ⇒ Object
215 216 217 218 219 220 221 |
# File 'lib/acpc_table_manager/match.rb', line 215 def set_seat!(seat_ = self.seat) self.seat = seat_ || self.class().new_random_seat(game_info['num_players']) if self.seat > game_info['num_players'] self.seat = game_info['num_players'] end self end |
#started? ⇒ Boolean
281 282 283 |
# File 'lib/acpc_table_manager/match.rb', line 281 def started? !self.slices.empty? end |
#users_port ⇒ Object
314 315 316 |
# File 'lib/acpc_table_manager/match.rb', line 314 def users_port port_numbers[seat - 1] end |