acpc_poker_match_state 0.0.4 → 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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/acpc_poker_match_state.gemspec +8 -9
  3. data/lib/acpc_poker_match_state.rb +3 -3
  4. data/lib/acpc_poker_match_state/match_state_transition.rb +22 -23
  5. data/lib/acpc_poker_match_state/players_at_the_table.rb +315 -329
  6. data/lib/acpc_poker_match_state/version.rb +1 -1
  7. data/spec/coverage/assets/0.7.1/application.css +1110 -0
  8. data/spec/coverage/assets/0.7.1/application.js +626 -0
  9. data/spec/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
  10. data/spec/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
  11. data/spec/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
  12. data/spec/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
  13. data/spec/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
  14. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
  15. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
  16. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
  17. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
  18. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
  19. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
  20. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
  21. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
  22. data/spec/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
  23. data/spec/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
  24. data/spec/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
  25. data/spec/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
  26. data/spec/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
  27. data/spec/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
  28. data/spec/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
  29. data/spec/coverage/assets/0.7.1/favicon_green.png +0 -0
  30. data/spec/coverage/assets/0.7.1/favicon_red.png +0 -0
  31. data/spec/coverage/assets/0.7.1/favicon_yellow.png +0 -0
  32. data/spec/coverage/assets/0.7.1/loading.gif +0 -0
  33. data/spec/coverage/assets/0.7.1/magnify.png +0 -0
  34. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  35. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  36. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  37. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  38. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  39. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  40. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  41. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  42. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
  43. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  44. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
  45. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
  46. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  47. data/spec/coverage/index.html +72 -0
  48. data/spec/match_state_transition_spec.rb +5 -5
  49. data/spec/players_at_the_table_spec.rb +15 -37
  50. data/spec/support/spec_helper.rb +5 -3
  51. metadata +134 -66
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b99cb18af5d5209190310006d6fedcb99de6659
4
- data.tar.gz: 0b0d99312c5bd4fcfba3f22d0a8ec82d1a2f4cdc
3
+ metadata.gz: b4add49d2c0e5aced134d96916d14060b80cb2ac
4
+ data.tar.gz: 14ff0c1a37e0277ddd3eba22a6fcd5777ebcf95c
5
5
  SHA512:
6
- metadata.gz: 6518c6631753952423fb7a0f52bfd9c10dab4762853af855c981d1a3a6470c73cc1c88c0c142522ec3c4a28be12307598efdf7b43a52cbec9454a8fb07b0ae87
7
- data.tar.gz: d043a2a7de1b4c712a1cd027d3aacf93e376ee3949c4c7a530814993aa7fb724153a3c0050d4b4e9d6a341deba4f5b8fb280e25eb346800e238f5a0202040d5f
6
+ metadata.gz: 147975becc5c6ab3abfdb38a449070dfa400fc8c9cce58726df4796f654f49a9704b55aea06b878f04566369eea84adf7e1f0dea03a3d7edfb39c1e1933841fd
7
+ data.tar.gz: b980f324be2472f5a3be487c490c88dab8d1408e1f29bdd7f3a9020f136287e550340ee59dc6b97c5215eaa99ae35c9dc604eeb2266758a57cd8038bb63ebc77
@@ -10,8 +10,8 @@ Gem::Specification.new do |s|
10
10
  s.summary = %q{ACPC Poker Match State}
11
11
  s.description = %q{Match state data manager.}
12
12
 
13
- s.add_dependency 'acpc_poker_types'
14
- s.add_dependency 'dmorrill10-utils'
13
+ s.add_dependency 'acpc_poker_types', '~> 3.0'
14
+ s.add_dependency 'dmorrill10-utils', '~> 1.0'
15
15
 
16
16
  s.rubyforge_project = "acpc_poker_match_state"
17
17
 
@@ -19,11 +19,10 @@ Gem::Specification.new do |s|
19
19
  s.test_files = Dir.glob "spec/**/*"
20
20
  s.require_paths = ["lib"]
21
21
 
22
- s.add_development_dependency 'turn'
23
- s.add_development_dependency 'minitest'
24
- s.add_development_dependency 'acpc_dealer_data'
25
- s.add_development_dependency 'acpc_dealer'
26
- s.add_development_dependency 'awesome_print'
27
- s.add_development_dependency 'pry'
28
- s.add_development_dependency 'pry-rescue'
22
+ s.add_development_dependency 'turn', '~> 0.9'
23
+ s.add_development_dependency 'minitest', '~> 4.7'
24
+ s.add_development_dependency 'acpc_dealer', '~> 0.0'
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'
29
28
  end
@@ -1,7 +1,7 @@
1
- require File.expand_path("../acpc_poker_match_state/version", __FILE__)
1
+ require 'acpc_poker_match_state/version'
2
2
 
