Class: AcpcPokerMatchState::PlayersAtTheTable

Inherits:
Object
  • Object
show all
Defined in:
lib/acpc_poker_match_state/players_at_the_table.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(game_def, player_names, users_seat, number_of_hands) ⇒ PlayersAtTheTable

Returns a new instance of PlayersAtTheTable.

Parameters:

  • game_def (GameDefinition)

    The game definition for the match these players are playing.

  • player_names (Array<String>)

    The names of the players to seat at the table, ordered by seat.

  • users_seat (Integer)

    The user’s seat at the table. players are joining.

  • number_of_hands (Integer)

    The number of hands in this match.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 40

def initialize(game_def, player_names, users_seat, number_of_hands)
  @players = AcpcPokerTypes::Player.create_players player_names, game_def

  @users_seat = AcpcPokerTypes::Seat.new(users_seat, player_names.length)

  @game_def = game_def
  @min_wager = game_def.min_wagers.first

  @transition = AcpcPokerMatchState::MatchStateTransition.new

  @player_acting_sequence = [[]]

  @number_of_hands = number_of_hands
end

Instance Attribute Details

#game_defObject (readonly)

Returns the value of attribute game_def.



22
23
24
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 22

def game_def
  @game_def
end

#min_wagerChipStack (readonly)

Returns Minimum wager by.

Returns:

  • (ChipStack)

    Minimum wager by.



27
28
29
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 27

def min_wager
  @min_wager
end

#number_of_handsObject (readonly)

Returns the value of attribute number_of_hands.



20
21
22
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 20

def number_of_hands
  @number_of_hands
end

#player_acting_sequenceArray<Array<Integer>> (readonly)

Returns The sequence of seats that acted, separated by round.

Returns:

  • (Array<Array<Integer>>)

    The sequence of seats that acted, separated by round.



16
17
18
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 16

def player_acting_sequence
  @player_acting_sequence
end

#player_who_acted_lastObject (readonly)

Returns the value of attribute player_who_acted_last.



29
30
31
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 29

def player_who_acted_last
  @player_who_acted_last
end

#playersObject (readonly)

Returns the value of attribute players.



12
13
14
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 12

def players
  @players
end

#transitionObject (readonly)

Returns the value of attribute transition.



18
19
20
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 18

def transition
  @transition
end

#users_seatObject (readonly)

Returns the value of attribute users_seat.



24
25
26
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 24

def users_seat
  @users_seat
end

Instance Method Details

#active_playersArray<AcpcPokerTypes::Player>

Returns The players who are active.

Returns:

  • (Array<AcpcPokerTypes::Player>)

    The players who are active.



108
109
110
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 108

def active_players
  @players.select { |player| player.active? }
end

#amount_to_call(player = next_player_to_act) ⇒ Object



251
252
253
254
255
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 251

def amount_to_call(player = next_player_to_act)
  @players.map do |p|
    p.chip_contributions.inject(:+)
  end.max - player.chip_contributions.inject(:+)
end

#betting_sequenceObject



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 167

def betting_sequence
  sequence = [[]]
  return sequence unless @transition.next_state

  @player_acting_sequence.each_with_index do |per_round, i|
    actions_taken_this_round = {}

    unless per_round.empty?
      @players.each do |player|
        # Skip if player has folded and a round after the fold is being checked
        next if i >= player.actions_taken_this_hand.length

        actions_taken_this_round[player.seat] = player.actions_taken_this_hand[i].dup
      end
    end

    per_round.each do |seat|
      sequence.last << actions_taken_this_round[seat].shift
    end
    sequence << [] if (@transition.next_state.round+1) > sequence.length
  end
  sequence
end

#betting_sequence_stringObject



161
162
163
164
165
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 161

def betting_sequence_string
  (betting_sequence.map do |per_round|
     (per_round.map{|action| action.to_s}).join('')
  end).join('/')
end

#big_blindObject



321
322
323
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 321

def big_blind
  player_blind_relation.values.max
end

#big_blind_payerObject



324
325
326
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 324

def big_blind_payer
  player_blind_relation.key big_blind
end

#chip_balancesObject

return [Array<Integer>] Each player’s current chip balance.



206
207
208
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 206

def chip_balances
  @players.map { |player| player.chip_balance }
end

#chip_contributionsObject

return [Array<Array<Integer>>] Each player’s current chip contribution organized by round.



211
212
213
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 211

def chip_contributions
  @players.map { |player| player.chip_contributions }
end

