basketball 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.rubocop.yml +9 -19
 - data/CHANGELOG.md +1 -39
 - data/README.md +75 -93
 - data/basketball.gemspec +3 -6
 - data/exe/{basketball-season-scheduling → basketball-coordinator} +1 -1
 - data/exe/{basketball-draft → basketball-room} +1 -1
 - data/lib/basketball/app/coordinator_cli.rb +250 -0
 - data/lib/basketball/app/coordinator_repository.rb +114 -0
 - data/lib/basketball/app/document_repository.rb +67 -0
 - data/lib/basketball/app/file_store.rb +38 -0
 - data/lib/basketball/app/in_memory_store.rb +42 -0
 - data/lib/basketball/app/league_repository.rb +20 -0
 - data/lib/basketball/app/league_serializable.rb +54 -0
 - data/lib/basketball/{draft/cli.rb → app/room_cli.rb} +74 -80
 - data/lib/basketball/app/room_repository.rb +149 -0
 - data/lib/basketball/app.rb +20 -0
 - data/lib/basketball/draft/assessment.rb +31 -0
 - data/lib/basketball/draft/event.rb +3 -2
 - data/lib/basketball/draft/front_office.rb +35 -28
 - data/lib/basketball/draft/{pick_event.rb → pick.rb} +13 -6
 - data/lib/basketball/draft/room.rb +119 -119
 - data/lib/basketball/draft/{player_search.rb → scout.rb} +4 -9
 - data/lib/basketball/draft/skip.rb +12 -0
 - data/lib/basketball/draft.rb +13 -6
 - data/lib/basketball/entity.rb +19 -10
 - data/lib/basketball/org/league.rb +68 -0
 - data/lib/basketball/org/player.rb +26 -0
 - data/lib/basketball/{draft → org}/position.rb +3 -2
 - data/lib/basketball/org/team.rb +38 -0
 - data/lib/basketball/org.rb +12 -0
 - data/lib/basketball/season/arena.rb +113 -0
 - data/lib/basketball/season/calendar.rb +41 -72
 - data/lib/basketball/season/coordinator.rb +186 -128
 - data/lib/basketball/season/{preseason_game.rb → exhibition.rb} +2 -1
 - data/lib/basketball/season/game.rb +15 -10
 - data/lib/basketball/season/matchup.rb +27 -0
 - data/lib/basketball/season/opponent.rb +15 -0
 - data/lib/basketball/season/{season_game.rb → regular.rb} +2 -1
 - data/lib/basketball/season/result.rb +37 -0
 - data/lib/basketball/season.rb +12 -13
 - data/lib/basketball/value_object.rb +8 -27
 - data/lib/basketball/value_object_dsl.rb +30 -0
 - data/lib/basketball/version.rb +1 -1
 - data/lib/basketball.rb +9 -4
 - metadata +37 -44
 - data/lib/basketball/draft/league.rb +0 -70
 - data/lib/basketball/draft/player.rb +0 -43
 - data/lib/basketball/draft/room_serializer.rb +0 -186
 - data/lib/basketball/draft/roster.rb +0 -37
 - data/lib/basketball/draft/sim_event.rb +0 -23
 - data/lib/basketball/draft/skip_event.rb +0 -13
 - data/lib/basketball/season/calendar_serializer.rb +0 -94
 - data/lib/basketball/season/conference.rb +0 -57
 - data/lib/basketball/season/division.rb +0 -43
 - data/lib/basketball/season/league.rb +0 -114
 - data/lib/basketball/season/league_serializer.rb +0 -99
 - data/lib/basketball/season/scheduling_cli.rb +0 -198
 - data/lib/basketball/season/team.rb +0 -21
 
| 
         @@ -0,0 +1,149 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Basketball
         
     | 
| 
      
 4 
     | 
    
         
            +
              module App
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Can load and save Room objects to JSON files.
         
     | 
| 
      
 6 
     | 
    
         
            +
                class RoomRepository < DocumentRepository
         
     | 
| 
      
 7 
     | 
    
         
            +
                  PICK_EVENT = 'Pick'
         
     | 
| 
      
 8 
     | 
    
         
            +
                  SKIP_EVENT = 'Skip'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  private_constant :PICK_EVENT, :SKIP_EVENT
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  private
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def from_h(hash)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    front_offices = deserialize_front_offices(hash[:front_offices])
         
     | 
