acpc_poker_types 3.0.2 → 3.1.0

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/acpc_poker_types.gemspec +10 -9
  3. data/lib/acpc_poker_types/acpc_dealer_data/hand_data.rb +46 -16
  4. data/lib/acpc_poker_types/acpc_dealer_data/hand_results.rb +1 -2
  5. data/lib/acpc_poker_types/acpc_dealer_data/match_definition.rb +3 -3
  6. data/lib/acpc_poker_types/acpc_dealer_data/poker_match_data.rb +72 -49
  7. data/lib/acpc_poker_types/card.rb +4 -4
  8. data/lib/acpc_poker_types/chip_stack.rb +4 -2
  9. data/lib/acpc_poker_types/match_state.rb +4 -6
  10. data/lib/acpc_poker_types/poker_action.rb +4 -3
  11. data/lib/acpc_poker_types/rank.rb +2 -2
  12. data/lib/acpc_poker_types/suit.rb +2 -2
  13. data/lib/acpc_poker_types/version.rb +1 -1
  14. data/spec/coverage/assets/0.5.3/app.js +88 -0
  15. data/spec/coverage/assets/0.5.3/fancybox/blank.gif +0 -0
  16. data/spec/coverage/assets/0.5.3/fancybox/fancy_close.png +0 -0
  17. data/spec/coverage/assets/0.5.3/fancybox/fancy_loading.png +0 -0
  18. data/spec/coverage/assets/0.5.3/fancybox/fancy_nav_left.png +0 -0
  19. data/spec/coverage/assets/0.5.3/fancybox/fancy_nav_right.png +0 -0
  20. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_e.png +0 -0
  21. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_n.png +0 -0
  22. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_ne.png +0 -0
  23. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_nw.png +0 -0
  24. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_s.png +0 -0
  25. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_se.png +0 -0
  26. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_sw.png +0 -0
  27. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_w.png +0 -0
  28. data/spec/coverage/assets/0.5.3/fancybox/fancy_title_left.png +0 -0
  29. data/spec/coverage/assets/0.5.3/fancybox/fancy_title_main.png +0 -0
  30. data/spec/coverage/assets/0.5.3/fancybox/fancy_title_over.png +0 -0
  31. data/spec/coverage/assets/0.5.3/fancybox/fancy_title_right.png +0 -0
  32. data/spec/coverage/assets/0.5.3/fancybox/fancybox-x.png +0 -0
  33. data/spec/coverage/assets/0.5.3/fancybox/fancybox-y.png +0 -0
  34. data/spec/coverage/assets/0.5.3/fancybox/fancybox.png +0 -0
  35. data/spec/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.css +363 -0
  36. data/spec/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.pack.js +44 -0
  37. data/spec/coverage/assets/0.5.3/favicon_green.png +0 -0
  38. data/spec/coverage/assets/0.5.3/favicon_red.png +0 -0
  39. data/spec/coverage/assets/0.5.3/favicon_yellow.png +0 -0
  40. data/spec/coverage/assets/0.5.3/highlight.css +129 -0
  41. data/spec/coverage/assets/0.5.3/highlight.pack.js +1 -0
  42. data/spec/coverage/assets/0.5.3/jquery-1.6.2.min.js +18 -0
  43. data/spec/coverage/assets/0.5.3/jquery.dataTables.min.js +152 -0
  44. data/spec/coverage/assets/0.5.3/jquery.timeago.js +141 -0
  45. data/spec/coverage/assets/0.5.3/jquery.url.js +174 -0
  46. data/spec/coverage/assets/0.5.3/loading.gif +0 -0
  47. data/spec/coverage/assets/0.5.3/magnify.png +0 -0
  48. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  49. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  50. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  51. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  52. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  53. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  54. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  55. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  56. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_222222_256x240.png +0 -0
  57. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  58. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_454545_256x240.png +0 -0
  59. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_888888_256x240.png +0 -0
  60. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  61. data/spec/coverage/assets/0.5.3/smoothness/jquery-ui-1.8.4.custom.css +295 -0
  62. data/spec/coverage/assets/0.5.3/stylesheet.css +383 -0
  63. data/spec/coverage/index.html +1 -1
  64. data/spec/hand_data_spec.rb +1 -1
  65. metadata +260 -148
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4486cbb027fcef016f2c31f6cb33360b618a17e0
4
- data.tar.gz: c06bc66f83a1609b25e7a8f30b577cb99c121454
3
+ metadata.gz: 360776ad7098c8fdb25bb82e62ada4ae80ae65ae
4
+ data.tar.gz: 8fb88c8dad1c962c95aca4926cb927b53d4570cc
5
5
  SHA512:
