lib/sportradar/api/baseball/lineup.rb
module Sportradar
module Api
module Baseball
class Lineup < Data
attr_reader :roster, :home, :away, :game
def initialize(data, game: nil)
@game = game
end
def update(data, source: nil)
case source
when :pbp
@home = initial_lineup.dup
@away = initial_lineup.dup
lineups = game.events.select {|ev| ev.lineup }.map(&:lineup)
lineups.each do |line|
player_data = line.response
player_data['id'] = player_data.delete('player_id')
update_from_lineup_event(player_data)
end
when :summary
@roster = (data.dig('home', 'roster') || []) + (data.dig('away', 'roster') || [])
return unless data.dig('home', 'lineup') && data.dig('away', 'lineup')
@home_team_lineup = data.dig('home', 'lineup')
@away_team_lineup = data.dig('away', 'lineup')
initialize_home
initialize_away
end
end
def full_home
@home_team_lineup
end
def full_away
@away_team_lineup
end
def update_from_lineup_event(data)
if data.dig('team_id') == game.home_id
update_home(data, data.dig('order'))
elsif data.dig('team_id') == game.away_id
update_away(data, data.dig('order'))
end
end
def update_home(player, order)
return if order == 0
idx = home.index do |h|
h['order'] == order
end
home[idx] = { 'order' => order }
home[idx].merge!(player)
end
def update_away(player, order)
return if order == 0
idx = away.index do |h|
h['order'] == order
end
away[idx] = { 'order' => order}
away[idx].merge!(player)
end
def find_player(id)
roster.detect do |player|
player['id'] == id
end
end
def initial_lineup
[
{ 'order' => 1 },
{ 'order' => 2 },
{ 'order' => 3 },
{ 'order' => 4 },
{ 'order' => 5 },
{ 'order' => 6 },
{ 'order' => 7 },
{ 'order' => 8 },
{ 'order' => 9 },
]
end
def next_batters(team, number_of_upcoming_batters = 3)
if team == 'home'
last_at_bat = game.at_bats.select{|at_bat| at_bat.event.half_inning.half == 'B'}.last
if last_at_bat
last_position = @home.detect{|htl| htl['id'] == last_at_bat.hitter_id}&.dig('order')
upcoming = home.rotate(last_position || 0)
else # first inning
upcoming = home
end
elsif team == 'away'
last_at_bat = game.at_bats.select{|at_bat| at_bat.event.half_inning.half == 'T'}.last
if last_at_bat
last_position = @away.detect{|atl| atl['id'] == last_at_bat.hitter_id}&.dig('order')
upcoming = away.rotate(last_position || 0)
else # first inning
upcoming = away
end
end
upcoming[0..(number_of_upcoming_batters - 1)]
# rescue => e
# i ||= 0
# game.get_summary
# i += 1
# retry unless i > 2
end
private
def initialize_away
@away = initial_lineup.dup
@away_team_lineup.sort_by{|t| t['sequence']}.each do |al|
# al.merge!(find_player(al['id']))
update_away(find_player(al['id']), al['order'])
end.sort_by{|al| al['order']}
end
def initialize_home
@home = initial_lineup.dup
@home_team_lineup.sort_by{|t| t['sequence']}.each do |hl|
# hl.merge!(find_player(hl['id']))
update_home(find_player(hl['id']), hl['order'])
end.sort_by{|hl| hl['order']}
end
end
end
end
end