acpc_poker_types 7.3.3 → 7.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +0 -0
- data/acpc_poker_types.gemspec +0 -2
- data/lib/acpc_poker_types/hand_player.rb +9 -1
- data/lib/acpc_poker_types/match_state.rb +100 -36
- data/lib/acpc_poker_types/players_at_the_table.rb +2 -1
- data/lib/acpc_poker_types/version.rb +1 -1
- data/spec/match_state_spec.rb +233 -32
- data/spec/players_at_the_table_spec.rb +1 -4
- data/spec/support/spec_helper.rb +0 -1
- metadata +56 -166
- data/spec/coverage/assets/0.7.1/application.css +0 -1110
- data/spec/coverage/assets/0.7.1/application.js +0 -626
- data/spec/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
- data/spec/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
- data/spec/coverage/assets/0.7.1/favicon_green.png +0 -0
- data/spec/coverage/assets/0.7.1/favicon_red.png +0 -0
- data/spec/coverage/assets/0.7.1/favicon_yellow.png +0 -0
- data/spec/coverage/assets/0.7.1/loading.gif +0 -0
- data/spec/coverage/assets/0.7.1/magnify.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/coverage/index.html +0 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6d8abfb13245c11549049475c1580e317e5f7c9
|
4
|
+
data.tar.gz: fa482033db1d70882e3412f5a2a18ddd9e7616ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c8f50a9f133902e258aa222184177e1085bae0920925ec47eac2bd9571fb400c485c54942c727334421f3f1897d2dbd8e9cdd48234a235e650a6a0f91da8ccf
|
7
|
+
data.tar.gz: 2932fe75d0878488e32ec8a2795ff2240957932b5b33c88a8390e84e1854c757e365afb25782375d8fef61ff2cf676dd98e9d619fdfad3a616370c046c9a6203
|
data/Rakefile
CHANGED
File without changes
|
data/acpc_poker_types.gemspec
CHANGED
@@ -23,7 +23,5 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_development_dependency 'minitest', '~> 5.0.6'
|
24
24
|
s.add_development_dependency 'mocha', '~> 0.13'
|
25
25
|
s.add_development_dependency 'awesome_print', '~> 1.0'
|
26
|
-
s.add_development_dependency 'pry-rescue', '~> 1.0'
|
27
26
|
s.add_development_dependency 'simplecov', '~> 0.7'
|
28
|
-
s.add_development_dependency 'method_profiler'
|
29
27
|
end
|
@@ -22,7 +22,7 @@ class HandPlayer
|
|
22
22
|
|
23
23
|
# @return [Hand] This player's hole cards or nil if this player is not
|
24
24
|
# holding cards.
|
25
|
-
|
25
|
+
attr_accessor :hand
|
26
26
|
|
27
27
|
# @return [Array<PokerAction>] The actions this player has taken
|
28
28
|
attr_reader :actions
|
@@ -42,6 +42,14 @@ class HandPlayer
|
|
42
42
|
@winnings = ChipStack.new 0
|
43
43
|
end
|
44
44
|
|
45
|
+
def ==(other_player)
|
46
|
+
@hand == other_player.hand &&
|
47
|
+
@initial_stack == other_player.initial_stack &&
|
48
|
+
@ante == other_player.ante &&
|
49
|
+
@actions == other_player.actions &&
|
50
|
+
@winnings == other_player.winnings
|
51
|
+
end
|
52
|
+
|
45
53
|
def stack
|
46
54
|
@initial_stack + balance
|
47
55
|
end
|
@@ -95,9 +95,11 @@ class MatchState < DelegateClass(String)
|
|
95
95
|
|
96
96
|
# @param [String] raw_match_state A raw match state string to be parsed.
|
97
97
|
# @raise IncompleteMatchState
|
98
|
-
def initialize(raw_match_state)
|
99
|
-
if
|
100
|
-
|
98
|
+
def initialize(raw_match_state, previous_state = nil, game_def = nil)
|
99
|
+
if (
|
100
|
+
%r{#{LABEL}:(\d+):(\d+):([^:]*):([^#{COMMUNITY_CARD_SEPARATOR}\s]+)#{COMMUNITY_CARD_SEPARATOR}*([^\s:]*)}.match(
|
101
|
+
raw_match_state
|
102
|
+
)
|
101
103
|
)
|
102
104
|
@position_relative_to_dealer = $1.to_i
|
103
105
|
@hand_number = $2.to_i
|
@@ -105,7 +107,47 @@ class MatchState < DelegateClass(String)
|
|
105
107
|
@hands_string = $4
|
106
108
|
@community_cards_string = $5
|
107
109
|
end
|
108
|
-
@
|
110
|
+
@str = nil
|
111
|
+
@all_hands = nil
|
112
|
+
@community_cards = nil
|
113
|
+
@round = nil
|
114
|
+
@hand = nil
|
115
|
+
@opponent_hands = nil
|
116
|
+
@first_state_of_first_round = nil
|
117
|
+
@first_state_of_round = nil
|
118
|
+
@last_action = nil
|
119
|
+
@number_of_actions_this_round = nil
|
120
|
+
@number_of_actions_this_hand = nil
|
121
|
+
@round_in_which_last_action_taken = nil
|
122
|
+
@number_of_players = nil
|
123
|
+
@betting_sequence = nil
|
124
|
+
@hand_ended = nil
|
125
|
+
@opponents_cards_visible = nil
|
126
|
+
@pot = nil
|
127
|
+
@legal_actions = nil
|
128
|
+
if (
|
129
|
+
previous_state.nil? ||
|
130
|
+
game_def.nil? ||
|
131
|
+
last_action.nil? ||
|
132
|
+
previous_state.number_of_actions_this_hand != number_of_actions_this_hand - 1
|
133
|
+
)
|
134
|
+
@precise_betting_sequence = nil
|
135
|
+
@next_to_act = nil
|
136
|
+
@players = nil
|
137
|
+
@player_acting_sequence = nil
|
138
|
+
@min_wager_by = nil
|
139
|
+
else # Only process the one new action, bootstrapping from the given last state
|
140
|
+
@precise_betting_sequence = previous_state.betting_sequence(game_def).map { |per_round| per_round.dup }
|
141
|
+
@next_to_act = previous_state.next_to_act(game_def)
|
142
|
+
@players = previous_state.players(game_def).dup
|
143
|
+
@players.each_with_index { |player, i| player.hand = all_hands[i] }
|
144
|
+
@player_acting_sequence = previous_state.player_acting_sequence(game_def).map { |per_round| per_round.dup }
|
145
|
+
@min_wager_by = previous_state.min_wager_by(game_def)
|
146
|
+
|
147
|
+
process_action!(last_action, round_in_which_last_action_taken)
|
148
|
+
init_new_round!(game_def, round) if round != previous_state.round
|
149
|
+
distribute_chips!(game_def) if hand_ended?(game_def)
|
150
|
+
end
|
109
151
|
|
110
152
|
super to_s
|
111
153
|
end
|
@@ -306,7 +348,10 @@ class MatchState < DelegateClass(String)
|
|
306
348
|
def hand_ended?(game_def)
|
307
349
|
return @hand_ended unless @hand_ended.nil?
|
308
350
|
|
309
|
-
@hand_ended =
|
351
|
+
@hand_ended = (
|
352
|
+
reached_showdown? ||
|
353
|
+
players(game_def).count { |player| player.folded? } >= number_of_players - 1
|
354
|
+
)
|
310
355
|
end
|
311
356
|
|
312
357
|
def reached_showdown?
|
@@ -325,7 +370,7 @@ class MatchState < DelegateClass(String)
|
|
325
370
|
|
326
371
|
# @return [ChipStack] Minimum wager by.
|
327
372
|
def min_wager_by(game_def)
|
328
|
-
every_action(game_def)
|
373
|
+
every_action(game_def) if @min_wager_by.nil?
|
329
374
|
|
330
375
|
@min_wager_by
|
331
376
|
end
|
@@ -333,8 +378,9 @@ class MatchState < DelegateClass(String)
|
|
333
378
|
# @return [Array<PokerAction>] The legal actions for the next player to act.
|
334
379
|
def legal_actions(game_def)
|
335
380
|
return [] unless next_to_act(game_def)
|
381
|
+
return @legal_actions unless @legal_actions.nil?
|
336
382
|
|
337
|
-
players(game_def).legal_actions(
|
383
|
+
@legal_actions = players(game_def).legal_actions(
|
338
384
|
next_to_act(game_def),
|
339
385
|
round,
|
340
386
|
game_def,
|
@@ -345,50 +391,68 @@ class MatchState < DelegateClass(String)
|
|
345
391
|
private
|
346
392
|
|
347
393
|
def walk_over_betting_sequence!(game_def)
|
348
|
-
last_round = -1
|
349
|
-
|
350
394
|
betting_sequence.each_with_index do |actions_per_round, current_round|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
395
|
+
init_new_round!(game_def, current_round)
|
396
|
+
|
397
|
+
walk_over_actions!(actions_per_round, current_round)
|
398
|
+
end
|
399
|
+
|
400
|
+
self
|
401
|
+
end
|
402
|
+
|
403
|
+
def init_new_round!(game_def, current_round)
|
404
|
+
@min_wager_by = game_def.min_wagers[current_round]
|
405
|
+
@next_to_act = @players.position_of_first_active_player(
|
406
|
+
game_def.first_player_positions[current_round]
|
407
|
+
)
|
408
|
+
while @player_acting_sequence.length <= current_round
|
355
409
|
@player_acting_sequence << []
|
356
410
|
@precise_betting_sequence << []
|
357
|
-
last_round = current_round
|
358
|
-
|
359
|
-
walk_over_actions!(actions_per_round, game_def, last_round, current_round)
|
360
411
|
end
|
361
412
|
|
362
413
|
self
|
363
414
|
end
|
364
415
|
|
365
|
-
def walk_over_actions!(actions_per_round,
|
416
|
+
def walk_over_actions!(actions_per_round, current_round)
|
366
417
|
actions_per_round.each do |action|
|
367
|
-
|
368
|
-
acting_player_position = @player_acting_sequence.last.last
|
418
|
+
process_action!(action, current_round)
|
369
419
|
|
370
|
-
|
420
|
+
yield(
|
421
|
+
@precise_betting_sequence[current_round].last,
|
422
|
+
current_round,
|
423
|
+
@player_acting_sequence[current_round].last
|
424
|
+
) if block_given?
|
425
|
+
end
|
371
426
|
|
372
|
-
|
373
|
-
|
374
|
-
action,
|
375
|
-
game_def.min_wagers[current_round]
|
376
|
-
)
|
427
|
+
self
|
428
|
+
end
|
377
429
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
430
|
+
def process_action!(action, current_round)
|
431
|
+
cost = @players.action_cost(
|
432
|
+
@next_to_act,
|
433
|
+
action,
|
434
|
+
@min_wager_by
|
435
|
+
)
|
436
|
+
|
437
|
+
@precise_betting_sequence[current_round] << PokerAction.new(
|
438
|
+
action.to_s(
|
439
|
+
pot_gained_chips: @players.inject(0) { |sum, player| sum += player.contributions[current_round].to_i } > 0,
|
440
|
+
player_sees_wager: @players.amount_to_call(@next_to_act) > 0
|
441
|
+
),
|
442
|
+
cost: cost
|
443
|
+
)
|
385
444
|
|
386
|
-
|
445
|
+
adjust_min_wager!(
|
446
|
+
@precise_betting_sequence[current_round].last,
|
447
|
+
@next_to_act
|
448
|
+
)
|
387
449
|
|
388
|
-
|
450
|
+
@players[@next_to_act].append_action!(
|
451
|
+
@precise_betting_sequence[current_round].last, current_round
|
452
|
+
)
|
389
453
|
|
390
|
-
|
391
|
-
|
454
|
+
@player_acting_sequence[current_round] << @next_to_act
|
455
|
+
@next_to_act = @players.next_to_act(@next_to_act)
|
392
456
|
|
393
457
|
self
|
394
458
|
end
|
@@ -43,11 +43,12 @@ class PlayersAtTheTable
|
|
43
43
|
end
|
44
44
|
@game_def = game_def
|
45
45
|
@seat = Seat.new(seat, game_def.number_of_players)
|
46
|
+
@match_state = nil
|
46
47
|
end
|
47
48
|
|
48
49
|
# @param [MatchState] match_state The next match state.
|
49
50
|
def update!(match_state)
|
50
|
-
@match_state = match_state
|
51
|
+
@match_state = MatchState.new(match_state, @match_state, @game_def)
|
51
52
|
|
52
53
|
update_players!
|
53
54
|
end
|
data/spec/match_state_spec.rb
CHANGED
@@ -136,6 +136,145 @@ describe MatchState do
|
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
|
+
describe '#new allows bootstrapping from previous states' do
|
140
|
+
it 'eg 1' do
|
141
|
+
wager_size = 10
|
142
|
+
game_def = GameDefinition.new(
|
143
|
+
first_player_positions: [3, 2, 2, 2],
|
144
|
+
chip_stacks: [500, 450, 550],
|
145
|
+
blinds: [0, 10, 5],
|
146
|
+
raise_sizes: [wager_size]*4,
|
147
|
+
number_of_ranks: 3,
|
148
|
+
number_of_hole_cards: 1
|
149
|
+
)
|
150
|
+
|
151
|
+
(0..game_def.number_of_players-1).each do |position|
|
152
|
+
hands = [ Hand.new ]*game_def.number_of_players
|
153
|
+
hands[position] = arbitrary_hole_card_hand
|
154
|
+
|
155
|
+
hand_string = hands.inject('') do |hand_string, hand|
|
156
|
+
hand_string << "#{hand}#{MatchState::HAND_SEPARATOR}"
|
157
|
+
end[0..-2]
|
158
|
+
|
159
|
+
last_state = MatchState.new(
|
160
|
+
"#{MatchState::LABEL}:#{position}:0:crcc/ccc/rr:#{hand_string}"
|
161
|
+
)
|
162
|
+
|
163
|
+
patient = MatchState.new(
|
164
|
+
"#{MatchState::LABEL}:#{position}:0:crcc/ccc/rrf:#{hand_string}",
|
165
|
+
last_state,
|
166
|
+
game_def
|
167
|
+
)
|
168
|
+
|
169
|
+
x_state = MatchState.new(
|
170
|
+
"#{MatchState::LABEL}:#{position}:0:crcc/ccc/rrf:#{hand_string}"
|
171
|
+
)
|
172
|
+
|
173
|
+
patient.betting_sequence(game_def).must_equal x_state.betting_sequence(game_def)
|
174
|
+
patient.players(game_def).must_equal x_state.players(game_def)
|
175
|
+
patient.next_to_act(game_def).must_equal x_state.next_to_act(game_def)
|
176
|
+
patient.legal_actions(game_def).must_equal x_state.legal_actions(game_def)
|
177
|
+
patient.player_acting_sequence(game_def).must_equal x_state.player_acting_sequence(game_def)
|
178
|
+
patient.hand_ended?(game_def).must_equal x_state.hand_ended?(game_def)
|
179
|
+
patient.pot(game_def).must_equal x_state.pot(game_def)
|
180
|
+
patient.min_wager_by(game_def).must_equal x_state.min_wager_by(game_def)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
it 'eg 2' do
|
184
|
+
wager_size = 10
|
185
|
+
game_def = GameDefinition.new(
|
186
|
+
first_player_positions: [1, 0, 0, 0],
|
187
|
+
number_of_hole_cards: 2,
|
188
|
+
number_of_suits: 4,
|
189
|
+
number_of_ranks: 13,
|
190
|
+
raise_sizes: [wager_size]*4
|
191
|
+
)
|
192
|
+
|
193
|
+
last_state = MatchState.new(
|
194
|
+
"MATCHSTATE:0:0:c:5d5c|/8dAs8s"
|
195
|
+
)
|
196
|
+
|
197
|
+
patient = MatchState.new(
|
198
|
+
"MATCHSTATE:0:0:cc/:5d5c|/8dAs8s",
|
199
|
+
last_state,
|
200
|
+
game_def
|
201
|
+
)
|
202
|
+
|
203
|
+
x_state = MatchState.new("MATCHSTATE:0:0:cc/:5d5c|/8dAs8s")
|
204
|
+
|
205
|
+
patient.betting_sequence(game_def).must_equal x_state.betting_sequence(game_def)
|
206
|
+
patient.players(game_def).must_equal x_state.players(game_def)
|
207
|
+
patient.next_to_act(game_def).must_equal x_state.next_to_act(game_def)
|
208
|
+
patient.legal_actions(game_def).must_equal x_state.legal_actions(game_def)
|
209
|
+
patient.player_acting_sequence(game_def).must_equal x_state.player_acting_sequence(game_def)
|
210
|
+
patient.hand_ended?(game_def).must_equal x_state.hand_ended?(game_def)
|
211
|
+
patient.pot(game_def).must_equal x_state.pot(game_def)
|
212
|
+
patient.min_wager_by(game_def).must_equal x_state.min_wager_by(game_def)
|
213
|
+
end
|
214
|
+
it 'eg 3' do
|
215
|
+
wager_size = 10
|
216
|
+
game_def = GameDefinition.new(
|
217
|
+
first_player_positions: [1, 0, 0, 0],
|
218
|
+
number_of_hole_cards: 2,
|
219
|
+
number_of_suits: 4,
|
220
|
+
number_of_ranks: 13,
|
221
|
+
raise_sizes: [wager_size]*4
|
222
|
+
)
|
223
|
+
|
224
|
+
last_state = MatchState.new(
|
225
|
+
"MATCHSTATE:0:0:cc/:5d5c|/8dAs8s"
|
226
|
+
)
|
227
|
+
|
228
|
+
patient = MatchState.new(
|
229
|
+
"MATCHSTATE:0:0:cc/c:5d5c|/8dAs8s",
|
230
|
+
last_state,
|
231
|
+
game_def
|
232
|
+
)
|
233
|
+
|
234
|
+
x_state = MatchState.new("MATCHSTATE:0:0:cc/c:5d5c|/8dAs8s")
|
235
|
+
|
236
|
+
patient.betting_sequence(game_def).must_equal x_state.betting_sequence(game_def)
|
237
|
+
patient.players(game_def).must_equal x_state.players(game_def)
|
238
|
+
patient.next_to_act(game_def).must_equal x_state.next_to_act(game_def)
|
239
|
+
patient.legal_actions(game_def).must_equal x_state.legal_actions(game_def)
|
240
|
+
patient.player_acting_sequence(game_def).must_equal x_state.player_acting_sequence(game_def)
|
241
|
+
patient.hand_ended?(game_def).must_equal x_state.hand_ended?(game_def)
|
242
|
+
patient.pot(game_def).must_equal x_state.pot(game_def)
|
243
|
+
patient.min_wager_by(game_def).must_equal x_state.min_wager_by(game_def)
|
244
|
+
end
|
245
|
+
it 'distributes chips properly' do
|
246
|
+
wager_size = 10
|
247
|
+
game_def = GameDefinition.new(
|
248
|
+
first_player_positions: [1, 0, 0, 0],
|
249
|
+
number_of_hole_cards: 2,
|
250
|
+
number_of_suits: 4,
|
251
|
+
number_of_ranks: 13,
|
252
|
+
raise_sizes: [wager_size]*4
|
253
|
+
)
|
254
|
+
|
255
|
+
last_state = MatchState.new(
|
256
|
+
"MATCHSTATE:0:0:cc/r:5d5c|/8dAs8s"
|
257
|
+
)
|
258
|
+
|
259
|
+
patient = MatchState.new(
|
260
|
+
"MATCHSTATE:0:0:cc/rf:5d5c|2h3s/8dAs8s",
|
261
|
+
last_state,
|
262
|
+
game_def
|
263
|
+
)
|
264
|
+
|
265
|
+
x_state = MatchState.new("MATCHSTATE:0:0:cc/rf:5d5c|2h3s/8dAs8s")
|
266
|
+
|
267
|
+
patient.betting_sequence(game_def).must_equal x_state.betting_sequence(game_def)
|
268
|
+
patient.players(game_def).must_equal x_state.players(game_def)
|
269
|
+
patient.next_to_act(game_def).must_equal x_state.next_to_act(game_def)
|
270
|
+
patient.legal_actions(game_def).must_equal x_state.legal_actions(game_def)
|
271
|
+
patient.player_acting_sequence(game_def).must_equal x_state.player_acting_sequence(game_def)
|
272
|
+
patient.hand_ended?(game_def).must_equal x_state.hand_ended?(game_def)
|
273
|
+
patient.pot(game_def).must_equal x_state.pot(game_def)
|
274
|
+
patient.min_wager_by(game_def).must_equal x_state.min_wager_by(game_def)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
139
278
|
describe '#round' do
|
140
279
|
it "properly reports the current round number" do
|
141
280
|
partial_match_state = MatchState::LABEL + ":0:0:"
|
@@ -300,41 +439,103 @@ describe MatchState do
|
|
300
439
|
)
|
301
440
|
end
|
302
441
|
end
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
442
|
+
describe 'works with a game definition to provide a more precise result' do
|
443
|
+
it 'eg 1' do
|
444
|
+
MatchState.parse(
|
445
|
+
"#{MatchState::LABEL}:0:0:ccr20cc/r50fr100c/cc/cc:AhKs||"
|
446
|
+
).betting_sequence(
|
447
|
+
GameDefinition.new(
|
448
|
+
first_player_positions: [3, 2, 2, 2],
|
449
|
+
chip_stacks: [200, 200, 200],
|
450
|
+
blinds: [10, 0, 5],
|
451
|
+
raise_sizes: [10]*4,
|
452
|
+
number_of_ranks: 3
|
453
|
+
)
|
454
|
+
).must_equal [
|
455
|
+
[
|
456
|
+
PokerAction.new(PokerAction::CALL),
|
457
|
+
PokerAction.new(PokerAction::CHECK),
|
458
|
+
PokerAction.new("#{PokerAction::RAISE}20"),
|
459
|
+
PokerAction.new(PokerAction::CALL),
|
460
|
+
PokerAction.new(PokerAction::CALL)
|
461
|
+
],
|
462
|
+
[
|
463
|
+
PokerAction.new("#{PokerAction::BET}50"),
|
464
|
+
PokerAction.new(PokerAction::FOLD),
|
465
|
+
PokerAction.new("#{PokerAction::RAISE}100"),
|
466
|
+
PokerAction.new(PokerAction::CALL)
|
467
|
+
|
468
|
+
],
|
469
|
+
[
|
470
|
+
PokerAction.new(PokerAction::CHECK),
|
471
|
+
PokerAction.new(PokerAction::CHECK)
|
472
|
+
],
|
473
|
+
[
|
474
|
+
PokerAction.new(PokerAction::CHECK),
|
475
|
+
PokerAction.new(PokerAction::CHECK)
|
476
|
+
]
|
477
|
+
]
|
478
|
+
end
|
479
|
+
it 'eg 2' do
|
480
|
+
wager_size = 10
|
481
|
+
game_def = GameDefinition.new(
|
308
482
|
first_player_positions: [3, 2, 2, 2],
|
309
|
-
chip_stacks: [
|
310
|
-
blinds: [
|
311
|
-
raise_sizes: [
|
312
|
-
number_of_ranks: 3
|
483
|
+
chip_stacks: [500, 450, 550],
|
484
|
+
blinds: [0, 10, 5],
|
485
|
+
raise_sizes: [wager_size]*4,
|
486
|
+
number_of_ranks: 3,
|
487
|
+
number_of_hole_cards: 1
|
313
488
|
)
|
314
|
-
).must_equal [
|
315
|
-
[
|
316
|
-
PokerAction.new(PokerAction::CALL),
|
317
|
-
PokerAction.new(PokerAction::CHECK),
|
318
|
-
PokerAction.new("#{PokerAction::RAISE}20"),
|
319
|
-
PokerAction.new(PokerAction::CALL),
|
320
|
-
PokerAction.new(PokerAction::CALL)
|
321
|
-
],
|
322
|
-
[
|
323
|
-
PokerAction.new("#{PokerAction::BET}50"),
|
324
|
-
PokerAction.new(PokerAction::FOLD),
|
325
|
-
PokerAction.new("#{PokerAction::RAISE}100"),
|
326
|
-
PokerAction.new(PokerAction::CALL)
|
327
489
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
490
|
+
(0..game_def.number_of_players-1).each do |position|
|
491
|
+
hands = [ Hand.new ]*game_def.number_of_players
|
492
|
+
hands[position] = arbitrary_hole_card_hand
|
493
|
+
|
494
|
+
hand_string = hands.inject('') do |hand_string, hand|
|
495
|
+
hand_string << "#{hand}#{MatchState::HAND_SEPARATOR}"
|
496
|
+
end[0..-2]
|
497
|
+
|
498
|
+
patient = MatchState.parse(
|
499
|
+
"#{MatchState::LABEL}:#{position}:0:crcc/ccc/rr:#{hand_string}"
|
500
|
+
)
|
501
|
+
|
502
|
+
patient.betting_sequence.must_equal [
|
503
|
+
[
|
504
|
+
PokerAction::CALL,
|
505
|
+
PokerAction::RAISE,
|
506
|
+
PokerAction::CALL,
|
507
|
+
PokerAction::CALL
|
508
|
+
],
|
509
|
+
[
|
510
|
+
PokerAction::CALL,
|
511
|
+
PokerAction::CALL,
|
512
|
+
PokerAction::CALL
|
513
|
+
],
|
514
|
+
[
|
515
|
+
PokerAction::RAISE,
|
516
|
+
PokerAction::RAISE
|
517
|
+
]
|
518
|
+
]
|
519
|
+
|
520
|
+
patient.betting_sequence(game_def).must_equal [
|
521
|
+
[
|
522
|
+
PokerAction::CALL,
|
523
|
+
PokerAction::RAISE,
|
524
|
+
PokerAction::CALL,
|
525
|
+
PokerAction::CALL
|
526
|
+
],
|
527
|
+
[
|
528
|
+
PokerAction::CHECK,
|
529
|
+
PokerAction::CHECK,
|
530
|
+
PokerAction::CHECK
|
531
|
+
],
|
532
|
+
[
|
533
|
+
PokerAction::BET,
|
534
|
+
PokerAction::RAISE
|
535
|
+
]
|
536
|
+
]
|
537
|
+
end
|
538
|
+
end
|
338
539
|
end
|
339
540
|
end
|
340
541
|
describe '#players_at_hand_start' do
|