3
- require File.expand_path("../acpc_poker_match_state/match_state_transition", __FILE__)
4
- require File.expand_path("../acpc_poker_match_state/players_at_the_table", __FILE__)
3
+ require 'acpc_poker_match_state/match_state_transition'
4
+ require 'acpc_poker_match_state/players_at_the_table'
5
5
 
6
6
  module AcpcPokerMatchState
7
7
  end
@@ -1,33 +1,32 @@
1
-
2
1
  require 'dmorrill10-utils/class'
3
2
  require 'acpc_poker_types/match_state'
4
3
 
5
- class MatchStateTransition
6
-
7
- exceptions :no_state_given
4
+ module AcpcPokerMatchState
5
+ class MatchStateTransition
6
+ exceptions :no_state_given
8
7
 
9
- attr_reader :next_state
8
+ attr_reader :next_state
9
+ attr_reader :last_state
10
10
 
11
- attr_reader :last_state
11
+ def set_next_state!(new_state)
12
+ @last_state = @next_state
13
+ @next_state = new_state
14
+ self
15
+ end
12
16
 
13
- def set_next_state!(new_state)
14
- @last_state = @next_state
15
- @next_state = new_state
16
- self
17
- end
17
+ # @return [Boolean] +true+ if the next state's round is different from the
18
+ # last, +false+ otherwise.
19
+ def new_round?
20
+ raise NoStateGiven unless @next_state
21
+ return true unless @last_state
18
22
 
19
- # @return [Boolean] +true+ if the next state's round is different from the
20
- # last, +false+ otherwise.
21
- def new_round?
22
- raise NoStateGiven unless @next_state
23
- return true unless @last_state
24
-
25
- @next_state.round != @last_state.round
26
- end
23
+ @next_state.round != @last_state.round
24
+ end
27
25
 
28
- def initial_state?
29
- raise NoStateGiven unless @next_state
26
+ def initial_state?
27
+ raise NoStateGiven unless @next_state
30
28
 
31
- @next_state.first_state_of_first_round?
29
+ @next_state.first_state_of_first_round?
30
+ end
32
31
  end
33
- end
32
+ end
@@ -1,433 +1,419 @@
1
- # @todo Remove this
2
- require 'awesome_print'
1
+ require 'dmorrill10-utils/class'
3
2
 
4
- require 'dmorrill10-utils'
5
3
  require 'acpc_poker_types'
4
+ require 'acpc_poker_match_state/match_state_transition'
6
5
 
7
- require File.expand_path('../match_state_transition', __FILE__)
6
+ module AcpcPokerMatchState
7
+ class PlayersAtTheTable
8
8
 
9
- class PlayersAtTheTable
9
+ exceptions :player_acted_before_sitting_at_table,
10
+ :no_players_to_seat, :users_seat_out_of_bounds,
11
+ :multiple_players_have_the_same_seat
10
12
 
11
- exceptions :player_acted_before_sitting_at_table,
12
- :no_players_to_seat, :users_seat_out_of_bounds,
13
- :multiple_players_have_the_same_seat
13
+ attr_reader :players
14
14
 
15
- attr_reader :players
15
+ # @return [Array<Array<Integer>>] The sequence of seats that acted,
16
+ # separated by round.
17
+ attr_reader :player_acting_sequence
16
18
 
17
- # @return [Array<Array<Integer>>] The sequence of seats that acted,
18
- # separated by round.
19
- attr_reader :player_acting_sequence
19
+ attr_reader :transition
20
20
 
21
- attr_reader :transition
21
+ attr_reader :number_of_hands
22
22
 
23
- attr_reader :number_of_hands
23
+ attr_reader :game_def
24
24
 
25
- attr_reader :game_def
25
+ attr_reader :users_seat
26
26
 
27
- attr_reader :users_seat
27
+ attr_reader :min_wager
28
28
 
29
- attr_reader :min_wager
29
+ attr_reader :player_who_acted_last
30
30
 
31
- attr_reader :player_who_acted_last
31
+ alias_new :seat_players
32
32
 
33
- alias_new :seat_players
33
+ # @param [GameDefinition] game_def The game definition for the
34
+ # match these players are playing.
35
+ # @param [Array<String>] player_names The names of the players to seat at the table,
36
+ # ordered by seat.
37
+ # @param [Integer] users_seat The user's seat at the table.
38
+ # players are joining.
39
+ # @param [Integer] number_of_hands The number of hands in this match.
40
+ def initialize(game_def, player_names, users_seat, number_of_hands)
41
+ @players = AcpcPokerTypes::Player.create_players player_names, game_def
34
42
 
