acpc_poker_types 3.0.2 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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)