| 
      
 16 
     | 
    
         
            +
                    players       = deserialize_players(hash[:players])
         
     | 
| 
      
 17 
     | 
    
         
            +
                    events        = deserialize_events(hash[:events], players:, front_offices:)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    Draft::Room.new(
         
     | 
| 
      
 20 
     | 
    
         
            +
                      rounds: hash[:rounds],
         
     | 
| 
      
 21 
     | 
    
         
            +
                      front_offices:,
         
     | 
| 
      
 22 
     | 
    
         
            +
                      players:,
         
     | 
| 
      
 23 
     | 
    
         
            +
                      events:
         
     | 
| 
      
 24 
     | 
    
         
            +
                    )
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def to_h(room)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    {
         
     | 
| 
      
 29 
     | 
    
         
            +
                      rounds: room.rounds,
         
     | 
| 
      
 30 
     | 
    
         
            +
                      front_offices: room.front_offices.map { |fo| serialize_front_office(fo) },
         
     | 
| 
      
 31 
     | 
    
         
            +
                      players: room.players.map { |p| serialize_player(p) },
         
     | 
| 
      
 32 
     | 
    
         
            +
                      events: serialize_events(room.events)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    }
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  # Serialization
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def serialize_player(player)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    {
         
     | 
| 
      
 40 
     | 
    
         
            +
                      id: player.id,
         
     | 
| 
      
 41 
     | 
    
         
            +
                      overall: player.overall,
         
     | 
| 
      
 42 
     | 
    
         
            +
                      position: player.position&.code
         
     | 
| 
      
 43 
     | 
    
         
            +
                    }
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def serialize_front_office(front_office)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    {
         
     | 
| 
      
 48 
     | 
    
         
            +
                      id: front_office.id,
         
     | 
| 
      
 49 
     | 
    
         
            +
                      risk_level: front_office.risk_level
         
     | 
| 
      
 50 
     | 
    
         
            +
                    }
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def serialize_events(events)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    events.map do |event|
         
     | 
| 
      
 55 
     | 
    
         
            +
                      case event
         
     | 
| 
      
 56 
     | 
    
         
            +
                      when Draft::Pick
         
     | 
| 
      
 57 
     | 
    
         
            +
                        serialize_pick(event)
         
     | 
| 
      
 58 
     | 
    
         
            +
                      when Draft::Skip
         
     | 
| 
      
 59 
     | 
    
         
            +
                        serialize_skip(event)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  def serialize_pick(event)
         
     | 
| 
      
 65 
     | 
    
         
            +
                    {
         
     | 
| 
      
 66 
     | 
    
         
            +
                      type: PICK_EVENT,
         
     | 
| 
      
 67 
     | 
    
         
            +
                      front_office: event.front_office.id,
         
     | 
| 
      
 68 
     | 
    
         
            +
                      pick: event.pick,
         
     | 
| 
      
 69 
     | 
    
         
            +
                      round: event.round,
         
     | 
| 
      
 70 
     | 
    
         
            +
                      round_pick: event.round_pick,
         
     | 
| 
      
 71 
     | 
    
         
            +
                      auto: event.auto,
         
     | 
| 
      
 72 
     | 
    
         
            +
                      player: event.player.id
         
     | 
| 
      
 73 
     | 
    
         
            +
                    }
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  def serialize_skip(event)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    {
         
     | 
| 
      
 78 
     | 
    
         
            +
                      type: SKIP_EVENT,
         
     | 
| 
      
 79 
     | 
    
         
            +
                      front_office: event.front_office.id,
         
     | 
| 
      
 80 
     | 
    
         
            +
                      pick: event.pick,
         
     | 
| 
      
 81 
     | 
    
         
            +
                      round: event.round,
         
     | 
| 
      
 82 
     | 
    
         
            +
                      round_pick: event.round_pick
         
     | 
| 
      
 83 
     | 
    
         
            +
                    }
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  # Deserialization
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  def deserialize_player(player_hash)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    Org::Player.new(
         
     | 
| 
      
 90 
     | 
    
         
            +
                      id: player_hash[:id],
         
     | 
| 
      
 91 
     | 
    
         
            +
                      overall: player_hash[:overall],
         
     | 
| 
      
 92 
     | 
    
         
            +
                      position: Org::Position.new(player_hash[:position])
         
     | 
| 
      
 93 
     | 
    
         
            +
                    )
         
     | 