35
- # @param [GameDefinition] game_def The game definition for the
36
- # match these players are playing.
37
- # @param [Array<String>] player_names The names of the players to seat at the table,
38
- # ordered by seat.
39
- # @param [Integer] users_seat The user's seat at the table.
40
- # players are joining.
41
- # @param [Integer] number_of_hands The number of hands in this match.
42
- def initialize(game_def, player_names, users_seat, number_of_hands)
43
- @players = Player.create_players player_names, game_def
44
-
45
- @users_seat = if users_seat.seat_in_bounds?(number_of_players) && @players.any?{|player| player.seat == users_seat}
46
- users_seat
47
- else
48
- raise UsersSeatOutOfBounds, users_seat
49
- end
43
+ @users_seat = if users_seat.seat_in_bounds?(number_of_players) && @players.any?{|player| player.seat == users_seat}
44
+ users_seat
45
+ else
46
+ raise UsersSeatOutOfBounds, users_seat
47
+ end
50
48
 
51
- @game_def = game_def
52
- @min_wager = @game_def.min_wagers.first
49
+ @game_def = game_def
50
+ @min_wager = @game_def.min_wagers.first
53
51
 
54
- @transition = MatchStateTransition.new
52
+ @transition = AcpcPokerMatchState::MatchStateTransition.new
55
53
 
56
- @player_acting_sequence = [[]]
54
+ @player_acting_sequence = [[]]
57
55
 
58
- @number_of_hands = number_of_hands
59
- end
56
+ @number_of_hands = number_of_hands
57
+ end
60
58
 
61
- def blinds
62
- @game_def.blinds
63
- end
59
+ def blinds
60
+ @game_def.blinds
61
+ end
64
62
 
65
- # @return [Integer] The number of players seated at the table.
66
- def number_of_players() @players.length end
63
+ # @return [Integer] The number of players seated at the table.
64
+ def number_of_players() @players.length end
67
65
 
68
- # @param [MatchState] match_state The next match state.
69
- def update!(match_state)
70
- @transition.set_next_state! match_state
66
+ # @param [MatchState] match_state The next match state.
67
+ def update!(match_state)
68
+ @transition.set_next_state! match_state
71
69
 
72
- if @transition.initial_state?
73
- start_new_hand!
74
- else
75
- @player_acting_sequence.last << next_player_to_act(@transition.last_state).seat
70
+ if @transition.initial_state?
71
+ start_new_hand!
72
+ else
73
+ @player_acting_sequence.last << next_player_to_act(@transition.last_state).seat
76
74
 
77
- update_state_of_players!
75
+ update_state_of_players!
78
76
 
79
- @player_acting_sequence << [] if @transition.new_round?
77
+ @player_acting_sequence << [] if @transition.new_round?
78
+ end
79
+ self
80
80
  end
81
- self
82
- end
83
81
 
84
- def next_player_to_act(state=@transition.next_state)
85
- return nil unless state && !hand_ended? && !active_players.empty?
82
+ def next_player_to_act(state=@transition.next_state)
83
+ return nil unless state && !hand_ended? && !active_players.empty?
86
84
 
87
- reference_position = if state.number_of_actions_this_round > 0
88
- position_relative_to_dealer player_who_acted_last
89
- else
90
- @game_def.first_player_positions[state.round] - 1
91
- end
85
+ reference_position = if state.number_of_actions_this_round > 0
86
+ position_relative_to_dealer player_who_acted_last
87
+ else
88
+ @game_def.first_player_positions[state.round] - 1
89
+ end
92
90
 
93
- number_of_players.times.inject(nil) do |player_who_might_act, i|
94
- position_relative_to_dealer_to_act = (reference_position + i + 1) % number_of_players
95
- player_who_might_act = active_players.find do |player|
96
- position_relative_to_dealer(player) == position_relative_to_dealer_to_act
91
+ number_of_players.times.inject(nil) do |player_who_might_act, i|
92
+ position_relative_to_dealer_to_act = (reference_position + i + 1) % number_of_players
93
+ player_who_might_act = active_players.find do |player|
94
+ position_relative_to_dealer(player) == position_relative_to_dealer_to_act
95
+ end
96
+ if player_who_might_act then break player_who_might_act else nil end
97
97
  end
98
- if player_who_might_act then break player_who_might_act else nil end
99
98
  end
100
- end
101
99
 
102
- def player_who_acted_last
103
- unless round_in_which_last_action_taken
104
- nil
105
- else
106
- @players.find do |player|
107
- player.seat == @player_acting_sequence[round_in_which_last_action_taken].last
100
+ def player_who_acted_last
101
+ unless @transition.next_state && @transition.next_state.round_in_which_last_action_taken
102
+ nil
103
+ else
104
+ @players.find do |player|
105
+ player.seat == @player_acting_sequence[@transition.next_state.round_in_which_last_action_taken].last
106
+ end
108
107
  end
