require 'delegate' module AcpcPokerTypes module SeatLike # @param [Integer] seat The seat to which the relative position is desired. # @param [Integer] number_of_players The number of players at the table. # @return [Integer] The relative position of +self+ to +seat+, given the # number of players at the table, +number_of_players+, indexed such that # the seat immediately to the left of +seat+ has a +position_relative_to+ of # zero. # @example 1.position_relative_to 0, 3 == 0 # @example 1.position_relative_to 1, 3 == 2 def position_relative_to(seat, number_of_players) unless seat.seat_in_bounds?(number_of_players) && seat_in_bounds?(number_of_players) raise "Seat #{seat} out of bounds for #{number_of_players} players" end adjusted_seat = if self > seat self else self + number_of_players end adjusted_seat - seat - 1 end # Inverse operation of +position_relative_to+. # Given # relative_position = seat.position_relative_to to_seat, number_of_players # then # to_seat = seat.seat_from_relative_position relative_position, number_of_players # # @param [Integer] relative_position_of_self_to_result The relative position # of seat +self+ to the seat that is returned by this function. # @param [Integer] number_of_players The number of players at the table. # @return [Integer] The seat to which the relative position, # +relative_position_of_self_to_result+, of +self+ was derived, given the # number of players at the table, +number_of_players+, indexed such that # the seat immediately to the left of +from_seat+ has a # +position_relative_to+ of zero. # @example 1.seat_from_relative_position 0, 3 == 0 # @example 1.seat_from_relative_position 2, 3 == 1 def seat_from_relative_position( relative_position_of_self_to_result, number_of_players ) unless seat_in_bounds?(number_of_players) raise "Seat #{seat} out of bounds for #{number_of_players} players" end unless relative_position_of_self_to_result.seat_in_bounds?( number_of_players ) raise "Relative position #{relative_position_of_self_to_result} out of bounds for #{number_of_players} players" end position_adjustment = relative_position_of_self_to_result + 1 to_seat = self.class.new( self + number_of_players - position_adjustment ) if self > to_seat || !to_seat.seat_in_bounds?(number_of_players) self - position_adjustment else to_seat end end # @param [Integer] number_of_players The number of players at the table. # @return [Bool] Reports whether or not +self+ represents an out of bounds # seat. def seat_in_bounds?(number_of_players) self < number_of_players && self >= 0 end end class Seat < DelegateClass(Integer) include SeatLike def initialize(seat) @seat = seat.to_i super @seat end end end