| 
      
 94 
     | 
    
         
            +
                  end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  def deserialize_front_office(hash)
         
     | 
| 
      
 97 
     | 
    
         
            +
                    Draft::FrontOffice.new(
         
     | 
| 
      
 98 
     | 
    
         
            +
                      id: hash[:id],
         
     | 
| 
      
 99 
     | 
    
         
            +
                      risk_level: hash[:risk_level]
         
     | 
| 
      
 100 
     | 
    
         
            +
                    )
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  def deserialize_front_offices(hashes)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    (hashes || []).map { |fo| deserialize_front_office(fo) }
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                  def deserialize_players(hashes)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    (hashes || []).map { |hash| deserialize_player(hash) }
         
     | 
| 
      
 109 
     | 
    
         
            +
                  end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                  def deserialize_pick(hash, players:, front_office:)
         
     | 
| 
      
 112 
     | 
    
         
            +
                    player_id = hash[:player]
         
     | 
| 
      
 113 
     | 
    
         
            +
                    player    = players.find { |p| p.id == player_id }
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                    Draft::Pick.new(
         
     | 
| 
      
 116 
     | 
    
         
            +
                      front_office:,
         
     | 
| 
      
 117 
     | 
    
         
            +
                      pick: hash[:pick],
         
     | 
| 
      
 118 
     | 
    
         
            +
                      round: hash[:round],
         
     | 
| 
      
 119 
     | 
    
         
            +
                      round_pick: hash[:round_pick],
         
     | 
| 
      
 120 
     | 
    
         
            +
                      player:,
         
     | 
| 
      
 121 
     | 
    
         
            +
                      auto: hash[:auto]
         
     | 
| 
      
 122 
     | 
    
         
            +
                    )
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  def deserialize_skip(hash, front_office:)
         
     | 
| 
      
 126 
     | 
    
         
            +
                    Draft::Skip.new(
         
     | 
| 
      
 127 
     | 
    
         
            +
                      front_office:,
         
     | 
| 
      
 128 
     | 
    
         
            +
                      pick: hash[:pick],
         
     | 
| 
      
 129 
     | 
    
         
            +
                      round: hash[:round],
         
     | 
| 
      
 130 
     | 
    
         
            +
                      round_pick: hash[:round_pick]
         
     | 
| 
      
 131 
     | 
    
         
            +
                    )
         
     | 
| 
      
 132 
     | 
    
         
            +
                  end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                  def deserialize_events(hashes, players:, front_offices:)
         
     | 
| 
      
 135 
     | 
    
         
            +
                    (hashes || []).map do |hash|
         
     | 
| 
      
 136 
     | 
    
         
            +
                      front_office_id = hash[:front_office]
         
     | 
| 
      
 137 
     | 
    
         
            +
                      front_office    = front_offices.find { |fo| fo.id == front_office_id }
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                      case hash[:type]
         
     | 
| 
      
 140 
     | 
    
         
            +
                      when PICK_EVENT
         
     | 
| 
      
 141 
     | 
    
         
            +
                        deserialize_pick(hash, players:, front_office:)
         
     | 
| 
      
 142 
     | 
    
         
            +
                      when SKIP_EVENT
         
     | 
| 
      
 143 
     | 
    
         
            +
                        deserialize_skip(hash, front_office:)
         
     | 
| 
      
 144 
     | 
    
         
            +
                      end
         
     | 
| 
      
 145 
     | 
    
         
            +
                    end
         
     | 
| 
      
 146 
     | 
    
         
            +
                  end
         
     | 
| 
      
 147 
     | 
    
         
            +
                end
         
     | 
| 
      
 148 
     | 
    
         
            +
              end
         
     | 
| 
      
 149 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Stores
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'app/file_store'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'app/in_memory_store'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            # Serialization
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative 'app/league_serializable'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            # Repositories / Common
         
     | 
| 
      
 11 
     | 
    
         
            +
            require_relative 'app/document_repository'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # Repositories / Implementations
         
     | 
| 
      
 14 
     | 
    
         
            +
            require_relative 'app/coordinator_repository'
         
     | 
| 
      
 15 
     | 
    
         
            +
            require_relative 'app/league_repository'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require_relative 'app/room_repository'
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            # Controllers
         
     | 
