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.



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

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_wagerObject (readonly)

Returns the value of attribute min_wager.



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

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.



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

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.



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

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

#amount_to_call(player) ⇒ Object



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

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

#betting_sequenceObject



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

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



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

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

#chip_balancesObject

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



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

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.



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

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.



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

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



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

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.



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

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.



288
289
290
291
292
293
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 288

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.



273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/acpc_poker_match_state/players_at_the_table.rb', line 273

def legal_actions
  Set.new(
    if next_player_to_act.nil?
      []
    elsif player_sees_wager?
      [AcpcPokerTypes::PokerAction::CALL, AcpcPokerTypes::PokerAction::FOLD, AcpcPokerTypes::PokerAction::RAISE]
    elsif chips_contributed_to_pot_this_round?
      [AcpcPokerTypes::PokerAction::CHECK, AcpcPokerTypes::PokerAction::RAISE]
    else
      [AcpcPokerTypes::PokerAction::CHECK, AcpcPokerTypes::PokerAction::BET]
    end
  )
end

#less_than_two_non_folded_players?Boolean

Returns:

  • (Boolean)


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

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.



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

def match_ended?
  hand_ended? && last_hand?
end

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



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

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.



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

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

#opponentsObject



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

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.



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

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.



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

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.



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

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.



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

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.



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

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.



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

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

#reached_showdown?Boolean

Returns:

  • (Boolean)


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

def reached_showdown?
  opponents_cards_visible?
end

#update!(match_state) ⇒ Object

Parameters:

  • match_state (MatchState)

    The next match state.



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

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



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

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.



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

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