109
108
  end
110
- end
111
109
 
112
- def opponents
113
- @players.select { |player| player.seat != @users_seat }
114
- end
110
+ def opponents
111
+ @players.select { |player| player.seat != @users_seat }
112
+ end
115
113
 
116
- def user_player
117
- @players.find { |player| @users_seat == player.seat }
118
- end
114
+ def user_player
115
+ @players.find { |player| @users_seat == player.seat }
116
+ end
119
117
 
120
- # @return [Array<Player>] The players who are active.
121
- def active_players
122
- @players.select { |player| player.active? }
123
- end
118
+ # @return [Array<AcpcPokerTypes::Player>] The players who are active.
119
+ def active_players
120
+ @players.select { |player| player.active? }
121
+ end
124
122
 
125
- #@return [Array<Player>] The players who have not folded.
126
- def non_folded_players
127
- @players.select { |player| !player.folded? }
128
- end
123
+ #@return [Array<AcpcPokerTypes::Player>] The players who have not folded.
124
+ def non_folded_players
125
+ @players.select { |player| !player.folded? }
126
+ end
129
127
 
130
- # @return [Boolean] +true+ if the hand has ended, +false+ otherwise.
131
- def hand_ended?
132
- less_than_two_non_folded_players? || reached_showdown?
133
- end
128
+ # @return [Boolean] +true+ if the hand has ended, +false+ otherwise.
129
+ def hand_ended?
130
+ less_than_two_non_folded_players? || reached_showdown?
131
+ end
134
132
 
135
- # @return [Boolean] +true+ if the match has ended, +false+ otherwise.
136
- def match_ended?
137
- hand_ended? && last_hand?
138
- end
133
+ # @return [Boolean] +true+ if the match has ended, +false+ otherwise.
134
+ def match_ended?
135
+ hand_ended? && last_hand?
136
+ end
139
137
 
140
- def less_than_two_non_folded_players?
141
- non_folded_players.length < 2
142
- end
138
+ def less_than_two_non_folded_players?
139
+ non_folded_players.length < 2
140
+ end
143
141
 
144
- def reached_showdown?
145
- opponents_cards_visible?
146
- end
142
+ def reached_showdown?
143
+ opponents_cards_visible?
144
+ end
147
145
 
148
- # @return [Boolean] +true+ if any opponents cards are visible, +false+ otherwise.
149
- def opponents_cards_visible?
150
- opponents.any? { |player| player.hole_cards && !player.hole_cards.empty? }
151
- end
146
+ # @return [Boolean] +true+ if any opponents cards are visible, +false+ otherwise.
147
+ def opponents_cards_visible?
148
+ opponents.any? { |player| player.hole_cards && !player.hole_cards.empty? }
149
+ end
152
150
 
153
- # @return [Player] The player with the dealer button.
154
- def player_with_dealer_button
155
- return nil unless @transition.next_state
156
- @players.find { |player| position_relative_to_dealer(player) == number_of_players - 1}
157
- end
151
+ # @return [AcpcPokerTypes::Player] The player with the dealer button.
152
+ def player_with_dealer_button
153
+ return nil unless @transition.next_state
154
+ @players.find { |player| position_relative_to_dealer(player) == number_of_players - 1}
155
+ end
158
156
 
159
- # @return [Hash<Player, #to_i] Relation from player to the blind that player paid.
160
- def player_blind_relation
161
- return nil unless @transition.next_state
157
+ # @return [Hash<AcpcPokerTypes::Player, #to_i] Relation from player to the blind that player paid.
158
+ def player_blind_relation
159
+ return nil unless @transition.next_state
162
160
 
163
- @players.inject({}) do |relation, player|
164
- relation[player] = blinds[position_relative_to_dealer(player)]
165
- relation
161
+ @players.inject({}) do |relation, player|
162
+ relation[player] = blinds[position_relative_to_dealer(player)]
163
+ relation
164
+ end
166
165
  end
167
- end
168
166
 
169
- # @return [String] player acting sequence as a string.
170
- def player_acting_sequence_string
171
- (@player_acting_sequence.map { |per_round| per_round.join('') }).join('/')
172
- end
167
+ # @return [String] player acting sequence as a string.
168
+ def player_acting_sequence_string
169
+ (@player_acting_sequence.map { |per_round| per_round.join('') }).join('/')
170
+ end
173
171
 