6
- metadata.gz: 7f10ec42bac803bd7a134d1fa3686ce45462fab47f56672050704c249fb48c3b4c0aa942ed911e8083805143992b0a39f41d3041e718aef984bcb8ca379794ce
7
- data.tar.gz: fd175bdd332b8cdad9ad26baff8663364cfdadc8db1f65bc320864d5b409193c833c4045f21d21632e8f9b217423751ceaa86e92ffcbfd7a97cb67ab8c886c16
6
+ metadata.gz: 31d5a12377b31af437d306e48735a66131beb7f4b435ad874e37cbf539a10a722e273ca50aacf22774d470b5b0dc994120d0157417688c1510dfa778643ca35a
7
+ data.tar.gz: 12516ae9be8561af5b8bbcdab9a36119756008f5af961530edbd6ed85336c52a39b51d646051913bea96fe86e4359194b09ab8d0d4f349ad1af15f3175a7999f
@@ -11,17 +11,18 @@ Gem::Specification.new do |s|
11
11
  s.description = %q{Poker classes and constants that conform to the standards of the Annual Computer Poker Competition.}
12
12
 
13
13
  s.add_dependency 'dmorrill10-utils', '~> 1.0'
14
- s.add_dependency 'acpc_dealer', '~> 0.0'
15
- s.add_dependency 'celluloid', '~> 0.13'
16
-
17
- s.add_development_dependency 'awesome_print'
18
- s.add_development_dependency 'minitest'
19
- s.add_development_dependency 'turn'
20
- s.add_development_dependency 'pry-rescue'
21
- s.add_development_dependency 'mocha'
22
- s.add_development_dependency 'simplecov'
14
+ s.add_dependency 'acpc_dealer', '~> 1.0'
15
+ s.add_dependency 'celluloid', '~> 0.14'
16
+ s.add_dependency 'contextual_exceptions', '~> 0.0'
23
17
 
24
18
  s.files = Dir.glob("lib/**/*") + %w(Rakefile acpc_poker_types.gemspec README.md)
25
19
  s.test_files = Dir.glob "spec/**/*"
26
20
  s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency 'turn', '~> 0.9'
23
+ s.add_development_dependency 'minitest', '~> 4.7'
24
+ s.add_development_dependency 'mocha', '~> 0.13'
25
+ s.add_development_dependency 'awesome_print', '~> 1.0'
26
+ s.add_development_dependency 'pry-rescue', '~> 1.0'
27
+ s.add_development_dependency 'simplecov', '~> 0.7'
27
28
  end
@@ -1,18 +1,23 @@
1
-
2
- require 'dmorrill10-utils/class'
3
-
4
1
  require 'acpc_poker_types/acpc_dealer_data/match_definition'
5
2
 
6
- # Monkey patch for easy boundary checking
7
- class Array
8
- def in_bounds?(i)
9
- i < length
3
+ require 'contextual_exceptions'
4
+ using ContextualExceptions::ClassRefinement
5
+
6
+ # Refinement for easy boundary checking
7
+ module AcpcPokerTypes::AcpcDealerData
8
+ module BoundaryCheckingRefinement
9
+ refine Array do
10
+ def in_bounds?(i)
11
+ i < length
12
+ end
13
+ end
10
14
  end
11
15
  end
16
+ using AcpcPokerTypes::AcpcDealerData::BoundaryCheckingRefinement
12
17
 
