Class: Sashite::Pcn::Game::Sides::Player

Inherits:
Object
  • Object
show all
Defined in:
lib/sashite/pcn/game/sides/player.rb

Overview

Represents a single player with optional metadata and time control

All fields are optional. An empty Player object (no information) is valid. The periods field defines time control settings for this player.

Examples:

Complete player with time control

player = Player.new(
  name: "Carlsen",
  elo: 2830,
  style: "CHESS",
  periods: [
    { time: 5400, moves: 40, inc: 0 },    # 90 min for first 40 moves
    { time: 1800, moves: nil, inc: 30 }   # 30 min + 30s/move for rest
  ]
)

Fischer/Increment time control (5+3 blitz)

player = Player.new(
  name: "Player 1",
  periods: [
    { time: 300, moves: nil, inc: 3 }     # 5 min + 3s increment
  ]
)

Byōyomi time control

player = Player.new(
  name: "Yamada",
  style: "SHOGI",
  periods: [
    { time: 3600, moves: nil, inc: 0 },   # Main time: 1 hour
    { time: 60, moves: 1, inc: 0 },       # 60s per move (5 periods)
    { time: 60, moves: 1, inc: 0 },
    { time: 60, moves: 1, inc: 0 },
    { time: 60, moves: 1, inc: 0 },
    { time: 60, moves: 1, inc: 0 }
  ]
)

No time control (casual game)

player = Player.new(name: "Casual Player", periods: [])

Empty player

player = Player.new  # Valid, no player information

Constant Summary collapse

ERROR_INVALID_STYLE =

Error messages

"style must be a valid SNN string"
ERROR_INVALID_NAME =
"name must be a string"
ERROR_INVALID_ELO =
"elo must be a non-negative integer (>= 0)"
ERROR_INVALID_PERIODS =
"periods must be an array"
ERROR_INVALID_PERIOD =
"each period must be a hash"
ERROR_MISSING_TIME =
"period must have 'time' field"
ERROR_INVALID_TIME =
"time must be a non-negative integer (>= 0)"
ERROR_INVALID_MOVES =
"moves must be nil or a positive integer (>= 1)"
ERROR_INVALID_INC =
"inc must be a non-negative integer (>= 0)"

Instance Method Summary collapse

Constructor Details

#initialize(style: nil, name: nil, elo: nil, periods: nil) ⇒ Player

Create a new Player instance

Raises:

  • (ArgumentError)

    if field values don’t meet constraints



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/sashite/pcn/game/sides/player.rb', line 69

def initialize(style: nil, name: nil, elo: nil, periods: nil)
  # Validate and assign style (optional)
  if style
    raise ::ArgumentError, ERROR_INVALID_STYLE unless style.is_a?(::String)
    @style = ::Sashite::Snn.parse(style)
  else
    @style = nil
  end

  # Validate and assign name (optional)
  if name
    raise ::ArgumentError, ERROR_INVALID_NAME unless name.is_a?(::String)
    @name = name.freeze
  else
    @name = nil
  end

  # Validate and assign elo (optional, must be >= 0)
  if elo
    raise ::ArgumentError, ERROR_INVALID_ELO unless elo.is_a?(::Integer)
    raise ::ArgumentError, ERROR_INVALID_ELO unless elo >= 0
    @elo = elo
  else
    @elo = nil
  end

  # Validate and assign periods
  periods = [] if periods.nil?

  raise ::ArgumentError, ERROR_INVALID_PERIODS unless periods.is_a?(::Array)
  @periods = validate_and_normalize_periods(periods).freeze

  freeze
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Check equality with another Player object



241
242
243
244
245
246
247
248
# File 'lib/sashite/pcn/game/sides/player.rb', line 241

def ==(other)
  return false unless other.is_a?(self.class)

  @style == other.style &&
    @name == other.name &&
    @elo == other.elo &&
    @periods == other.periods
end

#eloInteger?

Get player Elo rating

Examples:

player.elo  # => 2830


130
131
132
# File 'lib/sashite/pcn/game/sides/player.rb', line 130

def elo
  @elo
end

#empty?Boolean

Check if no player information is present

Examples:

player.empty?  # => true


185
186
187
# File 'lib/sashite/pcn/game/sides/player.rb', line 185

def empty?
  @style.nil? && @name.nil? && @elo.nil? && @periods.empty?
end

#has_time_control?Boolean

Check if player has time control

Examples:

player.has_time_control?  # => true


153
154
155
# File 'lib/sashite/pcn/game/sides/player.rb', line 153

def has_time_control?
  !unlimited_time?
end

#hashInteger

Hash code for use in collections



255
256
257
# File 'lib/sashite/pcn/game/sides/player.rb', line 255

def hash
  [@style, @name, @elo, @periods].hash
end

#initial_time_budgetInteger?

Get initial time budget (sum of all period times)

Examples:

player.initial_time_budget  # => 7200 (2 hours)


173
174
175
176
177
# File 'lib/sashite/pcn/game/sides/player.rb', line 173

def initial_time_budget
  return if unlimited_time?

  @periods.sum { |period| period[:time] }
end

#inspectString

String representation for debugging



227
228
229
230
231
232
233
234
235
# File 'lib/sashite/pcn/game/sides/player.rb', line 227

def inspect
  attrs = []
  attrs << "style=#{@style.inspect}" if @style
  attrs << "name=#{@name.inspect}" if @name
  attrs << "elo=#{@elo.inspect}" if @elo
  attrs << "periods=#{@periods.inspect}" if @periods.any?

  "#<#{self.class.name} #{attrs.join(' ')}>"
end

#nameString?

Get player name

Examples:

player.name  # => "Carlsen"


120
121
122
# File 'lib/sashite/pcn/game/sides/player.rb', line 120

def name
  @name
end

#periodsArray<Hash>

Get time control periods

Examples:

player.periods
# => [
#   { time: 300, moves: nil, inc: 3 }
# ]


143
144
145
# File 'lib/sashite/pcn/game/sides/player.rb', line 143

def periods
  @periods
end

#styleSashite::Snn::Name?

Get player style

Examples:

player.style  # => #<Sashite::Snn::Name ...>


110
111
112
# File 'lib/sashite/pcn/game/sides/player.rb', line 110

def style
  @style
end

#to_hHash

Convert to hash representation

Returns a hash containing only defined (non-nil) fields. If all fields are nil, returns an empty hash.

Examples:

Complete player

player.to_h
# => {
#   style: "CHESS",
#   name: "Carlsen",
#   elo: 2830,
#   periods: [
#     { time: 5400, moves: 40, inc: 0 },
#     { time: 1800, moves: nil, inc: 30 }
#   ]
# }

Partial player

player.to_h
# => { name: "Alice", periods: [] }

Empty player

player.to_h
# => {}


215
216
217
218
219
220
221
222
# File 'lib/sashite/pcn/game/sides/player.rb', line 215

def to_h
  result = {}
  result[:style] = @style.to_s unless @style.nil?
  result[:name] = @name unless @name.nil?
  result[:elo] = @elo unless @elo.nil?
  result[:periods] = @periods unless @periods.empty?
  result
end

#unlimited_time?Boolean

Check if player has unlimited time (no time control)

Examples:

player.unlimited_time?  # => false


163
164
165
# File 'lib/sashite/pcn/game/sides/player.rb', line 163

def unlimited_time?
  @periods.empty?
end