acpc_poker_types 7.3.3 → 7.4.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.
- 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
|