13
18
  module AcpcPokerTypes::AcpcDealerData
14
19
  class HandData
15
- exceptions :match_definitions_do_not_match, :invalid_data
20
+ exceptions :invalid_data, :names_do_not_match
16
21
 
17
22
  attr_accessor(
18
23
  # @returns [Array<Numeric>] Chip distribution at the end of the hand
@@ -43,7 +48,9 @@ module AcpcPokerTypes::AcpcDealerData
43
48
  set_data! action_data
44
49
 
45
50
  @turn_number = nil
46
- @seat = nil
51
+
52
+ # Zero-indexed seat
53
+ @seat = 0
47
54
  end
48
55
 
49
56
  def ==(other)
@@ -52,18 +59,30 @@ module AcpcPokerTypes::AcpcDealerData
52
59
  @data == other.data
53
60
  end
54
61
 
55
- def for_every_turn!(seat=0)
62
+ def start_hand!(seat=@seat)
56
63
  @seat = seat
57
- @data.each_index do |i|
58
- @turn_number = i
64
+ end
59
65
 
60
- yield @turn_number
61
- end
66
+ def next_turn!
67
+ init_or_increment_turn_num!
68
+ end
62
69
 
70
+ def end_hand!
63
71
  @turn_number = nil
64
72
  self
65
73
  end
66
74
 
75
+ def for_every_turn!(seat=@seat)
76
+ start_hand! seat
77
+
78
+ while @turn_number.nil? || (@turn_number < @data.length - 1) do
79
+ next_turn!
80
+ yield @turn_number
81
+ end
82
+
83
+ end_hand!
84
+ end
85
+
67
86
  def current_match_state(seat=@seat)
68
87
  if @turn_number
69
88
  @data[@turn_number].state_messages[seat]
@@ -112,8 +131,11 @@ module AcpcPokerTypes::AcpcDealerData
112
131
  result.each do |player_name, amount|
113
132
  begin
114
133
  @chip_distribution[@match_def.player_names.index(player_name.to_s)] = amount
115
- rescue TypeError
116
- raise PlayerNamesDoNotMatch
134
+ rescue TypeError => e
135
+ raise NamesDoNotMatch.with_context(
136
+ "Player name \"#{player_name.to_s}\" in match definition is not listed in final chip distribution",
137
+ e
138
+ )
117
139
  end
118
140
  end
119
141
  end
@@ -178,5 +200,13 @@ module AcpcPokerTypes::AcpcDealerData
178
200
  raise InvalidData, action_data[message_number].inspect
179
201
  end
180
202
  end
203
+ def init_or_increment_turn_num!
204
+ if @turn_number
205
+ @turn_number += 1
206
+ else
207
+ @turn_number = 0
208
+ end
209
+ self
210
+ end
181
211
  end
182
212
  end
@@ -1,5 +1,4 @@
1
-
2
- require 'dmorrill10-utils/class'
1
+ require 'dmorrill10-utils/class' # For alias_new
3
2
 
4
3
  require 'acpc_poker_types/acpc_dealer_data/match_definition'
5
4
  require 'acpc_poker_types/acpc_dealer_data/log_file'
@@ -1,14 +1,14 @@
1
-
2
1
  require 'set'
3
2
 
4
3
  require 'acpc_poker_types/game_definition'
5
4
 
6
- require 'dmorrill10-utils/class'
5
+ require 'contextual_exceptions'
6
+ using ContextualExceptions::ClassRefinement
7
7
 
8
8
  module AcpcPokerTypes::AcpcDealerData
9
9
  class MatchDefinition
10
10
 
11
- exceptions :unable_to_parse, :incorrect_number_of_player_names
11
+ exceptions :incorrect_number_of_player_names
12
12
 
13
13
  attr_reader :name, :game_def, :number_of_hands, :random_seed, :player_names
14
14
 
@@ -3,17 +3,18 @@ require 'acpc_poker_types/player'
3
3
 
4
4
  require 'celluloid/autostart'
5
5
 
6
- require 'dmorrill10-utils/class'
7
-
8
6
  require 'acpc_poker_types/acpc_dealer_data/action_messages'
9
7
  require 'acpc_poker_types/acpc_dealer_data/hand_data'
10
8
  require 'acpc_poker_types/acpc_dealer_data/hand_results'
11
9
  require 'acpc_poker_types/acpc_dealer_data/match_definition'
12
10
 
11
+ require 'contextual_exceptions'
12
+ using ContextualExceptions::ClassRefinement
13
+
13
14
  module AcpcPokerTypes::AcpcDealerData
14
15
  class PokerMatchData
15
16
 
16
- exceptions :match_definitions_do_not_match, :final_scores_do_not_match, :player_data_inconsistent
17
+ exceptions :match_definitions_do_not_match, :final_scores_do_not_match, :data_inconsistent, :names_do_not_match
17
18
 
18
19
  attr_accessor(
19
20
  # @returns [Array<Numeric>] Chip distribution at the end of the match
@@ -144,58 +145,64 @@ module AcpcPokerTypes::AcpcDealerData
144
145
 
145
146
  def player(seat=@seat) @players[seat] end
146
147
 
147
- def for_every_hand!
148
- initialize_players!
149
-
150
- @data.each_index do |i|
151
- @hand_number = i
152
-
153
- @players.each_with_index do |player, seat|
154
- player.start_new_hand!(
155
- @match_def.game_def.blinds[current_hand.data.first.state_messages[seat].position_relative_to_dealer],
156
- @match_def.game_def.chip_stacks[current_hand.data.first.state_messages[seat].position_relative_to_dealer],
157
- current_hand.data.first.state_messages[seat].users_hole_cards
158
- )
159
- end
160
-
161
- yield @hand_number
162
- end
148
+ def next_hand!
149
+ init_or_increment_hand_num!
150
+ provide_players_with_new_hand!
151
+ current_hand.start_hand! @seat
152
+ end
163
153
 
154
+ def end_match!
164
155
  if @chip_distribution && @chip_distribution != @players.map { |p| p.chip_balance }
165
- raise AcpcPokerTypes::DataInconsistent, "chip distribution: #{@chip_distribution}, player balances: #{@players.map { |p| p.chip_balance }}"
156
+ raise DataInconsistent, "chip distribution: #{@chip_distribution}, player balances: #{@players.map { |p| p.chip_balance }}"
166
157
  end
167
158
 
168
159
  @hand_number = nil
169
160
  self
170
161
  end
171
162
 
172
- def for_every_turn!
173
- current_hand.for_every_turn!(@seat) do |turn_number|
174
- @players.each_with_index do |player, seat|
175
- last_match_state = current_hand.last_match_state(seat)
176
- match_state = current_hand.current_match_state(seat)
163
+ def for_every_hand!
164
+ while @hand_number.nil? || (@hand_number < @data.length - 1) do
165
+ next_hand!
166
+ yield @hand_number
167
+ current_hand.end_hand!
168
+ end
177
169
 
178
- if current_hand.last_action && player.seat == current_hand.last_action.seat
170
+ end_match!
171
+ end
172
+
173
+ def next_turn!
174
+ current_hand.next_turn!
175
+
176
+ @players.each_with_index do |player, seat|
177
+ last_match_state = current_hand.last_match_state(seat)
178
+ match_state = current_hand.current_match_state(seat)
179
179
 
180
- player.take_action!(current_hand.last_action.action)
181
- end
180
+ if current_hand.last_action && player.seat == current_hand.last_action.seat
181
+
182
+ player.take_action!(current_hand.last_action.action)
183
+ end
182
184
 
183
- if (
184
- player.active? &&
185
- !match_state.first_state_of_first_round? &&
186
- match_state.round > last_match_state.round
185
+ if (
186
+ player.active? &&
187
+ !match_state.first_state_of_first_round? &&
188
+ match_state.round > last_match_state.round
189
+ )
190
+ player.start_new_round!
191
+ end
192
+
193
+ if current_hand.final_turn?
194
+ player.take_winnings!(
195
+ current_hand.chip_distribution[seat] + @match_def.game_def.blinds[current_hand.current_match_state(seat).position_relative_to_dealer]
187
196
  )
188
- player.start_new_round!
189
- end
190
-
191
- if current_hand.final_turn?
192
- player.take_winnings!(
193
- current_hand.chip_distribution[seat] + @match_def.game_def.blinds[current_hand.current_match_state(seat).position_relative_to_dealer]
194
- )
195
- end
196
197
  end
198
+ end
199
+ self
200
+ end
197
201
 
198
- yield turn_number
202
+ def for_every_turn!
203
+ while current_hand.turn_number.nil? || (current_hand.turn_number < current_hand.data.length - 1) do
204
+ next_turn!
205
+ yield current_hand.turn_number
199
206
  end
200
207
 
201
208
  self
@@ -343,7 +350,6 @@ module AcpcPokerTypes::AcpcDealerData
343
350
  @match_def.game_def.chip_stacks[seat]
344
351
  )
345
352
  end
346
-
347
353
  self
348
354
  end
349
355
 
@@ -352,11 +358,13 @@ module AcpcPokerTypes::AcpcDealerData
352
358
  final_score.each do |player_name, amount|
353
359
  begin
354
360
  @chip_distribution[@match_def.player_names.index(player_name.to_s)] = amount
355
- rescue TypeError
356
- raise AcpcPokerTypes::NamesDoNotMatch
361
+ rescue TypeError => e
362
+ raise NamesDoNotMatch.with_context(
363
+ "Player name \"#{player_name.to_s}\" in match definition is not listed in final chip distribution",
364
+ e
365
+ )
357
366
  end
358
367
  end
359
-
360
368
  self
361
369
  end
362
370
 
@@ -369,7 +377,6 @@ module AcpcPokerTypes::AcpcDealerData
369
377
  hand_result
370
378
  )
371
379
  end
372
-
373
380
  self
374
381
  end
375
382
 
@@ -379,15 +386,31 @@ module AcpcPokerTypes::AcpcDealerData
379
386
  current_hand.data.length == turn_index + 2 &&
380
387
  current_round < (@match_def.game_def.number_of_rounds - 1) &&
381
388
  (turns_taken[0..turn_index].count do |t|
382
- # @todo Use FOLD constant instead once poker action has one
383
- t.action_message.action.to_acpc_character == 'f'
389
+ t.action_message.action.to_acpc_character == AcpcPokerTypes::PokerAction::FOLD
384
390
  end) != @players.length - 1
385
391
  end
386
-
387
392
  def new_round?(current_round, turn_index)
388
393
  current_hand.data.length > turn_index + 1 &&
389
394
  current_hand.data[turn_index + 1].action_message &&
390
395
  current_hand.data[turn_index + 1].action_message.state.round > current_round
391
396
  end
397
+ def provide_players_with_new_hand!
398
+ @players.each_with_index do |player, seat|
399
+ player.start_new_hand!(
400
+ @match_def.game_def.blinds[current_hand.data.first.state_messages[seat].position_relative_to_dealer],
401
+ @match_def.game_def.chip_stacks[current_hand.data.first.state_messages[seat].position_relative_to_dealer],
402
+ current_hand.data.first.state_messages[seat].users_hole_cards
403
+ )
404
+ end
405
+ self
406
+ end
407
+ def init_or_increment_hand_num!
408
+ if @hand_number
409
+ @hand_number += 1
410
+ else
411
+ @hand_number = 0
412
+ end
413
+ self
414
+ end
392
415
  end
393
416
  end
@@ -1,5 +1,5 @@
1
1
 
2
- require 'dmorrill10-utils'
2
+ require 'dmorrill10-utils' # For alias_new
3
3
 
4
4
  require 'acpc_poker_types/rank'
5
5
  require 'acpc_poker_types/suit'
@@ -8,7 +8,7 @@ module AcpcPokerTypes
8
8
  class Card
9
9
  CONCATONATED_RANKS = (AcpcPokerTypes::Rank::DOMAIN.map { |rank, properties| properties[:acpc_character] }).join
10
10
  CONCATONATED_SUITS = (AcpcPokerTypes::Suit::DOMAIN.map { |suit, properties| properties[:acpc_character] }).join
11
- CONCATONATED_CARDS = CONCATONATED_RANKS + CONCATONATED_SUITS
11
+ CONCATONATED_CARDS = "#{CONCATONATED_RANKS}#{CONCATONATED_SUITS}"
12
12
 
13
13
  # @param [String] acpc_string_of_cards A string of cards in ACPC format
14
14
  # @return [Array<AcpcPokerTypes::Card>]
@@ -45,13 +45,13 @@ module AcpcPokerTypes
45
45
  end
46
46
 
47
47
  def to_str
48
- @rank.to_s + @suit.to_s
48
+ "#{@rank}#{@suit}"
49
49
  end
50
50
 
51
51
  alias_method :to_s, :to_str
52
52
 
53
53
  def to_acpc
54
- @rank.to_acpc + @suit.to_acpc
54
+ "#{@rank.to_acpc}#{@suit.to_acpc}"
55
55
  end
56
56
  end
57
57
  end
@@ -1,6 +1,8 @@
1
- require 'dmorrill10-utils/class'
2
1
  require 'delegate'
3
2
 
3
+ require 'contextual_exceptions'
4
+ using ContextualExceptions::ClassRefinement
5
+
4
6
  module AcpcPokerTypes
5
7
  class ChipStack < DelegateClass(Rational)
6
8
  exceptions :illegal_number_of_chips
@@ -32,7 +34,7 @@ module AcpcPokerTypes
32
34
 
33
35
  # @raise IllegalNumberOfChips
34
36
  def assert_valid_value
35
- raise IllegalNumberOfChips if @value < 0
37
+ raise IllegalNumberOfChips, "\"#{@value.to_s}\" is an invalid value of chips (cannot be negative)" if @value < 0
36
38
  end
37
39
  end
38
40
  end
@@ -56,10 +56,8 @@ module AcpcPokerTypes
56
56
  all_hole_cards,
57
57
  board_cards
58
58
  )
