lib/basketball/drafting/engine.rb in basketball-0.0.4 vs lib/basketball/drafting/engine.rb in basketball-0.0.5

- old
+ new

@@ -1,83 +1,83 @@ # frozen_string_literal: true -require_relative 'roster' +require_relative 'league' module Basketball module Drafting class Engine class AlreadyPickedError < StandardError; end class DupeEventError < StandardError; end class EventOutOfOrderError < StandardError; end class UnknownPlayerError < StandardError; end - class UnknownTeamError < StandardError; end + class UnknownFrontOfficeError < StandardError; end class EndOfDraftError < StandardError; end DEFAULT_ROUNDS = 12 private_constant :DEFAULT_ROUNDS attr_reader :events, :rounds - def initialize(players: [], teams: [], events: [], rounds: DEFAULT_ROUNDS) - @players_by_id = players.to_h { |p| [p.id, p] } - @teams_by_id = teams.to_h { |t| [t.id, t] } - @events = [] - @rounds = rounds.to_i + def initialize(players: [], front_offices: [], events: [], rounds: DEFAULT_ROUNDS) + @players_by_id = players.to_h { |p| [p.id, p] } + @front_offices_by_id = front_offices.to_h { |fo| [fo.id, fo] } + @events = [] + @rounds = rounds.to_i # Each one will be validated for correctness. events.each { |e| play!(e) } freeze end - def rosters - events_by_team = teams.to_h { |t| [t, []] } + def to_league + League.new(front_offices:).tap do |league| + player_events.each do |event| + league.register!(player: event.player, front_office: event.front_office) + end - events.each do |event| - events_by_team.fetch(event.team) << event + undrafted_players.each do |player| + league.register!(player:) + end end - - events_by_team.map do |team, events| - Roster.new(team:, events:) - end end def to_s events.join("\n") end - def teams - teams_by_id.values + def front_offices + front_offices_by_id.values end def players players_by_id.values end def total_picks - rounds * teams.length + rounds * front_offices.length end def current_round return if done? - (current_pick / teams.length.to_f).ceil + (current_pick / front_offices.length.to_f).ceil end def current_round_pick return if done? - mod = current_pick % teams.length + mod = current_pick % front_offices.length - mod.positive? ? mod : teams.length + mod.positive? ? mod : front_offices.length end - def current_team + def current_front_office return if done? - teams[current_round_pick - 1] + front_offices[current_round_pick - 1] end def current_pick return if done? @@ -99,11 +99,11 @@ def skip! return if done? event = SkipEvent.new( id: SecureRandom.uuid, - team: current_team, + front_office: current_front_office, pick: current_pick, round: current_round, round_pick: current_round_pick ) @@ -115,21 +115,21 @@ def sim!(times = nil) counter = 0 events = [] until done? || (times && counter >= times) - team = current_team + front_office = current_front_office - player = team.pick( + player = front_office.pick( undrafted_player_search:, - drafted_players: drafted_players(team), + drafted_players: drafted_players(front_office), round: current_round ) event = SimEvent.new( id: SecureRandom.uuid, - team:, + front_office:, player:, pick: current_pick, round: current_round, round_pick: current_round_pick ) @@ -148,11 +148,11 @@ def pick!(player) return nil if done? event = PickEvent.new( id: SecureRandom.uuid, - team: current_team, + front_office: current_front_office, player:, pick: current_pick, round: current_round, round_pick: current_round_pick ) @@ -168,23 +168,23 @@ PlayerSearch.new(undrafted_players) end private - attr_reader :players_by_id, :teams_by_id + attr_reader :players_by_id, :front_offices_by_id def player_events events.select { |e| e.respond_to?(:player) } end def internal_current_pick events.length + 1 end - def drafted_players(team = nil) + def drafted_players(front_office = nil) player_events.each_with_object([]) do |e, memo| - next unless team.nil? || e.team == team + next unless front_office.nil? || e.front_office == front_office memo << e.player end end @@ -198,16 +198,20 @@ if event.respond_to?(:player) && !players.include?(event.player) raise UnknownPlayerError, "#{event.player} doesnt exist" end - raise DupeEventError, "#{event} is a dupe" if events.include?(event) - raise EventOutOfOrder, "#{event} team cant pick right now" if event.team != current_team - raise EventOutOfOrder, "#{event} has wrong pick" if event.pick != current_pick - raise EventOutOfOrder, "#{event} has wrong round" if event.round != current_round - raise EventOutOfOrder, "#{event} has wrong round_pick" if event.round_pick != current_round_pick - raise UnknownTeamError, "#{team} doesnt exist" unless teams.include?(event.team) - raise EndOfDraftError, "#{total_picks} pick limit reached" if events.length > total_picks + 1 + if event.front_office != current_front_office + raise EventOutOfOrder, "#{event} #{event.front_office} cant pick right now" + end + + raise UnknownFrontOfficeError, "#{front_office} doesnt exist" unless front_offices.include?(event.front_office) + + raise DupeEventError, "#{event} is a dupe" if events.include?(event) + raise EventOutOfOrder, "#{event} has wrong pick" if event.pick != current_pick + raise EventOutOfOrder, "#{event} has wrong round" if event.round != current_round + raise EventOutOfOrder, "#{event} has wrong round_pick" if event.round_pick != current_round_pick + raise EndOfDraftError, "#{total_picks} pick limit reached" if events.length > total_picks + 1 events << event event end