#chip_stacksArray<AcpcPokerTypes::ChipStack>

Returns AcpcPokerTypes::Player stacks.

Returns:

  • (Array<AcpcPokerTypes::ChipStack>)

    AcpcPokerTypes::Player stacks.



201
202
203
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 201

def chip_stacks
  @players.map { |player| player.chip_stack }
end

#cost_of_action(player, action, round = @transition.next_state.round_in_which_last_action_taken) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 257

def cost_of_action(player, action, round=@transition.next_state.round_in_which_last_action_taken)
  AcpcPokerTypes::ChipStack.new(
    if action.action == AcpcPokerTypes::PokerAction::CALL
      amount_to_call player
    elsif action.action == AcpcPokerTypes::PokerAction::BET || action.action == AcpcPokerTypes::PokerAction::RAISE
      if action.modifier
        action.modifier.to_i - player.chip_contributions.inject(:+)
      else
        @game_def.min_wagers[round] + amount_to_call(player)
      end
    else
      0
    end
  )
end

#hand_ended?Boolean

Returns true if the hand has ended, false otherwise.

Returns:

  • (Boolean)

    true if the hand has ended, false otherwise.



118
119
120
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 118

def hand_ended?
  less_than_two_non_folded_players? || reached_showdown?
end

#last_hand?Boolean

Returns true if the current hand is the last in the match.

Returns:

  • (Boolean)

    true if the current hand is the last in the match.



314
315
316
317
318
319
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 314

def last_hand?
  # @todo make sure +@match_state.hand_number+ is not greater than @number_of_hands
  return false unless @transition.next_state

  @transition.next_state.hand_number == @number_of_hands - 1
end

Returns The set of legal actions for the currently acting player.

Returns:

  • (Set)

    The set of legal actions for the currently acting player.



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 274

def legal_actions
  Set.new(
    if next_player_to_act.nil?
      []
    elsif player_sees_wager?
      actions_without_wager = [
        AcpcPokerTypes::PokerAction::CALL,
        AcpcPokerTypes::PokerAction::FOLD
      ]

      if wager_legal?
        actions_without_wager << AcpcPokerTypes::PokerAction::RAISE
      else
        actions_without_wager
      end
    elsif chips_contributed_to_pot_this_round?
      actions_without_wager = [AcpcPokerTypes::PokerAction::CHECK]

      if wager_legal?
        actions_without_wager << AcpcPokerTypes::PokerAction::RAISE
      else
        actions_without_wager
      end
    else
      actions_without_wager = [AcpcPokerTypes::PokerAction::CHECK]

      if wager_legal?
        actions_without_wager << AcpcPokerTypes::PokerAction::BET
      else
        actions_without_wager
      end
    end
  )
end

#less_than_two_non_folded_players?Boolean

Returns:

  • (Boolean)


127
128
129
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 127

def less_than_two_non_folded_players?
  non_folded_players.length < 2
end

#match_ended?Boolean

Returns true if the match has ended, false otherwise.

Returns:

  • (Boolean)

    true if the match has ended, false otherwise.



123
124
125
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 123

def match_ended?
  hand_ended? && last_hand?
end

#next_player_to_act(state = @transition.next_state) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 71

def next_player_to_act(state=@transition.next_state)
  return nil unless state && !hand_ended? && !active_players.empty?

  reference_position = if state.number_of_actions_this_round > 0
    position_relative_to_dealer player_who_acted_last
  else
    @game_def.first_player_positions[state.round] - 1
  end

  @players.length.times.inject(nil) do |player_who_might_act, i|
    position_relative_to_dealer_to_act = (reference_position + i + 1) % @players.length
    player_who_might_act = active_players.find do |player|
      position_relative_to_dealer(player) == position_relative_to_dealer_to_act
    end
    if player_who_might_act then break player_who_might_act else nil end
  end
end

#non_folded_playersArray<AcpcPokerTypes::Player>

Returns The players who have not folded.

Returns:

  • (Array<AcpcPokerTypes::Player>)

    The players who have not folded.



113
114
115
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 113

def non_folded_players
  @players.select { |player| !player.folded? }
end

#opponentsObject



99
100
101
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 99

def opponents
  @players.select { |player| player.seat != @users_seat }
end

#opponents_cards_visible?Boolean

Returns true if any opponents cards are visible, false otherwise.

Returns:

  • (Boolean)

    true if any opponents cards are visible, false otherwise.



136
137
138
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 136

