acpc_poker_types 0.0.10 → 1.0.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +7 -4
  3. data/acpc_poker_types.gemspec +4 -2
  4. data/lib/acpc_poker_types.rb +13 -12
  5. data/lib/acpc_poker_types/acpc_dealer_data.rb +9 -0
  6. data/lib/acpc_poker_types/acpc_dealer_data/action_messages.rb +133 -0
  7. data/lib/acpc_poker_types/acpc_dealer_data/hand_data.rb +182 -0
  8. data/lib/acpc_poker_types/acpc_dealer_data/hand_results.rb +79 -0
  9. data/lib/acpc_poker_types/acpc_dealer_data/log_file.rb +5 -0
  10. data/lib/acpc_poker_types/acpc_dealer_data/match_definition.rb +54 -0
  11. data/lib/acpc_poker_types/acpc_dealer_data/poker_match_data.rb +393 -0
  12. data/lib/acpc_poker_types/board_cards.rb +4 -4
  13. data/lib/acpc_poker_types/card.rb +16 -16
  14. data/lib/acpc_poker_types/chip_stack.rb +1 -1
  15. data/lib/acpc_poker_types/game_definition.rb +34 -38
  16. data/lib/acpc_poker_types/hand.rb +5 -5
  17. data/lib/acpc_poker_types/match_state.rb +31 -32
  18. data/lib/acpc_poker_types/pile_of_cards.rb +1 -1
  19. data/lib/acpc_poker_types/player.rb +16 -15
  20. data/lib/acpc_poker_types/poker_action.rb +6 -6
  21. data/lib/acpc_poker_types/rank.rb +2 -2
  22. data/lib/acpc_poker_types/suit.rb +4 -4
  23. data/lib/acpc_poker_types/version.rb +1 -1
  24. data/spec/action_messages_spec.rb +450 -0
  25. data/spec/board_cards_spec.rb +9 -9
  26. data/spec/card_spec.rb +20 -20
  27. data/spec/chip_stack_spec.rb +28 -29
  28. data/spec/game_definition_spec.rb +11 -11
  29. data/spec/hand_data_spec.rb +295 -0
  30. data/spec/hand_results_spec.rb +292 -0
  31. data/spec/hand_spec.rb +11 -11
  32. data/spec/match_definition_spec.rb +95 -0
  33. data/spec/match_state_spec.rb +105 -287
  34. data/spec/pile_of_cards_spec.rb +14 -14
  35. data/spec/player_spec.rb +61 -61
  36. data/spec/poker_action_spec.rb +49 -49
  37. data/spec/poker_match_data_spec.rb +388 -0
  38. data/spec/rank_spec.rb +19 -19
  39. data/spec/suit_spec.rb +19 -19
  40. data/spec/support/spec_helper.rb +28 -6
  41. metadata +55 -10
@@ -1,7 +1,7 @@
1
1
 
2
2
  require 'hand_evaluator'
3
3
 
4
- class PileOfCards < Array
4
+ class AcpcPokerTypes::PileOfCards < Array
5
5
  # @return [Integer] The strength of the strongest poker hand that can be made from this pile of cards.
6
6
  def to_poker_hand_strength
7
7
  HandEvaluator.rank_hand map { |card| card.to_i }
@@ -1,11 +1,11 @@
1
1
 
2
2
  require 'dmorrill10-utils'
3
3
 
4
- require File.expand_path('../chip_stack', __FILE__)
5
- require File.expand_path('../game_definition', __FILE__)
4
+ require 'acpc_poker_types/chip_stack'
5
+ require 'acpc_poker_types/hand'
6
6
 
7
7
  # Class to model a player.
8
- class Player
8
+ class AcpcPokerTypes::Player
9
9
  exceptions :incorrect_number_of_player_names
10
10
 
11
11
  def self.create_players(player_names, game_def)
@@ -17,10 +17,11 @@ class Player
17
17
  end
18
18
 
19
19
  game_def.number_of_players.times.inject([]) do |players, seat|
