acpc_poker_match_state 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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