def opponents_cards_visible?
  opponents.any? { |player| player.hole_cards && !player.hole_cards.empty? }
end

#player_acting_sequence_stringString

Returns player acting sequence as a string.

Returns:

  • (String)

    player acting sequence as a string.



157
158
159
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 157

def player_acting_sequence_string
  (@player_acting_sequence.map { |per_round| per_round.join('') }).join('/')
end

#player_blind_relationHash<AcpcPokerTypes::Player, #to_i] Relation from player to the blind that player paid.

Returns Hash<AcpcPokerTypes::Player, #to_i] Relation from player to the blind that player paid.

Returns:

  • (Hash<AcpcPokerTypes::Player, #to_i] Relation from player to the blind that player paid.)

    Hash<AcpcPokerTypes::Player, #to_i] Relation from player to the blind that player paid.



147
148
149
150
151
152
153
154
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 147

def player_blind_relation
  return nil unless @transition.next_state

  @players.inject({}) do |relation, player|
    relation[player] = @game_def.blinds[position_relative_to_dealer(player)]
    relation
  end
end

#player_with_dealer_buttonAcpcPokerTypes::Player

Returns The player with the dealer button.

Returns:

  • (AcpcPokerTypes::Player)

    The player with the dealer button.



141
142
143
144
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 141

def player_with_dealer_button
  return nil unless @transition.next_state
  @players.find { |player| position_relative_to_dealer(player) == @players.length - 1}
end

#position_relative_to_dealer(player) ⇒ Integer

Returns The position relative to the dealer of the given player, player, indexed such that the player immediately to to the left of the dealer has a position_relative_to_dealer of zero.

Parameters:

  • player (Integer)

    The player of which the position relative to the dealer is desired.

Returns:

  • (Integer)

    The position relative to the dealer of the given player, player, indexed such that the player immediately to to the left of the dealer has a position_relative_to_dealer of zero.



236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 236

def position_relative_to_dealer(player)
  seats_from_dealer = (users_position_relative_to_dealer + 1) % @players.length

  dealers_seat = AcpcPokerTypes::Seat.new(
    if @users_seat < seats_from_dealer
      @players.length
    else
      0
    end + @users_seat - seats_from_dealer,
    @players.length
  )

  dealers_seat.n_seats_away(1).seats_to(player.seat)
end

#position_relative_to_user(player) ⇒ Integer

Returns The position relative to the user of the given player, player, indexed such that the player immediately to the left of the user has a position_relative_to_user of zero.

Examples:

The player immediately to the left of the user has

+position_relative_to_user+ == 0

The user has

+position_relative_to_user+ == [email protected]+ - 1

Parameters:

  • player (Integer)

    The player of which the position relative to the dealer is desired.

Returns:

  • (Integer)

    The position relative to the user of the given player, player, indexed such that the player immediately to the left of the user has a position_relative_to_user of zero.



225
226
227
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 225

def position_relative_to_user(player)
  @users_seat.n_seats_away(1).seats_to player.seat
end

#reached_showdown?Boolean

Returns:

  • (Boolean)


131
132
133
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 131

def reached_showdown?
  opponents_cards_visible?
end

#small_blindObject



327
328
329
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 327

def small_blind
  player_blind_relation.values.sort[-2]
end

#small_blind_payerObject



330
331
332
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 330

def small_blind_payer
  player_blind_relation.key small_blind
end

#update!(match_state) ⇒ Object

Parameters:

  • match_state (MatchState)

    The next match state.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 56

def update!(match_state)
  @transition.set_next_state! match_state

  if @transition.initial_state?
    start_new_hand!
  else
    @player_acting_sequence.last << next_player_to_act(@transition.last_state).seat

    update_state_of_players!

    @player_acting_sequence << [] if @transition.new_round?
  end
  self
end

#user_playerObject



103
104
105
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 103

def user_player
  @players.find { |player| @users_seat == player.seat }
end

#users_turn_to_act?Boolean

Returns true if it is the user’s turn to act, false otherwise.

Returns:

  • (Boolean)

    true if it is the user’s turn to act, false otherwise.



192
193
194
195
196
197
198
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 192

def users_turn_to_act?
  if next_player_to_act
    next_player_to_act.seat == @users_seat
  else
    false
  end
end

#wager_legal?Boolean

Returns:

  • (Boolean)


309
310
311
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 309

def wager_legal?
  next_player_to_act.chip_contributions.inject(:+) + amount_to_call < @game_def.chip_stacks[position_relative_to_dealer(next_player_to_act)]
end