20
- players << Player.join_match(player_names[seat],
21
- seat,
22
- ChipStack.new(game_def.chip_stacks[seat])
23
- )
20
+ players << AcpcPokerTypes::Player.join_match(
21
+ player_names[seat],
22
+ seat,
23
+ AcpcPokerTypes::ChipStack.new(game_def.chip_stacks[seat])
24
+ )
24
25
  end
25
26
  end
26
27
 
@@ -31,10 +32,10 @@ class Player
31
32
  # number that represents the order that this player joined the dealer.
32
33
  attr_reader :seat
33
34
 
34
- # @return [ChipStack] This player's chip stack.
35
+ # @return [AcpcPokerTypes::ChipStack] This player's chip stack.
35
36
  attr_reader :chip_stack
36
37
 
37
- # @return [Array<ChipStack>] This player's contribution to the pot in the
38
+ # @return [Array<AcpcPokerTypes::ChipStack>] This player's contribution to the pot in the
38
39
  # current hand, organized by round.
39
40
  attr_reader :chip_contributions
40
41
 
@@ -74,8 +75,8 @@ class Player
74
75
  end
75
76
 
76
77
  def equal_on_public_info?(other)
77
- @name == other.name &&
78
- @seat == other.seat &&
78
+ @name == other.name &&
79
+ @seat == other.seat &&
79
80
  @chip_stack == other.chip_stack &&
80
81
  @chip_contributions == other.chip_contributions &&
81
82
  @chip_balance == other.chip_balance &&
@@ -85,7 +86,7 @@ class Player
85
86
  # @param [#to_i] blind_amount The blind amount for this player to pay.
86
87
  # @param [#to_i] chip_stack (see #chip_stack)
87
88
  # @param [Hand] hole_cards (see #hole_cards)
88
- def start_new_hand!(blind=ChipStack.new(0), chip_stack=@chip_stack, hole_cards=Hand.new)
89
+ def start_new_hand!(blind=AcpcPokerTypes::ChipStack.new(0), chip_stack=@chip_stack, hole_cards=AcpcPokerTypes::Hand.new)
89
90
  @chip_stack = chip_stack
90
91
  @hole_cards = hole_cards
91
92
  @actions_taken_this_hand = []
@@ -112,7 +113,7 @@ class Player
112
113
 
113
114
  # @return [Boolean] Reports whether or not this player has folded.
114
115
  def folded?
115
- @actions_taken_this_hand.any? do |actions|
116
+ @actions_taken_this_hand.any? do |actions|
116
117
  actions.any? { |action| action.to_sym == :fold }
117
118
  end
118
119
  end
@@ -163,8 +164,8 @@ class Player
163
164
  end
164
165
 
165
166
  # Take chips away from this player's chip stack.
166
- # @param (see ChipStack#-)
167
- # @raise (see ChipStack#-)
167
+ # @param (see AcpcPokerTypes::ChipStack#-)
168
+ # @raise (see AcpcPokerTypes::ChipStack#-)
168
169
  def take_from_chip_stack!(number_of_chips)
169
170
  @chip_stack -= number_of_chips
170
171
  @chip_balance -= number_of_chips.to_r
@@ -2,9 +2,9 @@
2
2
  require 'set'
3
3
  require 'dmorrill10-utils/class'
4
4
 
5
- require File.expand_path('../chip_stack', __FILE__)
5
+ require 'acpc_poker_types/chip_stack'
6
6
 
7
- class PokerAction
7
+ class AcpcPokerTypes::PokerAction
8
8
 
9
9
  exceptions :illegal_poker_action, :illegal_poker_action_modification
10
10
 
@@ -36,11 +36,11 @@ class PokerAction
36
36
  # @param [Symbol, String] action A representation of this action.
37
37
  # @param [Hash] context The context in which this action is being made. Recognized keys include +:modifier+,
38
38
  # +:acting_player_sees_wager+, and +:amount_to_put_in_pot+.
39
- # @raise IllegalPokerAction
39
+ # @raise IllegalAcpcPokerTypes::PokerAction
40
40
  def initialize(action, context={})