174
- def betting_sequence_string
175
- (betting_sequence.map do |per_round|
176
- (per_round.map{|action| action.to_acpc}).join('')
177
- end).join('/')
178
- end
172
+ def betting_sequence_string
173
+ (betting_sequence.map do |per_round|
174
+ (per_round.map{|action| action.to_s}).join('')
175
+ end).join('/')
176
+ end
179
177
 
180
- def betting_sequence
181
- sequence = [[]]
182
- return sequence unless @transition.next_state
178
+ def betting_sequence
179
+ sequence = [[]]
180
+ return sequence unless @transition.next_state
183
181
 
184
- @player_acting_sequence.each_with_index do |per_round, i|
185
- actions_taken_this_round = {}
182
+ @player_acting_sequence.each_with_index do |per_round, i|
183
+ actions_taken_this_round = {}
186
184
 
187
- unless per_round.empty?
188
- @players.each do |player|
189
- # Skip if player has folded and a round after the fold is being checked
190
- next if i >= player.actions_taken_this_hand.length
185
+ unless per_round.empty?
186
+ @players.each do |player|
187
+ # Skip if player has folded and a round after the fold is being checked
188
+ next if i >= player.actions_taken_this_hand.length
191
189
 
192
- actions_taken_this_round[player.seat] = player.actions_taken_this_hand[i].dup
190
+ actions_taken_this_round[player.seat] = player.actions_taken_this_hand[i].dup
191
+ end
193
192
  end
194
- end
195
193
 
196
- per_round.each do |seat|
197
- sequence.last << actions_taken_this_round[seat].shift
194
+ per_round.each do |seat|
195
+ sequence.last << actions_taken_this_round[seat].shift
196
+ end
197
+ sequence << [] if (@transition.next_state.round+1) > sequence.length
198
198
  end
199
- sequence << [] if (@transition.next_state.round+1) > sequence.length
199
+ sequence
200
200
  end
201
- sequence
202
- end
203
201
 
204
- # @return [Boolean] +true+ if it is the user's turn to act, +false+ otherwise.
205
- def users_turn_to_act?
206
- if next_player_to_act
207
- next_player_to_act.seat == @users_seat
208
- else
209
- false
202
+ # @return [Boolean] +true+ if it is the user's turn to act, +false+ otherwise.
203
+ def users_turn_to_act?
204
+ if next_player_to_act
205
+ next_player_to_act.seat == @users_seat
206
+ else
207
+ false
208
+ end
210
209
  end
211
- end
212
210
 
213
- # @return [Array<ChipStack>] Player stacks.
214
- def chip_stacks
215
- @players.map { |player| player.chip_stack }
216
- end
211
+ # @return [Array<AcpcPokerTypes::ChipStack>] AcpcPokerTypes::Player stacks.
212
+ def chip_stacks
213
+ @players.map { |player| player.chip_stack }
214
+ end
217
215
 
218
- # return [Array<Integer>] Each player's current chip balance.
219
- def chip_balances
220
- @players.map { |player| player.chip_balance }
221
- end
216
+ # return [Array<Integer>] Each player's current chip balance.
217
+ def chip_balances
218
+ @players.map { |player| player.chip_balance }
219
+ end
222
220
 
223
- # return [Array<Array<Integer>>] Each player's current chip contribution organized by round.
224
- def chip_contributions
225
- @players.map { |player| player.chip_contributions }
226
- end
221
+ # return [Array<Array<Integer>>] Each player's current chip contribution organized by round.
222
+ def chip_contributions
223
+ @players.map { |player| player.chip_contributions }
224
+ end
227
225
 
228
- # @param [Integer] player The player of which the position relative to the
229
- # dealer is desired.
230
- # @return [Integer] The position relative to the user of the given player,
231
- # +player+, indexed such that the player immediately to the left of the
232
- # dealer has a +position_relative_to_dealer+ of zero.
233
- # @example The player immediately to the left of the user has
234
- # +position_relative_to_user+ == 0
235
- # @example The user has
236
- # +position_relative_to_user+ == +number_of_players+ - 1
237
- # @raise (see Integer#position_relative_to)
238
- def position_relative_to_user(player)
239
- player.seat.position_relative_to user_player.seat, number_of_players
240
- end
226
+ # @param [Integer] player The player of which the position relative to the
227
+ # dealer is desired.
228
+ # @return [Integer] The position relative to the user of the given player,
229
+ # +player+, indexed such that the player immediately to the left of the
230
+ # dealer has a +position_relative_to_dealer+ of zero.
231
+ # @example The player immediately to the left of the user has
232
+ # +position_relative_to_user+ == 0
233
+ # @example The user has
234
+ # +position_relative_to_user+ == +number_of_players+ - 1
235
+ # @raise (see Integer#position_relative_to)
236
+ def position_relative_to_user(player)
237
+ player.seat.position_relative_to user_player.seat, number_of_players
238
+ end
241
239
 
