class Rubygoal::Team

Constants

INFINITE

Attributes

coach[R]
formation[RW]
game[R]
goalkeeper[RW]
match_data_factory[R]
opponent_side[R]
players[R]
side[R]

Public Class Methods

new(game, coach) click to toggle source
# File lib/rubygoal/team.rb, line 22
def initialize(game, coach)
  @game    = game
  @players = {}
  @coach   = coach

  @match_data_factory = MatchData::Factory.new(game, side)

  initialize_lineup_values
  initialize_players
  initialize_formation
end

Public Instance Methods

players_list() click to toggle source
# File lib/rubygoal/team.rb, line 79
def players_list
  players.values
end
players_position() click to toggle source
# File lib/rubygoal/team.rb, line 83
def players_position
  players.each_with_object({}) do |(name, player), hash|
    hash[name] = Field.field_position(player.position, side)
  end
end
players_to_initial_position() click to toggle source
# File lib/rubygoal/team.rb, line 34
def players_to_initial_position
  match_data = match_data_factory.create
  formation = coach.formation(match_data)
  restart_player_positions_in_own_field(formation)
end
update(elapsed_time) click to toggle source
# File lib/rubygoal/team.rb, line 40
def update(elapsed_time)
  match_data = match_data_factory.create
  self.formation = coach.formation(match_data)

  unless formation.valid?
    puts formation.errors
    raise "Invalid formation: #{coach.name}"
  end

  update_coach_defined_positions(formation)

  player_to_move = nil
  min_distance_to_ball = INFINITE
  players_list.each do |player|
    pass_or_shoot(player) if player.can_kick?(ball)

    distance_to_ball = player.distance(ball.position)
    if min_distance_to_ball > distance_to_ball
      min_distance_to_ball = distance_to_ball
      player_to_move = player
    end
  end

  player_to_move.move_to(ball.position)

  players.each do |name, player|
    if name == :goalkeeper
      if player != player_to_move
        player.move_to_cover_goal(ball)
        player.update(elapsed_time)
        next
      end
    end

    player.move_to_coach_position unless player == player_to_move
    player.update(elapsed_time)
  end
end

Private Instance Methods

initialize_formation() click to toggle source
# File lib/rubygoal/team.rb, line 99
def initialize_formation
  @formation = @coach.initial_formation
end
initialize_lineup_values() click to toggle source
# File lib/rubygoal/team.rb, line 94
def initialize_lineup_values
  @average_players_count = 6
  @fast_players_count = 3
end
initialize_player_positions() click to toggle source
# File lib/rubygoal/team.rb, line 164
def initialize_player_positions
  Field.default_player_field_positions.each_with_index do |pos, index|
    players.values[index].position = lineup_to_position(pos)
    players.values[index].coach_defined_position = lineup_to_position(pos)
  end
end
initialize_players() click to toggle source
# File lib/rubygoal/team.rb, line 103
def initialize_players
  @players = { goalkeeper: GoalKeeperPlayer.new(game, side, :goalkeeper) }

  unless @coach.valid?
    puts @coach.errors
    raise "Invalid team definition: #{@coach.name}"
  end

  @players[@coach.captain_player.name] = CaptainPlayer.new(game, side, @coach.captain_player.name)

  @coach.players_by_type(:fast).each do |player_def|
    @players[player_def.name] = FastPlayer.new(game, side, player_def.name)
  end

  @coach.players_by_type(:average).each do |player_def|
    @players[player_def.name] = AveragePlayer.new(game, side, player_def.name)
  end

  initialize_player_positions
end
lineup_to_position(field_position) click to toggle source
# File lib/rubygoal/team.rb, line 189
def lineup_to_position(field_position)
  Field.absolute_position(field_position, side)
end
nearest_forward_teammate(player) click to toggle source
# File lib/rubygoal/team.rb, line 138
def nearest_forward_teammate(player)
  min_dist = INFINITE
  nearest_teammate = nil

  (players.values - [player]).each do |teammate|
    next unless teammate_is_on_front?(player, teammate)
    dist = player.distance(teammate.position)
    if min_dist > dist
      nearest_teammate = teammate
      min_dist = dist
    end
  end

  nearest_teammate
end
pass_or_shoot(player) click to toggle source
# File lib/rubygoal/team.rb, line 124
def pass_or_shoot(player)
  # Kick straight to the goal whether the distance is short (200)
  # or we don't have a better option
  target = shoot_target

  unless Field.close_to_goal?(player.position, opponent_side)
    if teammate = nearest_forward_teammate(player)
      target = teammate.position
    end
  end

  player.kick(ball, target)
end
restart_player_positions_in_own_field(formation) click to toggle source
# File lib/rubygoal/team.rb, line 177
def restart_player_positions_in_own_field(formation)
  formation.players_position.each do |player_name, pos|
    pos.x *= 0.5
    pos = lineup_to_position(pos)

    player = players[player_name]

    player.coach_defined_position = pos
    player.position = pos
  end
end
shoot_target() click to toggle source
# File lib/rubygoal/team.rb, line 154
def shoot_target
  # Do not kick always to the center, look for the sides of the goal
  limit = Field::GOAL_HEIGHT / 2
  offset = Random.rand(-limit..limit)

  target = Field.goal_position(opponent_side)
  target.y += offset
  target
end
update_coach_defined_positions(formation) click to toggle source
# File lib/rubygoal/team.rb, line 171
def update_coach_defined_positions(formation)
  formation.players_position.each do |player_name, pos|
    players[player_name].coach_defined_position = lineup_to_position(pos)
  end
end