41
41
  (@symbol, @modifier) = validate_action(
42
- action,
43
- context[:modifier],
42
+ action,
43
+ context[:modifier],
44
44
  if context[:acting_player_sees_wager].nil?
45
45
  true
46
46
  else
@@ -95,7 +95,7 @@ class PokerAction
95
95
  modifier_to_use = if modifier
96
96
  modifier
97
97
  elsif !in_place_modifier.empty?
98
- ChipStack.new in_place_modifier.to_i
98
+ AcpcPokerTypes::ChipStack.new in_place_modifier.to_i
99
99
  end
100
100
 
101
101
  symbol_betting_type = LEGAL_ACTIONS.key(action_type) || action_type.to_sym
@@ -1,7 +1,7 @@
1
1
 
2
2
  require 'dmorrill10-utils'
3
3
 
4
- class Rank
4
+ class AcpcPokerTypes::Rank
5
5
  exceptions :unrecognized_rank
6
6
 
7
7
  DOMAIN = {
@@ -43,7 +43,7 @@ class Rank
43
43
  end
44
44
 
45
45
  def initialize(rank)
46
- @symbol = Rank.symbol_from_rank_token rank
46
+ @symbol = AcpcPokerTypes::Rank.symbol_from_rank_token rank
47
47
  end
48
48
 
49
49
  def to_sym
@@ -1,7 +1,7 @@
1
1
 
2
2
  require 'dmorrill10-utils'
3
3
 
4
- class Suit
4
+ class AcpcPokerTypes::Suit
5
5
  exceptions :unrecognized_suit
6
6
 
7
7
  DOMAIN = {
@@ -29,12 +29,12 @@ class Suit
29
29
  suit_hash = hash_from_suit_token suit
30
30
 
31
31
  raise UnrecognizedSuit, suit.to_s unless suit_hash
32
-
32
+
33
33
  suit_hash.first
34
34
  end
35
35
 
36
36
  def initialize(suit)
37
- @symbol = Suit.symbol_from_suit_token suit
37
+ @symbol = AcpcPokerTypes::Suit.symbol_from_suit_token suit
38
38
  end
39
39
 
40
40
  def to_sym
@@ -54,5 +54,5 @@ class Suit
54
54
 
55
55
  def to_html
56
56
  DOMAIN[@symbol][:html_character]
57
- end
57
+ end
58
58
  end
@@ -1,3 +1,3 @@
1
1
  module AcpcPokerTypes
2
- VERSION = '0.0.10'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -0,0 +1,450 @@
1
+
2
+ # Spec helper (must include first to track code coverage with SimpleCov)
3
+ require_relative 'support/spec_helper'
4
+
5
+ require 'mocha/setup'
6
+
7
+ require 'acpc_dealer'
8
+ require 'acpc_poker_types/match_state'
9
+ require 'acpc_poker_types/poker_action'
10
+
11
+ require 'acpc_poker_types/acpc_dealer_data/action_messages'
12
+ require 'acpc_poker_types/acpc_dealer_data/match_definition'
13
+ require 'acpc_poker_types/acpc_dealer_data/log_file'
14
+
15
+ describe AcpcPokerTypes::AcpcDealerData::ActionMessages do
16
+ before do
17
+ @data = nil
18
+ @final_score = nil
19
+ @patient = nil
20
+ @match_def = nil
21
+ @player_names = nil
22
+ @no_final_score = false
23
+ end
24
+
25
+ describe '::parse_to_message' do
26
+ it 'properly parses a ACPC log "TO . . ." line' do
27
+ [
28
+ "TO 1 at 1341695999.222281 MATCHSTATE:0:0::5d5c|\n" =>
29
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
30
+ 0,
31
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:0::5d5c|')
32
+ ),
33
+ "TO 2 at 1341695920.914907 MATCHSTATE:1:0:r19686:|9hQd\n" =>
34
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
35
+ 1,
36
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:0:r19686:|9hQd')
37
+ ),
38
+ "TO 3 at 1341696044.566738 MATCHSTATE:2:0:rf:||8dAs\n" =>
39
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
40
+ 2,
41
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:2:0:rf:||8dAs')
42
+ ),
43
+ "TO 1 at 1341715418.808925 MATCHSTATE:0:0:fcr17162:5d5c||\n" =>
44
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
45
+ 0,
46
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:0:fcr17162:5d5c||')
47
+ )
48
+ ].each do |to_message_to_data|
49
+ to_message_to_data.each do |to_message, expected_values|
50
+ AcpcPokerTypes::AcpcDealerData::ActionMessages.parse_to_message(to_message).must_equal expected_values
51
+ end
52
+ end
53
+ end
54
+ it 'returns nil if asked to parse an improperly formatted string' do
55
+ AcpcPokerTypes::AcpcDealerData::ActionMessages.parse_to_message("improperly formatted string").must_be_nil
56
+ end
57
+ end
58
+
59
+ describe '::parse_from_message' do
60
+ it 'properly parses a ACPC log "FROM . . ." line' do
61
+ [
62
+ "FROM 2 at 1341695999.222410 MATCHSTATE:1:0::|9hQd:c\n" =>
63
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
64
+ 1,
65
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:0::|9hQd'),
66
+ AcpcPokerTypes::PokerAction.new('c')
67
+ ),
68
+ "FROM 1 at 1341695920.914935 MATCHSTATE:0:0:r19686:5d5c|:r20000\n" =>
69
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
70
+ 0,
71
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:0:r19686:5d5c|'),
72
+ AcpcPokerTypes::PokerAction.new('r20000')
73
+ ),
74
+ "FROM 3 at 1341696044.566938 MATCHSTATE:2:0:rfr:||8dAs:r\n" =>
75
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
76
+ 2,
77
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:2:0:rfr:||8dAs'),
78
+ AcpcPokerTypes::PokerAction.new('r')
79
+ ),
80
+ "FROM 2 at 1341715418.808896 MATCHSTATE:1:0:fc:|9hQd|:r17162\n" =>
81
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
82
+ 1,
83
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:0:fc:|9hQd|'),
84
+ AcpcPokerTypes::PokerAction.new('r17162')
85
+ )
86
+ ].each do |from_message_to_data|
87
+ from_message_to_data.each do |from_message, expected_values|
88
+ AcpcPokerTypes::AcpcDealerData::ActionMessages.parse_from_message(from_message).must_equal expected_values
89
+ end
90
+ end
91
+ end
92
+ it 'returns nil if asked to parse an improperly formatted string' do
93
+ AcpcPokerTypes::AcpcDealerData::ActionMessages.parse_from_message("improperly formatted string").must_be_nil
94
+ end
95
+ end
96
+
97
+ describe '::parse_score' do
98
+ it 'properly parses a ACPC log "SCORE. . ." line' do
99
+ [
100
+ "SCORE:100|-100:p1|p2\n" => {p1: 100, p2: -100},
101
+ 'SCORE:19835|621.5|-20455.5:p1|p2|p3' => {p1: 19835, p2: 621.5, p3: -20455.5}
102
+ ].each do |score_to_player_results|
103
+ score_to_player_results.each do |score_string, expected_values|
104
+ AcpcPokerTypes::AcpcDealerData::ActionMessages.parse_score(score_string).must_equal expected_values
105
+ end
106
+ end
107
+ end
108
+ it 'returns nil if asked to parse an improperly formatted string' do
109
+ AcpcPokerTypes::AcpcDealerData::ActionMessages.parse_score("improperly formatted string").must_be_nil
110
+ end
111
+ end
112
+
113
+ describe 'properly parses ACPC log statements' do
114
+ describe 'from file' do
115
+ it 'when every hand is desired' do
116
+ init_data do |action_messages|
117
+ file_name = 'file_name'
118
+ AcpcPokerTypes::AcpcDealerData::LogFile.expects(:open).with(file_name, 'r').yields(
119
+ action_messages
120
+ ).returns(
121
+ AcpcPokerTypes::AcpcDealerData::ActionMessages.parse(
122
+ action_messages,
123
+ @player_names,
124
+ AcpcDealer::DEALER_DIRECTORY
125
+ )
126
+ )
127
+
128
+ @patient = AcpcPokerTypes::AcpcDealerData::ActionMessages.parse_file(
129
+ file_name,
130
+ @player_names,
131
+ AcpcDealer::DEALER_DIRECTORY
132
+ )
133
+
134
+ check_patient
135
+ end
136
+ end
137
+ it 'when a particular number of hands is desired' do
138
+ @no_final_score = true
139
+ num_hands = 1
140
+ init_data do |action_messages|
141
+ file_name = 'file_name'
142
+ AcpcPokerTypes::AcpcDealerData::LogFile.expects(:open).with(file_name, 'r').yields(
143
+ action_messages
144
+ ).returns(
145
+ AcpcPokerTypes::AcpcDealerData::ActionMessages.parse(
146
+ action_messages,
147
+ @player_names,
148
+ AcpcDealer::DEALER_DIRECTORY,
149
+ num_hands
150
+ )
151
+ )
152
+
153
+ @patient = AcpcPokerTypes::AcpcDealerData::ActionMessages.parse_file(
154
+ file_name,
155
+ @player_names,
156
+ AcpcDealer::DEALER_DIRECTORY,
157
+ num_hands
158
+ )
159
+
160
+ # Fix data to check patient against
161
+ @final_score = nil
162
+ @data = @data[0..num_hands-1]
163
+
164
+ check_patient
165
+ end
166
+ end
167
+ end
168
+ describe 'from array' do
169
+ it 'when all hands are desired' do
170
+ init_data do |action_messages|
171
+ @patient = AcpcPokerTypes::AcpcDealerData::ActionMessages.parse(
172
+ action_messages,
173
+ @player_names,
174
+ AcpcDealer::DEALER_DIRECTORY
175
+ )
176
+
177
+ check_patient
178
+ end
179
+ end
180
+ it 'when a particular number of hands is desired' do
181
+ @no_final_score = true
182
+ num_hands = 1
183
+ init_data do |log_statements|
184
+ @patient = AcpcPokerTypes::AcpcDealerData::ActionMessages.parse(
185
+ log_statements,
186
+ @player_names,
187
+ AcpcDealer::DEALER_DIRECTORY,
188
+ num_hands
189
+ )
190
+
191
+ # Fix data to check patient against
192
+ @final_score = nil
193
+ @data = @data[0..num_hands-1]
194
+
195
+ check_patient
196
+ end
197
+ end
198
+ end
199
+ end
200
+
201
+ def check_patient
202
+ @patient.data.must_equal @data
203
+ @patient.final_score.must_equal @final_score unless @no_final_score
204
+ @patient.match_def.must_equal @match_def
205
+ end
206
+
207
+ def init_data
208
+ all_data.each do |game, data_hash|
209
+ @final_score = data_hash[:final_score]
210
+ @data = data_hash[:data]
211
+ @player_names = data_hash[:player_names]
212
+ @match_def = AcpcPokerTypes::AcpcDealerData::MatchDefinition.parse(
213
+ data_hash[:action_messages].first,
214
+ @player_names,
215
+ AcpcDealer::DEALER_DIRECTORY
216
+ )
217
+
218
+ yield data_hash[:action_messages]
219
+ end
220
+ end
221
+
222
+ def all_data
223
+ {
224
+ two_player_limit: {
225
+ action_messages: [
226
+ "# name/game/hands/seed 2p.limit.h1000.r0 holdem.limit.2p.reverse_blinds.game 1000 0\n",
227
+ "TO 1 at 1341696000.058613 MATCHSTATE:1:998:crc/cc/cc/:|TdQd/As6d6h/7h/4s\n",
228
+ "TO 2 at 1341696000.058634 MATCHSTATE:0:998:crc/cc/cc/:Jc8d|/As6d6h/7h/4s\n",
229
+ "FROM 2 at 1341696000.058641 MATCHSTATE:0:998:crc/cc/cc/:Jc8d|/As6d6h/7h/4s:r\n",
230
+ "TO 1 at 1341696000.058664 MATCHSTATE:1:999:crc/cc/cc/r:|TdQd/As6d6h/7h/4s\n",
231
+ "TO 2 at 1341696000.058681 MATCHSTATE:0:999:crc/cc/cc/r:Jc8d|/As6d6h/7h/4s\n",
232
+ "FROM 1 at 1341696000.058688 MATCHSTATE:1:999:crc/cc/cc/r:|TdQd/As6d6h/7h/4s:c\n",
233
+ "TO 1 at 1341696000.058712 MATCHSTATE:1:999:crc/cc/cc/rc:Jc8d|TdQd/As6d6h/7h/4s\n",
234
+ "TO 2 at 1341696000.058732 MATCHSTATE:0:999:crc/cc/cc/rc:Jc8d|TdQd/As6d6h/7h/4s\n",
235
+ "FINISHED at 1341696000.058664\n",
236
+ 'SCORE:455|-455:p1|p2'
237
+ ],
238
+ data: [
239
+ [
240
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
241
+ 0,
242
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:998:crc/cc/cc/:|TdQd/As6d6h/7h/4s')
243
+ ),
244
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
245
+ 1,
246
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:998:crc/cc/cc/:Jc8d|/As6d6h/7h/4s')
247
+ ),
248
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
249
+ 1,
250
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:998:crc/cc/cc/:Jc8d|/As6d6h/7h/4s'),
251
+ AcpcPokerTypes::PokerAction.new('r')
252
+ )
253
+ ],
254
+ [
255
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
256
+ 0,
257
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:999:crc/cc/cc/r:|TdQd/As6d6h/7h/4s')
258
+ ),
259
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
260
+ 1,
261
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:999:crc/cc/cc/r:Jc8d|/As6d6h/7h/4s')
262
+ ),
263
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
264
+ 0,
265
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:999:crc/cc/cc/r:|TdQd/As6d6h/7h/4s'),
266
+ AcpcPokerTypes::PokerAction.new('c')
267
+ ),
268
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
269
+ 0,
270
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:999:crc/cc/cc/rc:Jc8d|TdQd/As6d6h/7h/4s')
271
+ ),
272
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
273
+ 1,
274
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:999:crc/cc/cc/rc:Jc8d|TdQd/As6d6h/7h/4s')
275
+ )
276
+ ]
277
+ ],
278
+ final_score: {p1: 455, p2: -455},
279
+ player_names: ['p1', 'p2']
280
+ },
281
+ two_player_nolimit: {
282
+ action_messages: [
283
+ "# name/game/hands/seed 2p.nolimit.h1000.r0 holdem.nolimit.2p.reverse_blinds.game 1000 0\n",
284
+ "TO 1 at 1341695921.617099 MATCHSTATE:0:998:cc/r5841r19996r20000:Kc6h|/QhAh8d\n",
285
+ "TO 2 at 1341695921.617126 MATCHSTATE:1:998:cc/r5841r19996r20000:|Qc3s/QhAh8d\n",
286
+ "FROM 2 at 1341695921.617133 MATCHSTATE:1:998:cc/r5841r19996r20000:|Qc3s/QhAh8d:c\n",
287
+ "TO 1 at 1341695921.617182 MATCHSTATE:0:998:cc/r5841r19996r20000c//:Kc6h|Qc3s/QhAh8d/Th/9d\n",
288
+ "TO 2 at 1341695921.617224 MATCHSTATE:1:998:cc/r5841r19996r20000c//:Kc6h|Qc3s/QhAh8d/Th/9d\n",
289
+ "TO 1 at 1341695921.617268 MATCHSTATE:1:999::|TdQd\n",
290
+ "TO 2 at 1341695921.617309 MATCHSTATE:0:999::Jc8d|\n",
291
+ "FROM 1 at 1341695921.617324 MATCHSTATE:1:999::|TdQd:f\n",
292
+ "TO 1 at 1341695921.617377 MATCHSTATE:1:999:f:|TdQd\n",
293
+ "TO 2 at 1341695921.617415 MATCHSTATE:0:999:f:Jc8d|\n",
294
+ "FINISHED at 1341695921.617268\n",
295
+ "SCORE:-64658|64658:p1|p2"
296
+ ],
297
+ data: [
298
+ [
299
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
300
+ 0,
301
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:998:cc/r5841r19996r20000:Kc6h|/QhAh8d')
302
+ ),
303
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
304
+ 1,
305
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:998:cc/r5841r19996r20000:|Qc3s/QhAh8d')
306
+ ),
307
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
308
+ 1,
309
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:998:cc/r5841r19996r20000:|Qc3s/QhAh8d:c'),
310
+ AcpcPokerTypes::PokerAction.new('c')
311
+ ),
312
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
313
+ 0,
314
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:998:cc/r5841r19996r20000c//:Kc6h|Qc3s/QhAh8d/Th/9d')
315
+ ),
316
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
317
+ 1,
318
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:998:cc/r5841r19996r20000c//:Kc6h|Qc3s/QhAh8d/Th/9d')
319
+ )
320
+ ],
321
+ [
322
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
323
+ 0,
324
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:999::|TdQd')
325
+ ),
326
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
327
+ 1,
328
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:999::Jc8d|')
329
+ ),
330
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
331
+ 0,
332
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:999::|TdQd'),
333
+ AcpcPokerTypes::PokerAction.new('f')
334
+ ),
335
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
336
+ 0,
337
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:999:f:|TdQd')
338
+ ),
339
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
340
+ 1,
341
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:999:f:Jc8d|')
342
+ )
343
+ ]
344
+ ],
345
+ final_score: {p1: -64658, p2: 64658},
346
+ player_names: ['p1', 'p2']
347
+ },
348
+ three_player_limit: {
349
+ action_messages: [
350
+ "# name/game/hands/seed 3p.limit.h1000.r0 holdem.limit.3p.game 1000 0\n",
351
+ "TO 1 at 1341696046.871086 MATCHSTATE:0:999:ccc/ccc/rrcc/rrrfr:QsAs||/4d6d2d/5d/2c\n",
352
+ "TO 2 at 1341696046.871128 MATCHSTATE:1:999:ccc/ccc/rrcc/rrrfr:|3s8h|/4d6d2d/5d/2c\n",
353
+ "TO 3 at 1341696046.871175 MATCHSTATE:2:999:ccc/ccc/rrcc/rrrfr:||Qd3c/4d6d2d/5d/2c\n",
354
+ "FROM 3 at 1341696046.871201 MATCHSTATE:2:999:ccc/ccc/rrcc/rrrfr:||Qd3c/4d6d2d/5d/2c:c\n",
355
+ "TO 1 at 1341696046.871245 MATCHSTATE:0:999:ccc/ccc/rrcc/rrrfrc:QsAs|3s8h|Qd3c/4d6d2d/5d/2c\n",
356
+ "TO 2 at 1341696046.871267 MATCHSTATE:1:999:ccc/ccc/rrcc/rrrfrc:|3s8h|Qd3c/4d6d2d/5d/2c\n",
357
+ "TO 3 at 1341696046.871313 MATCHSTATE:2:999:ccc/ccc/rrcc/rrrfrc:|3s8h|Qd3c/4d6d2d/5d/2c\n",
358
+ "FINISHED at 1341696046.871175\n",
359
+ "SCORE:-4330|625|3705:p1|p2|p3"
360
+ ],
361
+ data: [
362
+ [
363
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
364
+ 0,
365
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:999:ccc/ccc/rrcc/rrrfr:QsAs||/4d6d2d/5d/2c')
366
+ ),
367
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
368
+ 1,
369
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:999:ccc/ccc/rrcc/rrrfr:|3s8h|/4d6d2d/5d/2c')
370
+ ),
371
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
372
+ 2,
373
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:2:999:ccc/ccc/rrcc/rrrfr:||Qd3c/4d6d2d/5d/2c')
374
+ ),
375
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
376
+ 2,
377
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:2:999:ccc/ccc/rrcc/rrrfr:||Qd3c/4d6d2d/5d/2c'),
378
+ AcpcPokerTypes::PokerAction.new('c')
379
+ ),
380
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
381
+ 0,
382
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:999:ccc/ccc/rrcc/rrrfrc:QsAs|3s8h|Qd3c/4d6d2d/5d/2c')
383
+ ),
384
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
385
+ 1,
386
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:999:ccc/ccc/rrcc/rrrfrc:|3s8h|Qd3c/4d6d2d/5d/2c')
387
+ ),
388
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
389
+ 2,
390
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:2:999:ccc/ccc/rrcc/rrrfrc:|3s8h|Qd3c/4d6d2d/5d/2c')
391
+ )
392
+ ]
393
+ ],
394
+ final_score: {p1: -4330, p2: 625, p3: 3705},
395
+ player_names: ['p1', 'p2', 'p3']
396
+ },
397
+ three_player_nolimit: {
398
+ action_messages: [
399
+ "# name/game/hands/seed 3p.nolimit.h1000.r0 holdem.nolimit.3p.game 1000 0\n",
400
+ "TO 1 at 1341715420.129997 MATCHSTATE:0:998:ccr12926r20000c:QsAs||\n",
401
+ "TO 2 at 1341715420.130034 MATCHSTATE:1:998:ccr12926r20000c:|3s8h|\n",
402
+ "TO 3 at 1341715420.130070 MATCHSTATE:2:998:ccr12926r20000c:||Qd3c\n",
403
+ "FROM 2 at 1341715420.130093 MATCHSTATE:1:998:ccr12926r20000c:|3s8h|:c\n",
404
+ "TO 1 at 1341715420.130156 MATCHSTATE:0:999:ccr12926r20000cc///:QsAs|3s8h|Qd3c/4d6d2d/5d/2c\n",
405
+ "TO 2 at 1341715420.130191 MATCHSTATE:1:999:ccr12926r20000cc///:QsAs|3s8h|Qd3c/4d6d2d/5d/2c\n",
406
+ "TO 3 at 1341715420.130225 MATCHSTATE:2:999:ccr12926r20000cc///:QsAs|3s8h|Qd3c/4d6d2d/5d/2c\n",
407
+ "FINISHED at 1341715420.130034\n",
408
+ "SCORE:684452|552584.5|-1237036.5:p1|p2|p3"
409
+ ],
410
+ data: [
411
+ [
412
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
413
+ 0,
414
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:998:ccr12926r20000c:QsAs||')
415
+ ),
416
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
417
+ 1,
418
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:998:ccr12926r20000c:|3s8h|')
419
+ ),
420
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
421
+ 2,
422
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:2:998:ccr12926r20000c:||Qd3c')
423
+ ),
424
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::FromMessage.new(
425
+ 1,
426
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:998:ccr12926r20000c:|3s8h|'),
427
+ AcpcPokerTypes::PokerAction.new('c')
428
+ )
429
+ ],
430
+ [
431
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
432
+ 0,
433
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:0:999:ccr12926r20000cc///:QsAs|3s8h|Qd3c/4d6d2d/5d/2c')
434
+ ),
435
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
436
+ 1,
437
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:1:999:ccr12926r20000cc///:QsAs|3s8h|Qd3c/4d6d2d/5d/2c')
438
+ ),
439
+ AcpcPokerTypes::AcpcDealerData::ActionMessages::ToMessage.new(
440
+ 2,
441
+ AcpcPokerTypes::MatchState.parse('MATCHSTATE:2:999:ccr12926r20000cc///:QsAs|3s8h|Qd3c/4d6d2d/5d/2c')
442
+ )
443
+ ]
444
+ ],
445
+ final_score: {p1: 684452, p2: 552584.5, p3: -1237036.5},
446
+ player_names: ['p1', 'p2', 'p3']
447
+ }
448
+ }
449
+ end
450
+ end