| 
      
 19 
     | 
    
         
            +
            require_relative 'app/coordinator_cli'
         
     | 
| 
      
 20 
     | 
    
         
            +
            require_relative 'app/room_cli'
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Basketball
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Draft
         
     | 
| 
      
 5 
     | 
    
         
            +
                # An assessment is given to a front office when it needs the front office to make a pick.
         
     | 
| 
      
 6 
     | 
    
         
            +
                # This is essentially just a data-transfer object to get information to a front office to make a pick.
         
     | 
| 
      
 7 
     | 
    
         
            +
                class Assessment
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_reader :drafted_players,
         
     | 
| 
      
 9 
     | 
    
         
            +
                              :pick,
         
     | 
| 
      
 10 
     | 
    
         
            +
                              :round_pick,
         
     | 
| 
      
 11 
     | 
    
         
            +
                              :round,
         
     | 
| 
      
 12 
     | 
    
         
            +
                              :undrafted_players
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def initialize(
         
     | 
| 
      
 15 
     | 
    
         
            +
                    drafted_players:,
         
     | 
| 
      
 16 
     | 
    
         
            +
                    pick:,
         
     | 
| 
      
 17 
     | 
    
         
            +
                    round_pick:,
         
     | 
| 
      
 18 
     | 
    
         
            +
                    round:,
         
     | 
| 
      
 19 
     | 
    
         
            +
                    undrafted_players:
         
     | 
| 
      
 20 
     | 
    
         
            +
                  )
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @drafted_players   = drafted_players
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @pick              = pick
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @round             = round
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @round_pick        = round_pick
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @undrafted_players = undrafted_players
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    freeze
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -2,8 +2,9 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Basketball
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Draft
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Describes what all Room events have to have to be considered an "event".
         
     | 
| 
       5 
6 
     | 
    
         
             
                class Event < ValueObject
         
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
      
 7 
     | 
    
         
            +
                  value_reader :pick, :round, :round_pick, :front_office
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
                  def initialize(front_office:, pick:, round:, round_pick:)
         
     | 
| 
       9 
10 
     | 
    
         
             
                    super()
         
     | 
| 
         @@ -17,7 +18,7 @@ module Basketball 
     | 
|
| 
       17 
18 
     | 
    
         
             
                  end
         
     | 
| 
       18 
19 
     | 
    
         | 
| 
       19 
20 
     | 
    
         
             
                  def to_s
         
     | 
| 
       20 
     | 
    
         
            -
                    "##{pick}  
     | 
| 
      
 21 
     | 
    
         
            +
                    "[##{pick} R:#{round} P:#{round_pick}] #{front_office}"
         
     | 
| 
       21 
22 
     | 
    
         
             
                  end
         
     | 
| 
       22 
23 
     | 
    
         
             
                end
         
     | 
| 
       23 
24 
     | 
    
         
             
              end
         
     | 
| 
         @@ -2,22 +2,34 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Basketball
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Draft
         
     | 
| 
      
 5 
     | 
    
         
            +
                # A team will send their front office to a draft room to make draft selections.
         
     | 
| 
       5 
6 
     | 
    
         
             
                class FrontOffice < Entity
         
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
       7 
     | 
    
         
            -
                   
     | 
| 
      
 7 
     | 
    
         
            +
                  # The higher the number the more the front office will make more top-player-based decisions
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # over position-based decisions.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  DEFAULT_MAX_STAR_LEVEL = 5
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  # Riskier front offices may choose to not draft the top player.  The higher the number the more
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # they will not select the top player available.
         
     | 
| 
      
 13 
     | 
    
         
            +
                  DEFAULT_MAX_RISK_LEVEL = 5
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       8 
15 
     | 
    
         
             
                  MAX_POSITIONS = 12
         
     | 
| 
       9 
16 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                  private_constant : 
     | 
| 
      
 17 
     | 
    
         
            +
                  private_constant :DEFAULT_MAX_STAR_LEVEL, :DEFAULT_MAX_RISK_LEVEL, :MAX_POSITIONS
         
     | 
| 
       11 
18 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                  attr_reader :prioritized_positions, : 
     | 
| 
      
 19 
     | 
    
         
            +
                  attr_reader :prioritized_positions, :risk_level, :star_level, :scout
         
     | 
| 
       13 