242
- # @param [Integer] player The player of which the position relative to the
243
- # dealer is desired.
244
- # @return [Integer] The position relative to the dealer of the given player,
245
- # +player+, indexed such that the player immediately to to the left of the
246
- # dealer has a +position_relative_to_dealer+ of zero.
247
- # @raise (see Integer#seat_from_relative_position)
248
- # @raise (see Integer#position_relative_to)
249
- def position_relative_to_dealer(player)
250
- seat_of_dealer = @users_seat.seat_from_relative_position(
251
- users_position_relative_to_dealer, number_of_players)
252
-
253
- player.seat.position_relative_to seat_of_dealer, number_of_players
254
- end
240
+ # @param [Integer] player The player of which the position relative to the
241
+ # dealer is desired.
242
+ # @return [Integer] The position relative to the dealer of the given player,
243
+ # +player+, indexed such that the player immediately to to the left of the
244
+ # dealer has a +position_relative_to_dealer+ of zero.
245
+ # @raise (see Integer#seat_from_relative_position)
246
+ # @raise (see Integer#position_relative_to)
247
+ def position_relative_to_dealer(player)
248
+ seat_of_dealer = @users_seat.seat_from_relative_position(
249
+ users_position_relative_to_dealer, number_of_players)
250
+
251
+ player.seat.position_relative_to seat_of_dealer, number_of_players
252
+ end
255
253
 
256
- def amount_to_call(player)
257
- @players.map do |p|
258
- p.chip_contributions.sum
259
- end.max - player.chip_contributions.sum
260
- end
254
+ def amount_to_call(player)
255
+ @players.map do |p|
256
+ p.chip_contributions.sum
257
+ end.max - player.chip_contributions.sum
258
+ end
261
259
 
262
- def cost_of_action(player, action, round=round_in_which_last_action_taken)
263
- ChipStack.new(
264
- if action.to_acpc_character == 'c'
265
- amount_to_call player
266
- elsif action.to_acpc_character == 'b' || action.to_acpc_character == 'r'
267
- if action.modifier
268
- action.modifier - player.chip_contributions.sum
260
+ def cost_of_action(player, action, round=@transition.next_state.round_in_which_last_action_taken)
261
+ AcpcPokerTypes::ChipStack.new(
262
+ if action.action == AcpcPokerTypes::PokerAction::CALL
263
+ amount_to_call player
264
+ elsif action.action == AcpcPokerTypes::PokerAction::BET || action.action == AcpcPokerTypes::PokerAction::RAISE
265
+ if action.modifier
266
+ action.modifier.to_i - player.chip_contributions.sum
267
+ else
268
+ @game_def.min_wagers[round] + amount_to_call(player)
269
+ end
269
270
  else
270
- @game_def.min_wagers[round] + amount_to_call(player)
271
+ 0
271
272
  end
272
- else
273
- 0
274
- end
275
- )
276
- end
277
-
278
- # @return [Set] The set of legal actions for the currently acting player.
279
- def legal_actions
280
- list_of_actions = if next_player_to_act.nil?
281
- []
282
- elsif player_sees_wager?
283
- ['c', 'f', 'r']
284
- elsif chips_contributed_to_pot_this_round?
285
- ['k', 'r']
286
- else
287
- ['k', 'b']
273
+ )
288
274
  end
289
275
 
290
- list_of_actions.inject(Set.new) do |set, action|
291
- set << PokerAction.new(action)
276
+ # @return [Set] The set of legal actions for the currently acting player.
277
+ def legal_actions
278
+ Set.new(
279
+ if next_player_to_act.nil?
280
+ []
281
+ elsif player_sees_wager?
282
+ [AcpcPokerTypes::PokerAction::CALL, AcpcPokerTypes::PokerAction::FOLD, AcpcPokerTypes::PokerAction::RAISE]
283
+ elsif chips_contributed_to_pot_this_round?
284
+ [AcpcPokerTypes::PokerAction::CHECK, AcpcPokerTypes::PokerAction::RAISE]
285
+ else
286
+ [AcpcPokerTypes::PokerAction::CHECK, AcpcPokerTypes::PokerAction::BET]
287
+ end
288
+ )
292
289
  end
293
- end
294
290
 
295
- # @return [Boolean] +true+ if the current hand is the last in the match.
296
- def last_hand?
297
- # @todo make sure +@match_state.hand_number+ is not greater than @number_of_hands
298
- return false unless @transition.next_state
291
+ # @return [Boolean] +true+ if the current hand is the last in the match.
292
+ def last_hand?
293
+ # @todo make sure +@match_state.hand_number+ is not greater than @number_of_hands
294
+ return false unless @transition.next_state
299
295
 
