acpc_poker_types 7.8.4 → 7.8.5
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/lib/acpc_poker_types/match_state.rb +46 -16
- data/lib/acpc_poker_types/version.rb +1 -1
- data/spec/match_state_spec.rb +79 -5
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7084a475af9591c14e3acbb9c4e6175f5c7bdeb9
|
|
4
|
+
data.tar.gz: 8278322d9a1df82e20e61c2594f8d89f63afbf6d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1afae92e4aaef2ebca49f077fa51eadda232272d363458683242d21d5929263b2e3eb8c8dfddd0d735d175e75febee5fc18b20a0131193e73033a1c11ef652f4
|
|
7
|
+
data.tar.gz: ace19dcb18b1fe1dccb30c217ade1b9104f93e79171e06299733993c9563c4ca3224e1a95d9648cf8af707ac5b0b277f9d8d824219e7d3e06671648202a11f56
|
|
@@ -404,7 +404,9 @@ class MatchState < DelegateClass(String)
|
|
|
404
404
|
end
|
|
405
405
|
|
|
406
406
|
def pot(game_def)
|
|
407
|
-
@pot ||= players(game_def).map
|
|
407
|
+
@pot ||= players(game_def).map do |player|
|
|
408
|
+
player.contributions
|
|
409
|
+
end.flatten.inject(:+)
|
|
408
410
|
end
|
|
409
411
|
|
|
410
412
|
# @return [ChipStack] Minimum wager by.
|
|
@@ -427,6 +429,20 @@ class MatchState < DelegateClass(String)
|
|
|
427
429
|
)
|
|
428
430
|
end
|
|
429
431
|
|
|
432
|
+
def hand_strengths(game_def)
|
|
433
|
+
@hand_strengths ||= players(game_def).map do |player|
|
|
434
|
+
if player.folded?
|
|
435
|
+
-1
|
|
436
|
+
else
|
|
437
|
+
PileOfCards.new(community_cards.flatten + player.hand).to_poker_hand_strength
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
def winning_players(game_def)
|
|
443
|
+
@winning_players ||= compute_winning_players!(game_def)
|
|
444
|
+
end
|
|
445
|
+
|
|
430
446
|
private
|
|
431
447
|
|
|
432
448
|
def finish_update!(game_def)
|
|
@@ -437,14 +453,9 @@ class MatchState < DelegateClass(String)
|
|
|
437
453
|
end
|
|
438
454
|
|
|
439
455
|
def compute_winning_players!(game_def)
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
else
|
|
444
|
-
PileOfCards.new(community_cards.flatten + player.hand).to_poker_hand_strength
|
|
445
|
-
end
|
|
446
|
-
end
|
|
447
|
-
@winning_players = hand_strengths.indices hand_strengths.max
|
|
456
|
+
@winning_players = hand_strengths(game_def).indices(
|
|
457
|
+
hand_strengths(game_def).max
|
|
458
|
+
)
|
|
448
459
|
end
|
|
449
460
|
|
|
450
461
|
def walk_over_betting_sequence!(game_def)
|
|
@@ -490,6 +501,7 @@ class MatchState < DelegateClass(String)
|
|
|
490
501
|
action,
|
|
491
502
|
@min_wager_by
|
|
492
503
|
)
|
|
504
|
+
raise %Q{Action "#{action}" cannot cost more than the stack size of the acting player: Acting player position: #{@next_to_act}, stack size: #{@players[@next_to_act].stack.to_f}, action cost: #{cost.to_f}, match state: #{to_s}.} if cost > @players[@next_to_act].stack
|
|
493
505
|
|
|
494
506
|
@precise_betting_sequence[current_round] << PokerAction.new(
|
|
495
507
|
action.to_s(
|
|
@@ -520,17 +532,35 @@ class MatchState < DelegateClass(String)
|
|
|
520
532
|
|
|
521
533
|
# Distribute chips to all winning players
|
|
522
534
|
def distribute_chips!(game_def)
|
|
523
|
-
return self
|
|
524
|
-
|
|
525
|
-
compute_winning_players!(game_def) unless @winning_players
|
|
535
|
+
return self unless pot(game_def) > 0
|
|
526
536
|
|
|
527
|
-
|
|
528
|
-
amount_each_player_wins = pot(game_def)/@winning_players.length.to_r
|
|
537
|
+
best_hs = hand_strengths(game_def).max
|
|
529
538
|
|
|
530
|
-
|
|
531
|
-
|
|
539
|
+
contributions = players(game_def).map do |player|
|
|
540
|
+
player.total_contribution
|
|
532
541
|
end
|
|
533
542
|
|
|
543
|
+
# @todo This only works for Doyle's game where there are no non-trivial side-pots.
|
|
544
|
+
winnings = contributions.dup
|
|
545
|
+
players(game_def).each_with_index do |player, i|
|
|
546
|
+
next if hand_strengths(game_def)[i] < best_hs
|
|
547
|
+
|
|
548
|
+
contributions.each_with_index do |c, j|
|
|
549
|
+
next if i == j
|
|
550
|
+
|
|
551
|
+
num_chips = (
|
|
552
|
+
[c, player.total_contribution].min /
|
|
553
|
+
winning_players(game_def).length.to_r
|
|
554
|
+
)
|
|
555
|
+
winnings[i] += num_chips
|
|
556
|
+
winnings[j] -= num_chips
|
|
557
|
+
|
|
558
|
+
raise %Q{The winnings for player in position #{j} is negative (#{winnings[j]}) in match state "#{to_s}"} if winnings[j] < 0
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
players(game_def).each_with_index do |player, i|
|
|
562
|
+
player.winnings = winnings[i]
|
|
563
|
+
end
|
|
534
564
|
self
|
|
535
565
|
end
|
|
536
566
|
|
data/spec/match_state_spec.rb
CHANGED
|
@@ -783,6 +783,77 @@ describe MatchState do
|
|
|
783
783
|
end
|
|
784
784
|
end
|
|
785
785
|
end
|
|
786
|
+
describe 'correctly tracks player contributions to the pot and winnings when players begin with different stack sizes and both go all-in' do
|
|
787
|
+
let(:game_def) do
|
|
788
|
+
GameDefinition.new(
|
|
789
|
+
:betting_type=>"nolimit",
|
|
790
|
+
:chip_stacks=>[20000, 20000],
|
|
791
|
+
:number_of_players=>2,
|
|
792
|
+
:blinds=>[100, 50],
|
|
793
|
+
:raise_sizes=>nil,
|
|
794
|
+
:number_of_rounds=>4,
|
|
795
|
+
:first_player_positions=>[1, 0, 0, 0],
|
|
796
|
+
:number_of_suits=>4,
|
|
797
|
+
:number_of_ranks=>13,
|
|
798
|
+
:number_of_hole_cards=>2,
|
|
799
|
+
:number_of_board_cards=>[0, 3, 1, 1]
|
|
800
|
+
)
|
|
801
|
+
end
|
|
802
|
+
let(:x_actions) do
|
|
803
|
+
[
|
|
804
|
+
[
|
|
805
|
+
[
|
|
806
|
+
PokerAction.new(PokerAction::RAISE, cost: 20050),
|
|
807
|
+
],
|
|
808
|
+
[
|
|
809
|
+
PokerAction.new(PokerAction::CALL, cost: 19800)
|
|
810
|
+
],
|
|
811
|
+
]
|
|
812
|
+
]
|
|
813
|
+
end
|
|
814
|
+
let(:patient) { MatchState.new(match_state).players(game_def) }
|
|
815
|
+
|
|
816
|
+
it 'when the winner has fewer chips' do
|
|
817
|
+
def match_state
|
|
818
|
+
"#{MatchState::LABEL}:0:0:19900|20100:r20100c///:AhKs|2h7d"
|
|
819
|
+
end
|
|
820
|
+
patient.map do |player, pos|
|
|
821
|
+
player.initial_stack
|
|
822
|
+
end.must_equal [19900, 20100]
|
|
823
|
+
|
|
824
|
+
patient.map do |player, pos|
|
|
825
|
+
player.total_contribution
|
|
826
|
+
end.must_equal [19900, 20100]
|
|
827
|
+
|
|
828
|
+
patient.map { |player, pos| player.winnings }.must_equal(
|
|
829
|
+
[2 * 19900, 200]
|
|
830
|
+
)
|
|
831
|
+
|
|
832
|
+
patient.map do |player, pos|
|
|
833
|
+
player.stack
|
|
834
|
+
end.must_equal [19900 + 19900, 200]
|
|
835
|
+
end
|
|
836
|
+
|
|
837
|
+
it 'when the winner has more chips' do
|
|
838
|
+
def match_state
|
|
839
|
+
"#{MatchState::LABEL}:0:0:19900|20100:r20100c///:2h7d|AhKs"
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
patient.map do |player, pos|
|
|
843
|
+
player.initial_stack
|
|
844
|
+
end.must_equal [19900, 20100]
|
|
845
|
+
|
|
846
|
+
patient.map do |player, pos|
|
|
847
|
+
player.total_contribution
|
|
848
|
+
end.must_equal [19900, 20100]
|
|
849
|
+
|
|
850
|
+
patient.map { |player, pos| player.winnings }.must_equal(
|
|
851
|
+
[0, 19900 + 20100]
|
|
852
|
+
)
|
|
853
|
+
|
|
854
|
+
patient.map { |player, pos| player.stack }.must_equal [0, 40000]
|
|
855
|
+
end
|
|
856
|
+
end
|
|
786
857
|
describe 'distributes chips properly' do
|
|
787
858
|
it 'when there is a showdown and one winner' do
|
|
788
859
|
wager_size = 10
|
|
@@ -842,8 +913,9 @@ describe MatchState do
|
|
|
842
913
|
hand_string << "#{hand}#{MatchState::HAND_SEPARATOR}"
|
|
843
914
|
end[0..-2]
|
|
844
915
|
|
|
845
|
-
match_state =
|
|
916
|
+
match_state = (
|
|
846
917
|
"#{MatchState::LABEL}:#{position}:0:crcc/ccc/rrfc/crc:#{hand_string_}"
|
|
918
|
+
)
|
|
847
919
|
|
|
848
920
|
MatchState.new(match_state).players(x_game_def).each_with_index do |player, i|
|
|
849
921
|
player.winnings.must_equal x_winnings[i]
|
|
@@ -900,9 +972,11 @@ describe MatchState do
|
|
|
900
972
|
:number_of_hole_cards=>2,
|
|
901
973
|
:number_of_board_cards=>[0, 3, 1, 1]
|
|
902
974
|
)
|
|
903
|
-
MatchState.parse(
|
|
975
|
+
patient = MatchState.parse(
|
|
904
976
|
'MATCHSTATE:0:2:cr20000c///:8h8s|5s5c/KdTcKh/9h/Jh'
|
|
905
|
-
)
|
|
977
|
+
)
|
|
978
|
+
patient.winning_players(game_def).must_equal [0]
|
|
979
|
+
patient.players(game_def).map { |pl| pl.winnings }.must_equal [40000, 0]
|
|
906
980
|
end
|
|
907
981
|
end
|
|
908
982
|
end
|
|
@@ -966,7 +1040,7 @@ describe MatchState do
|
|
|
966
1040
|
wager_size = 10
|
|
967
1041
|
x_game_def = GameDefinition.new(
|
|
968
1042
|
first_player_positions: [3, 2, 2, 2],
|
|
969
|
-
chip_stacks: [
|
|
1043
|
+
chip_stacks: [200, 200, 150],
|
|
970
1044
|
blinds: [0, 10, 5],
|
|
971
1045
|
raise_sizes: [wager_size]*4,
|
|
972
1046
|
number_of_ranks: 3
|
|
@@ -1068,7 +1142,7 @@ describe MatchState do
|
|
|
1068
1142
|
wager_size = 10
|
|
1069
1143
|
x_game_def = GameDefinition.new(
|
|
1070
1144
|
first_player_positions: [3, 2, 2, 2],
|
|
1071
|
-
chip_stacks: [
|
|
1145
|
+
chip_stacks: [200, 200, 150],
|
|
1072
1146
|
blinds: [0, 10, 5],
|
|
1073
1147
|
raise_sizes: [wager_size]*4,
|
|
1074
1148
|
number_of_ranks: 3
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: acpc_poker_types
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.8.
|
|
4
|
+
version: 7.8.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dustin Morrill
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-01-
|
|
11
|
+
date: 2017-01-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: process_runner
|