59
- string = LABEL +
60
- ":#{position_relative_to_dealer}:#{hand_number}:#{betting_sequence}:#{all_hole_cards}"
61
-
62
- string += board_cards.to_acpc if board_cards && !board_cards.empty?
59
+ string = "#{LABEL}:#{position_relative_to_dealer}:#{hand_number}:#{betting_sequence}:#{all_hole_cards}"
60
+ string << board_cards.to_acpc if board_cards && !board_cards.empty?
63
61
  string
64
62
  end
65
63
 
@@ -160,8 +158,8 @@ module AcpcPokerTypes
160
158
  # +betting_sequence+.
161
159
  def betting_sequence_string(betting_sequence=@betting_sequence)
162
160
  (round + 1).times.inject('') do |string, i|
163
- string += (betting_sequence[i].map { |action| action.to_s }).join('')
164
- string += '/' unless i == round
161
+ string << (betting_sequence[i].map { |action| action.to_s }).join('')
162
+ string << '/' unless i == round
165
163
  string
166
164
  end
167
165
  end
@@ -1,9 +1,10 @@
1
-
2
1
  require 'set'
3
- require 'dmorrill10-utils/class'
4
2
 
5
3
  require 'acpc_poker_types/chip_stack'
6
4
 
5
+ require 'contextual_exceptions'
6
+ using ContextualExceptions::ClassRefinement
7
+
7
8
  module AcpcPokerTypes
8
9
  class PokerAction
9
10
  exceptions :illegal_action, :illegal_modification
@@ -76,7 +77,7 @@ module AcpcPokerTypes
76
77
  private
77
78
 
78
79
  def combine_action_and_modifier(action=@action, modifier=@modifier)
79
- action + modifier.to_s
80
+ "#{action}#{modifier}"
80
81
  end
81
82
 
82
83
  def validate_action!(action, given_modifier)