300
- @transition.next_state.hand_number == @number_of_hands - 1
301
- end
296
+ @transition.next_state.hand_number == @number_of_hands - 1
297
+ end
302
298
 
303
- private
299
+ private
304
300
 
305
- def player_contributed_to_pot_this_round?(player=next_player_to_act)
306
- player.chip_contributions.last > 0
307
- end
301
+ def player_contributed_to_pot_this_round?(player=next_player_to_act)
302
+ player.chip_contributions.last > 0
303
+ end
308
304
 
309
- # @todo Change MST#next_state to current_state
310
- def chips_contributed_to_pot_this_round?(round=@transition.next_state.round)
311
- chip_contributions.inject(0) do |both_players_contributions, contributions|
312
- both_players_contributions += contributions[round].to_i
313
- end > 0
314
- end
305
+ # @todo Change MST#next_state to current_state
306
+ def chips_contributed_to_pot_this_round?(round=@transition.next_state.round)
307
+ chip_contributions.inject(0) do |all_contributions, contributions|
308
+ all_contributions += contributions[round].to_r
309
+ end > 0
310
+ end
315
311
 
316
- def player_sees_wager?(player=next_player_to_act)
317
- amount_to_call(player) > 0
318
- end
312
+ def player_sees_wager?(player=next_player_to_act)
313
+ return false unless player
314
+ amount_to_call(player) > 0
315
+ end
319
316
 
320
- def users_position_relative_to_dealer() @transition.next_state.position_relative_to_dealer end
317
+ def users_position_relative_to_dealer() @transition.next_state.position_relative_to_dealer end
321
318
 
322
- # @todo move to MatchState
323
- def round_in_which_last_action_taken(state=@transition.next_state)
324
- unless state && state.number_of_actions_this_hand > 0
325
- nil
326
- else
327
- if state.number_of_actions_this_round < 1
328
- state.round - 1
329
- else
330
- state.round
331
- end
332
- end
333
- end
319
+ def start_new_hand!
320
+ @player_acting_sequence = [[]]
334
321
 
335
- def start_new_hand!
336
- @player_acting_sequence = [[]]
322
+ @players.each do |player|
323
+ player.start_new_hand!(
324
+ blinds[position_relative_to_dealer(player)],
325
+ @game_def.chip_stacks[position_relative_to_dealer(player)], # @todo if playing Doyle's game
326
+ @transition.next_state.list_of_hole_card_hands[position_relative_to_dealer(player)]
327
+ )
328
+ end
337
329
 
338
- @players.each do |player|
339
- player.start_new_hand!(
340
- blinds[position_relative_to_dealer(player)],
341
- @game_def.chip_stacks[position_relative_to_dealer(player)], # @todo if playing Doyle's game
342
- @transition.next_state.list_of_hole_card_hands[position_relative_to_dealer(player)]
343
- )
330
+ set_min_wager!
344
331
  end
345
332
 
346
- set_min_wager!
347
- end
348
-
349
- def assign_hole_cards_to_players!
350
- @players.each do |player|
351
- player.assign_cards! @transition.next_state.list_of_hole_card_hands[position_relative_to_dealer(player)]
333
+ def assign_hole_cards_to_players!
334
+ @players.each do |player|
335
+ player.assign_cards! @transition.next_state.list_of_hole_card_hands[position_relative_to_dealer(player)]
336
+ end
352
337
  end
353
- end
354
338
 
355
- def update_state_of_players!
356
- assign_hole_cards_to_players!
339
+ def update_state_of_players!
340
+ assign_hole_cards_to_players!
357
341
 
358
- action_with_context = PokerAction.new(
359
- @transition.next_state.last_action.to_acpc, {
360
- amount_to_put_in_pot: cost_of_action(
342
+ action_with_context = AcpcPokerTypes::PokerAction.new(
343
+ @transition.next_state.last_action.to_s,
344
+ cost: cost_of_action(
361
345
  player_who_acted_last,
362
346
  @transition.next_state.last_action
363
- ),
364
- # @todo Change the name and semantics of this key here to chips_has_contributed
365
- acting_player_sees_wager: chips_contributed_to_pot_this_round?(@transition.next_state.round_in_which_last_action_taken)
366
- }
367
- )
368
- unless action_with_context.to_acpc_character == 'f'
369
- last_amount_called = amount_to_call(player_who_acted_last)
370
- @min_wager = ChipStack.new [@min_wager.to_r, action_with_context.amount_to_put_in_pot.to_r - last_amount_called].max
371
- end
347
+ )
348
+ )
349
+ unless action_with_context.to_s == 'f'
350
+ last_amount_called = amount_to_call(player_who_acted_last)
351
+ @min_wager = AcpcPokerTypes::ChipStack.new [@min_wager.to_r, action_with_context.cost.to_r - last_amount_called].max
352
+ end
372
353
 