20 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                  def initialize( 
     | 
| 
      
 21 
     | 
    
         
            +
                  def initialize(
         
     | 
| 
      
 22 
     | 
    
         
            +
                    id:,
         
     | 
| 
      
 23 
     | 
    
         
            +
                    prioritized_positions: [],
         
     | 
| 
      
 24 
     | 
    
         
            +
                    risk_level: rand(0..DEFAULT_MAX_RISK_LEVEL),
         
     | 
| 
      
 25 
     | 
    
         
            +
                    star_level: rand(0..DEFAULT_MAX_STAR_LEVEL)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  )
         
     | 
| 
       15 
27 
     | 
    
         
             
                    super(id)
         
     | 
| 
       16 
28 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                    @ 
     | 
| 
       18 
     | 
    
         
            -
                    @ 
     | 
| 
       19 
     | 
    
         
            -
                    @depth                 = depth.to_i
         
     | 
| 
      
 29 
     | 
    
         
            +
                    @risk_level            = risk_level.to_i
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @star_level            = star_level.to_i
         
     | 
| 
       20 
31 
     | 
    
         
             
                    @prioritized_positions = prioritized_positions
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @scout                 = Scout.new
         
     | 
| 
       21 
33 
     | 
    
         | 
| 
       22 
34 
     | 
    
         
             
                    # fill in the rest of the queue here
         
     | 
| 
       23 
35 
     | 
    
         
             
                    need_count = MAX_POSITIONS - @prioritized_positions.length
         
     | 
| 
         @@ -27,51 +39,46 @@ module Basketball 
     | 
|
| 
       27 
39 
     | 
    
         
             
                    freeze
         
     | 
| 
       28 
40 
     | 
    
         
             
                  end
         
     | 
| 
       29 
41 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                  def pick( 
     | 
| 
      
 42 
     | 
    
         
            +
                  def pick(assessment)
         
     | 
| 
       31 
43 
     | 
    
         
             
                    players = []
         
     | 
| 
      
 44 
     | 
    
         
            +
                    players = adaptive_search(assessment) if star_level >= assessment.round
         
     | 
| 
      
 45 
     | 
    
         
            +
                    players = balanced_search(assessment) if players.empty?
         
     | 
| 
      
 46 
     | 
    
         
            +
                    players = top_players(assessment)     if players.empty?
         
     | 
| 
       32 
47 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                    players 
     | 
| 
       34 
     | 
    
         
            -
                    players = balanced_search(undrafted_player_search:, drafted_players:) if players.empty?
         
     | 
| 
       35 
     | 
    
         
            -
                    players = top_players(undrafted_player_search:)                       if players.empty?
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                    players[0..fuzz].sample
         
     | 
| 
       38 
     | 
    
         
            -
                  end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                  def to_s
         
     | 
| 
       41 
     | 
    
         
            -
                    "[#{super}] #{name}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                    players[0..risk_level].sample
         
     | 
| 
       42 
49 
     | 
    
         
             
                  end
         
     | 
| 
       43 
50 
     | 
    
         | 
| 
       44 
51 
     | 
    
         
             
                  private
         
     | 
| 
       45 
52 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
                  def adaptive_search( 
     | 
| 
       47 
     | 
    
         
            -
                    drafted_positions = drafted_players.map(&:position)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  def adaptive_search(assessment)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    drafted_positions = assessment.drafted_players.map(&:position)
         
     | 
| 
       48 
55 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                     
     | 
| 
      
 56 
     | 
    
         
            +
                    scout.top_for(players: assessment.undrafted_players, exclude_positions: drafted_positions)
         
     | 
| 
       50 
57 
     | 
    
         
             
                  end
         
     | 
| 
       51 
58 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                  def balanced_search( 
     | 
| 
      
 59 
     | 
    
         
            +
                  def balanced_search(assessment)
         
     | 
| 
       53 
60 
     | 
    
         
             
                    players = []
         
     | 
| 
       54 
61 
     | 
    
         | 
| 
       55 
62 
     | 
    
         
             
                    # Try to find best pick for exact desired position.
         
     | 
| 
       56 
63 
     | 
    
         
             
                    # If you cant find one, then move to the next desired position until the end of the queue
         
     | 
| 
       57 
     | 
    
         
            -
                    available_prioritized_positions(drafted_players 
     | 
| 
       58 
     | 
    
         
            -
                      players =  
     | 
| 
      
 64 
     | 
    
         
            +
                    available_prioritized_positions(assessment.drafted_players).each do |position|
         
     | 
| 
      
 65 
     | 
    
         
            +
                      players = scout.top_for(players: assessment.undrafted_players, position:)
         
     | 
| 
       59 
66 
     | 
    
         | 
| 
       60 
67 
     | 
    
         
             
                      break if players.any?
         
     | 
| 
       61 
68 
     | 
    
         
             
                    end
         
     | 
| 
       62 
69 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                    players = players.any? ? players :  
     | 
| 
      
 70 
     | 
    
         
            +
                    players = players.any? ? players : scout.top_for
         
     | 
| 
       64 
71 
     | 
    
         
             
                  end
         
     | 
| 
       65 
72 
     | 
    
         | 
| 
       66 
73 
     | 
    
         
             
                  def all_random_positions
         
     | 
| 
       67 
     | 
    
         
            -
                    Position::ALL_VALUES.to_a.shuffle.map { |v| Position.new(v) }
         
     | 
| 
      
 74 
     | 
    
         
            +
                    Org::Position::ALL_VALUES.to_a.shuffle.map { |v| Org::Position.new(v) }
         
     | 
| 
       68 
75 
     | 
    
         
             
                  end
         
     | 
| 
       69 
76 
     | 
    
         | 
| 
       70 
77 
     | 
    
         
             
                  def random_positions_queue
         
     | 
| 
       71 
     | 
    
         
            -
                    all_random_positions + all_random_positions + [Position.random] + [Position.random]
         
     | 
| 
      
 78 
     | 
    
         
            +
                    all_random_positions + all_random_positions + [Org::Position.random] + [Org::Position.random]
         
     | 
| 
       72 
79 
     | 
    
         
             
                  end
         
     | 
| 
       73 
80 
     | 
    
         | 
| 
       74 
     | 
    
         
            -
                  def available_prioritized_positions(drafted_players 
     | 
| 
      
 81 
     | 
    
         
            +
                  def available_prioritized_positions(drafted_players)
         
     | 
| 
       75 
82 
     | 
    
         
             
                    drafted_positions = drafted_players.map(&:position)
         
     | 
| 
       76 
83 
     | 
    
         
             
                    queue             = prioritized_positions.dup
         
     | 
| 
       77 
84 
     | 
    
         | 
| 
         @@ -1,25 +1,32 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require_relative 'event'
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
3 
     | 
    
         
             
            module Basketball
         
     | 
| 
       6 
4 
     | 
    
         
             
              module Draft
         
     | 
| 
       7 
     | 
    
         
            -
                 
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
                # Room event where a player is selected.
         
     | 
| 
      
 6 
     | 
    
         
            +
                class Pick < Event
         
     | 
| 
      
 7 
     | 
    
         
            +
                  value_reader :player, :auto
         
     | 
| 
       9 
8 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                  def initialize(front_office:, player:, pick:, round:, round_pick:)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(front_office:, player:, pick:, round:, round_pick:, auto: false)
         
     | 
| 
       11 
10 
     | 
    
         
             
                    super(front_office:, pick:, round:, round_pick:)
         
     | 
| 
       12 
11 
     | 
    
         | 
| 
       13 
12 
     | 
    
         
             
                    raise ArgumentError, 'player required' unless player
         
     | 
| 
       14 
13 
     | 
    
         | 
| 
       15 
14 
     | 
    
         
             
                    @player = player
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @auto   = auto
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                    freeze
         
     | 
| 
       18 
18 
     | 
    
         
             
                  end
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                  def to_s
         
     | 
| 
       21 
     | 
    
         
            -
                    "#{ 
     | 
| 
      
 21 
     | 
    
         
            +
                    "#{super} #{auto ? 'auto-' : ''}picked #{player}"
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  def ==(other)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    super &&
         
     | 
| 
      
 26 
     | 
    
         
            +
                      player == other.player &&
         
     | 
| 
      
 27 
     | 
    
         
            +
                      auto == other.auto
         
     | 
| 
       22 
28 
     | 
    
         
             
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                  alias eql? ==
         
     | 
| 
       23 
30 
     | 
    
         
             
                end
         
     | 
| 
       24 
31 
     | 
    
         
             
              end
         
     | 
| 
       25 
32 
     | 
    
         
             
            end
         
     |