373
- player_who_acted_last.take_action! action_with_context
354
+ player_who_acted_last.take_action!(
355
+ action_with_context,
356
+ pot_gained_chips: chips_contributed_to_pot_this_round?(@transition.next_state.round_in_which_last_action_taken),
357
+ sees_wager: player_sees_wager?
358
+ )
374
359
 
375
- if @transition.new_round?
376
- active_players.each { |player| player.start_new_round! }
377
- set_min_wager!
378
- end
360
+ if @transition.new_round?
361
+ active_players.each { |player| player.start_new_round! }
362
+ set_min_wager!
363
+ end
379
364
 
380
- if hand_ended?
381
- distribute_chips! @transition.next_state.board_cards
365
+ if hand_ended?
366
+ distribute_chips! @transition.next_state.board_cards
367
+ end
382
368
  end
383
- end
384
369
 
385
- # Distribute chips to all winning players
386
- # @param [BoardCards] board_cards The community board cards.
387
- def distribute_chips!(board_cards)
388
- raise NoChipsToDistribute unless pot > 0
389
- raise NoPlayersToTakeChips unless non_folded_players.length > 0
390
-
391
- # @todo This only works for Doyle's game where there are no side-pots.
392
- if 1 == non_folded_players.length
393
- non_folded_players.first.take_winnings! pot
394
- else
395
- players_and_their_hand_strength = {}
396
- non_folded_players.each do |player|
397
- hand_strength = PileOfCards.new(board_cards.flatten + player.hole_cards).to_poker_hand_strength
398
-
399
- players_and_their_hand_strength[player] = hand_strength
400
- end
370
+ # Distribute chips to all winning players
371
+ # @param [BoardCards] board_cards The community board cards.
372
+ def distribute_chips!(board_cards)
373
+ raise NoChipsToDistribute unless pot > 0
374
+ raise NoPlayersToTakeChips unless non_folded_players.length > 0
401
375
 
402
- strength_of_strongest_hand = players_and_their_hand_strength.values.max
403
- winning_players = players_and_their_hand_strength.find_all do |player, hand_strength|
404
- hand_strength == strength_of_strongest_hand
405
- end.map { |player_with_hand_strength| player_with_hand_strength.first }
376
+ # @todo This only works for Doyle's game where there are no side-pots.
377
+ if 1 == non_folded_players.length
378
+ non_folded_players.first.take_winnings! pot
379
+ else
380
+ players_and_their_hand_strength = {}
381
+ non_folded_players.each do |player|
382
+ hand_strength = AcpcPokerTypes::PileOfCards.new(board_cards.flatten + player.hole_cards).to_poker_hand_strength
406
383
 
407
- amount_each_player_wins = pot/winning_players.length.to_r
384
+ players_and_their_hand_strength[player] = hand_strength
385
+ end
408
386
 
409
- winning_players.each do |player|
410
- player.take_winnings! amount_each_player_wins
387
+ strength_of_strongest_hand = players_and_their_hand_strength.values.max
388
+ winning_players = players_and_their_hand_strength.find_all do |player, hand_strength|
389
+ hand_strength == strength_of_strongest_hand
390
+ end.map { |player_with_hand_strength| player_with_hand_strength.first }
391
+
392
+ amount_each_player_wins = pot/winning_players.length.to_r
393
+
394
+ winning_players.each do |player|
395
+ player.take_winnings! amount_each_player_wins
396
+ end
411
397
  end
412
398
  end
413
- end
414
399
 
415
- def pot
416
- chip_contributions.mapped_sum.sum
417
- end
400
+ def pot
401
+ chip_contributions.mapped_sum.sum
402
+ end
418
403
 
419
- def set_min_wager!
420
- @min_wager = @game_def.min_wagers[@transition.next_state.round]
404
+ def set_min_wager!
405
+ @min_wager = @game_def.min_wagers[@transition.next_state.round]
406
+ end
421
407
  end
422
- end
423
408
 
424
- class Array
425
- def find_out_of_bounds_seat(number_of_players)
426
- self.find do |position|
427
- !position.seat_in_bounds?(number_of_players)
409
+ class Array
410
+ def find_out_of_bounds_seat(number_of_players)
411
+ self.find do |position|
412
+ !position.seat_in_bounds?(number_of_players)
413
+ end
414
+ end
415
+ def copy
416
+ inject([]) { |new_array, elem| new_array << elem.copy }
428
417
  end
429
418
  end
430
- def copy
431
- inject([]) { |new_array, elem| new_array << elem.copy }
432
- end
433
- end
419
+ end