basketball 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 793bfe7afef52aa72d3f89c94541fc7d8f24b350d63cb7c75d7215c285695b74
4
- data.tar.gz: 46a3ac7199fb534ff4827c8fe48bbe371c7f87bc623e579ffdce2310132a1263
3
+ metadata.gz: 00ac0278bb2e786c5a68b3cc7ac8fd5d49005f9f9a01fad32501c75a00880dce
4
+ data.tar.gz: 4b76f9d42a702a206c837346de20396c6948c9bcb071a4143610e8179ba93c64
5
5
  SHA512:
6
- metadata.gz: cf8c46719f3669a31c932d7dc2742c287666fcb305c90c596c87b79c37d4fb95aafa446c70575ed4d8d3750a3f3672646e9ee49c6a0cf95e4dd7eb092831670e
7
- data.tar.gz: db01d3bfc4a8c1448875c5a099d0a33fd60ad60471ae5cda5f9eeeaf8a1fb2daa3e52d5ca2d8138867e42aaf6f54d259cdad7d3628cfbaa2d7bcf134fe5dc4b9
6
+ metadata.gz: 806f800744de18f81e590cd712adf83592e372b8f1b19c3b8f9a6e702c7fbc04981380ba784b63436f2cc34d5f80238c0fce53366eed8a2a8a63eb9b64cb69c4
7
+ data.tar.gz: acffa65b0315e7d5ec6638cd92c217e9aa665787114935d0859a4b6b02cfb0c8afd6e66d7914de6b147d6878d83ca210b2d5f5bfbdeb748784f559300fe79d46
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ #### 0.0.7 - May 14th, 2023
2
+
3
+ * Added #to_hash and #from_hash serializer methods to allow larger consumer json constructions more directly.
4
+ * Opt for string keys during serialization/deserialization.
5
+
6
+ #### 0.0.6 - May 11th, 2023
7
+
8
+ * Added Scheduling module that can generate full schedules for entire league.
9
+ * Drafting::Event does not have identity anymore (no current tangible benefit).
10
+
1
11
  #### 0.0.5 - May 5th, 2023
2
12
 
3
13
  * Remove the notion of Team in favor of a flat front office.
data/Gemfile CHANGED
@@ -3,3 +3,14 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
+
7
+ gem 'bundler-audit', '~>0.9'
8
+ gem 'guard-rspec', '~>4.7'
9
+ gem 'pry', '~>0.14'
10
+ gem 'rake', '~>13.0'
11
+ gem 'rspec', '~>3.12'
12
+ gem 'rubocop', '~>1.49'
13
+ gem 'rubocop-rake', '~>0.6'
14
+ gem 'rubocop-rspec', '~>2.20'
15
+ gem 'simplecov', '~>0.22'
16
+ gem 'simplecov-console', '~>0.9'
data/README.md CHANGED
@@ -30,13 +30,17 @@ bundle binstubs basketball
30
30
 
31
31
  This library is broken down into several bounded contexts that can be consumed either via its Ruby API's or CLI through provided executable scripts:
32
32
 
33
- ![Basketball Architecture - Overview.png](/docs/architecture/overview.png)
33
+ ![Basketball Architecture - Overview](/docs/architecture/overview.png)
34
+
35
+ #### Command Line Interfaces
36
+
37
+ Each module is meant to be interfaced with using its Ruby API by consuming applications. Each module also ships with a CLI script (backed by a module service) which a user can interact with to emulate different portions of the league management process. Technically speaking, the CLI provides an example application built on top of the each individual core module. Each module section below should contain with it example CLI calls.
34
38
 
35
39
  ## Drafting Module
36
40
 
37
41
  The drafting module is responsible for providing a turn-based iterator allowing the consumer to either manually pick or simulate picks. Here is a cartoon showing the major components:
38
42
 
39
- ![Basketball Architecture - Drafting.png](/docs/architecture/drafting.png)
43
+ ![Basketball Architecture - Drafting](/docs/architecture/drafting.png)
40
44
 
41
45
  Element | Description
42
46
  :------------ | :-----------
@@ -47,70 +51,147 @@ Element | Description
47
51
  **Front Office** | Identifiable as a team, contains configuration for how to auto-pick draft selections.
48
52
  **League** | Set of rosters that together form a cohesive league.
49
53
  **Pick Event** | Result event emitted when a player is manually selected.
50
- **Playe ** | Identitiable as a person able to be drafted.
54
+ **Player** | Identitiable as a person able to be drafted.
51
55
  **Position** | Value object based on position code: PG, SG, SF, PF, and C.
52
56
  **Roster** | Identifiable as a team, set of players that make up a single team.
53
57
  **Sim Event** | Result event emitted when a player is automatically selected by a front office.
54
58
  **Skip Event** | Result event emitted when a front office decides to skip a round.
55
59
 
56
- ### The Drafting CLI
60
+ #### The Drafting CLI
57
61
 
58
- The drafting module is meant to be interfaces using its Ruby API by consuming applications. It also ships with a CLI which a user can interact with to emulate "the draft process". Technically speaking, the CLI provides an example application built on top of the Drafting module. Each time a CLI command is executed, its results will be resaved, so the output file can then be used as the next command's input file to string together commands. The following sections are example CLI interactions:
62
+ The drafting module's main object: `Basketball::Drafting::Engine` is a stateful iterator. Each time a CLI command is executed, it's results will be re-saved to disk so the output file can then be used as the next command's input file to string together commands.
59
63
 
60
- #### Generate a Fresh Draft
64
+ ###### Generate a Fresh Draft
61
65
 
62
66
  ```zsh
63
67
  basketball-draft -o tmp/draft.json
64
68
  ```
65
69
 
66
- #### N Top Available Players
70
+ ###### N Top Available Players
67
71
 
68
72
  ```zsh
69
73
  basketball-draft -i tmp/draft.json -t 10
70
74
  ```
71
75
 
72
- #### N Top Available Players for a Position
76
+ ###### N Top Available Players for a Position
73
77
 
74
78
  ```zsh
75
79
  basketball-draft -i tmp/draft.json -t 10 -q PG
76
80
  ```
77
81
 
78
- #### Output Current Rosters
82
+ ###### Output Current Rosters
79
83
 
80
84
  ```zsh
81
85
  basketball-draft -i tmp/draft.json -r
82
86
  ```
83
87
 
84
- #### Output Event Log
88
+ ###### Output Event Log
85
89
 
86
90
  ```zsh
87
91
  basketball-draft -i tmp/draft.json -l
88
92
  ```
89
93
 
90
- #### Simulate N picks
94
+ ###### Simulate N Picks
91
95
 
92
96
  ```zsh
93
97
  basketball-draft -i tmp/draft.json -s 10
94
98
  ```
95
99
 
96
- #### Skip N picks
100
+ ###### Skip N Picks
97
101
 
98
102
  ```zsh
99
103
  basketball-draft -i tmp/draft.json -x 10
100
104
  ```
101
105
 
102
- #### Pick Players
106
+ ###### Pick Players
103
107
 
104
108
  ```zsh
105
109
  basketball-draft -i tmp/draft.json -p P-100,P-200,P-300
106
110
  ```
107
111
 
108
- #### Simulate the Rest of the Draft
112
+ ###### Simulate the Rest of the Draft
109
113
 
110
114
  ```zsh
111
115
  basketball-draft -i tmp/draft.json -a
112
116
  ```
113
117
 
118
+ ###### Help Menu
119
+
120
+ ```zsh
121
+ basketball-draft -h
122
+ ```
123
+
124
+ ## Scheduling Module
125
+
126
+ The Scheduling module is meant to take a League (conferences/divisions/teams) and turn it into a Calendar. This Calendar creation is atomic - the full calendar will be generated completely all in one call. Here is a cartoon showing the major components:
127
+
128
+ ![Basketball Architecture - Scheduling](/docs/architecture/scheduling.png)
129
+
130
+ Element | Description
131
+ :------------ | :-----------
132
+ **Away Team** | Team object designated as the away team for a Game.
133
+ **Calendar Serializer** | Understands how to serialize and deserialize a Calendar object.
134
+ **Calendar** | Hold a calendar for a year season. Pass in a year and the Calendar will know how to mark important boundary dates (preseason start, preseason end, season start, and season end) and it knows how to ensure Calendar correctness regarding dates.
135
+ **Conference** | Describes a conference in terms of structure; composed of an array of divisions (there can only 3).
136
+ **Coordinator** | Service which can generate a Calendar from a League.
137
+ **Division** | Describes a division in terms of structure; composed of an array of teams (there can only 5).
138
+ **Game** | Matches up a date with two teams (home and away) to represent a scheduled matchup.
139
+ **Home Team** | Team object designated as the home team for a Game.
140
+ **League Serializer** | Understands how to serialize and deserialize a League object.
141
+ **League** | Describes a league in terms of structure; composed of an array conferences (there can only be 2).
142
+ **Scheduling** | Bounded context (sub-module) dealing with matchup and calendar generation.
143
+ **Team** | Identified by an ID and described by a name: represents a basketball team that can be scheduled.
144
+
145
+ #### The Scheduling CLI
146
+
147
+ ###### Generate League
148
+
149
+ ```zsh
150
+ basketball-schedule -o tmp/league.json
151
+ ```
152
+
153
+ ###### Generate Calendar From League
154
+
155
+ ```zsh
156
+ basketball-schedule -i tmp/league.json -o tmp/calendar.json
157
+ ```
158
+
159
+ ###### Generate Calendar From League For a Specific Year
160
+
161
+ ```zsh
162
+ basketball-schedule -i tmp/league.json -o tmp/calendar.json -y 2005
163
+ ```
164
+
165
+ ###### Output a Generated Calendar's Matchups
166
+
167
+ ```zsh
168
+ basketball-schedule -c tmp/calendar.json
169
+ ```
170
+
171
+ ###### Output a Generated Calendar's Matchups For a Specific Team
172
+
173
+ ```zsh
174
+ basketball-schedule -c tmp/calendar.json -t C0-D0-T0
175
+ ```
176
+
177
+ ###### Output a Generated Calendar's Matchups For a Specific Date
178
+
179
+ ```zsh
180
+ basketball-schedule -c tmp/calendar.json -d 2005-02-03
181
+ ```
182
+
183
+ ###### Output a Generated Calendar's Matchups For a Specific Team and Date
184
+
185
+ ```zsh
186
+ basketball-schedule -c tmp/calendar.json -d 2005-02-03 -t C0-D0-T0
187
+ ```
188
+
189
+ ###### Help Menu
190
+
191
+ ```zsh
192
+ basketball-schedule -h
193
+ ```
194
+
114
195
  ## Contributing
115
196
 
116
197
  ### Development Environment Configuration
data/basketball.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.email = ['mattruggio@icloud.com']
18
18
  s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(.github|bin|docs|spec)/}) }
19
19
  s.bindir = 'exe'
20
- s.executables = %w[basketball-draft]
20
+ s.executables = %w[basketball-draft basketball-schedule]
21
21
  s.homepage = 'https://github.com/mattruggio/basketball'
22
22
  s.license = 'MIT'
23
23
  s.metadata = {
@@ -33,15 +33,4 @@ Gem::Specification.new do |s|
33
33
 
34
34
  s.add_dependency('faker', '~>3.2')
35
35
  s.add_dependency('slop', '~>4.10')
36
-
37
- s.add_development_dependency('bundler-audit', '~>0.9')
38
- s.add_development_dependency('guard-rspec', '~>4.7')
39
- s.add_development_dependency('pry', '~>0.14')
40
- s.add_development_dependency('rake', '~>13.0')
41
- s.add_development_dependency('rspec', '~>3.12')
42
- s.add_development_dependency('rubocop', '~>1.49')
43
- s.add_development_dependency('rubocop-rake', '~>0.6')
44
- s.add_development_dependency('rubocop-rspec', '~>2.20')
45
- s.add_development_dependency('simplecov', '~>0.22')
46
- s.add_development_dependency('simplecov-console', '~>0.9')
47
36
  end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'basketball'
6
+
7
+ Basketball::Scheduling::CLI.new(args: ARGV).invoke!
@@ -7,7 +7,7 @@ require_relative 'position'
7
7
 
8
8
  module Basketball
9
9
  module Drafting
10
- # Example:
10
+ # Examples:
11
11
  # exe/basketball-draft -o tmp/draft.json
12
12
  # exe/basketball-draft -i tmp/draft.json -o tmp/draft-wip.json -s 26 -p P-5,P-10 -t 10 -q PG
13
13
  # exe/basketball-draft -i tmp/draft-wip.json -x 2
@@ -69,7 +69,7 @@ module Basketball
69
69
 
70
70
  def slop_parse(args)
71
71
  Slop.parse(args) do |o|
72
- o.banner = 'Usage: draft [options] ...'
72
+ o.banner = 'Usage: basketball-draft [options] ...'
73
73
 
74
74
  o.string '-i', '--input',
75
75
  'Path to load the engine from. If omitted then a new draft will be generated.'
@@ -100,7 +100,6 @@ module Basketball
100
100
  return if done?
101
101
 
102
102
  event = SkipEvent.new(
103
- id: SecureRandom.uuid,
104
103
  front_office: current_front_office,
105
104
  pick: current_pick,
106
105
  round: current_round,
@@ -126,7 +125,6 @@ module Basketball
126
125
  )
127
126
 
128
127
  event = SimEvent.new(
129
- id: SecureRandom.uuid,
130
128
  front_office:,
131
129
  player:,
132
130
  pick: current_pick,
@@ -149,7 +147,6 @@ module Basketball
149
147
  return nil if done?
150
148
 
151
149
  event = PickEvent.new(
152
- id: SecureRandom.uuid,
153
150
  front_office: current_front_office,
154
151
  player:,
155
152
  pick: current_pick,
@@ -206,11 +203,11 @@ module Basketball
206
203
 
207
204
  raise UnknownFrontOfficeError, "#{front_office} doesnt exist" unless front_offices.include?(event.front_office)
208
205
 
209
- raise DupeEventError, "#{event} is a dupe" if events.include?(event)
210
- raise EventOutOfOrder, "#{event} has wrong pick" if event.pick != current_pick
211
- raise EventOutOfOrder, "#{event} has wrong round" if event.round != current_round
212
- raise EventOutOfOrder, "#{event} has wrong round_pick" if event.round_pick != current_round_pick
213
- raise EndOfDraftError, "#{total_picks} pick limit reached" if events.length > total_picks + 1
206
+ raise DupeEventError, "#{event} is a dupe" if events.include?(event)
207
+ raise EventOutOfOrder, "#{event} has wrong pick" if event.pick != current_pick
208
+ raise EventOutOfOrder, "#{event} has wrong round" if event.round != current_round
209
+ raise EventOutOfOrder, "#{event} has wrong round_pick" if event.round_pick != current_round_pick
210
+ raise EndOfDraftError, "#{total_picks} pick limit reached" if events.length > total_picks + 1
214
211
 
215
212
  events << event
216
213
 
@@ -17,8 +17,15 @@ module Basketball
17
17
 
18
18
  private_constant :EVENT_CLASSES
19
19
 
20
- def deserialize(string)
21
- json = JSON.parse(string, symbolize_names: true)
20
+ def to_hash(engine)
21
+ {
22
+ 'info' => serialize_info(engine),
23
+ 'engine' => serialize_engine(engine),
24
+ 'league' => serialize_league(engine)
25
+ }
26
+ end
27
+
28
+ def from_hash(json)
22
29
  front_offices = deserialize_front_offices(json)
23
30
  players = deserialize_players(json)
24
31
  events = deserialize_events(json, players, front_offices)
@@ -29,39 +36,41 @@ module Basketball
29
36
  events:
30
37
  }
31
38
 
32
- engine_opts[:rounds] = json.dig(:engine, :rounds) if json.dig(:engine, :rounds)
39
+ engine_opts[:rounds] = json.dig('engine', 'rounds') if json.dig('engine', 'rounds')
33
40
 
34
41
  Engine.new(**engine_opts)
35
42
  end
36
43
 
44
+ def deserialize(string)
45
+ json = JSON.parse(string)
46
+
47
+ from_hash(json)
48
+ end
49
+
37
50
  def serialize(engine)
38
- {
39
- info: serialize_info(engine),
40
- engine: serialize_engine(engine),
41
- league: serialize_league(engine)
42
- }.to_json
51
+ to_hash(engine).to_json
43
52
  end
44
53
 
45
54
  private
46
55
 
47
56
  def serialize_engine(engine)
48
57
  {
49
- rounds: engine.rounds,
50
- front_offices: serialize_front_offices(engine),
51
- players: serialize_players(engine),
52
- events: serialize_events(engine.events)
58
+ 'rounds' => engine.rounds,
59
+ 'front_offices' => serialize_front_offices(engine),
60
+ 'players' => serialize_players(engine),
61
+ 'events' => serialize_events(engine.events)
53
62
  }
54
63
  end
55
64
 
56
65
  def serialize_info(engine)
57
66
  {
58
- total_picks: engine.total_picks,
59
- current_round: engine.current_round,
60
- current_round_pick: engine.current_round_pick,
61
- current_front_office: engine.current_front_office&.id,
62
- current_pick: engine.current_pick,
63
- remaining_picks: engine.remaining_picks,
64
- done: engine.done?
67
+ 'total_picks' => engine.total_picks,
68
+ 'current_round' => engine.current_round,
69
+ 'current_round_pick' => engine.current_round_pick,
70
+ 'current_front_office' => engine.current_front_office&.id,
71
+ 'current_pick' => engine.current_pick,
72
+ 'remaining_picks' => engine.remaining_picks,
73
+ 'done' => engine.done?
65
74
  }
66
75
  end
67
76
 
@@ -72,14 +81,14 @@ module Basketball
72
81
  [
73
82
  roster.id,
74
83
  {
75
- players: roster.players.map(&:id)
84
+ 'players' => roster.players.map(&:id)
76
85
  }
77
86
  ]
78
87
  end
79
88
 
80
89
  {
81
- free_agents: league.free_agents.map(&:id),
82
- rosters:
90
+ 'free_agents' => league.free_agents.map(&:id),
91
+ 'rosters' => rosters
83
92
  }
84
93
  end
85
94
 
@@ -88,10 +97,10 @@ module Basketball
88
97
  [
89
98
  front_office.id,
90
99
  {
91
- name: front_office.name,
92
- fuzz: front_office.fuzz,
93
- depth: front_office.depth,
94
- prioritized_positions: front_office.prioritized_positions.map(&:code)
100
+ 'name' => front_office.name,
101
+ 'fuzz' => front_office.fuzz,
102
+ 'depth' => front_office.depth,
103
+ 'prioritized_positions' => front_office.prioritized_positions.map(&:code)
95
104
  }
96
105
  ]
97
106
  end
@@ -102,10 +111,10 @@ module Basketball
102
111
  [
103
112
  player.id,
104
113
  {
105
- first_name: player.first_name,
106
- last_name: player.last_name,
107
- overall: player.overall,
108
- position: player.position.code
114
+ 'first_name' => player.first_name,
115
+ 'last_name' => player.last_name,
116
+ 'overall' => player.overall,
117
+ 'position' => player.position.code
109
118
  }
110
119
  ]
111
120
  end
@@ -114,30 +123,29 @@ module Basketball
114
123
  def serialize_events(events)
115
124
  events.map do |event|
116
125
  {
117
- type: event.class.name.split('::').last,
118
- id: event.id,
119
- front_office: event.front_office.id,
120
- pick: event.pick,
121
- round: event.round,
122
- round_pick: event.round_pick
126
+ 'type' => event.class.name.split('::').last,
127
+ 'front_office' => event.front_office.id,
128
+ 'pick' => event.pick,
129
+ 'round' => event.round,
130
+ 'round_pick' => event.round_pick
123
131
  }.tap do |hash|
124
- hash[:player] = event.player.id if event.respond_to?(:player)
132
+ hash['player'] = event.player.id if event.respond_to?(:player)
125
133
  end
126
134
  end
127
135
  end
128
136
 
129
137
  def deserialize_front_offices(json)
130
- (json.dig(:engine, :front_offices) || []).map do |id, front_office_hash|
131
- prioritized_positions = (front_office_hash[:prioritized_positions] || []).map do |v|
138
+ (json.dig('engine', 'front_offices') || []).map do |id, front_office_hash|
139
+ prioritized_positions = (front_office_hash['prioritized_positions'] || []).map do |v|
132
140
  Position.new(v)
133
141
  end
134
142
 
135
143
  front_office_opts = {
136
144
  id:,
137
- name: front_office_hash[:name],
145
+ name: front_office_hash['name'],
138
146
  prioritized_positions:,
139
- fuzz: front_office_hash[:fuzz],
140
- depth: front_office_hash[:depth]
147
+ fuzz: front_office_hash['fuzz'],
148
+ depth: front_office_hash['depth']
141
149
  }
142
150
 
143
151
  FrontOffice.new(**front_office_opts)
@@ -145,26 +153,29 @@ module Basketball
145
153
  end
146
154
 
147
155
  def deserialize_players(json)
148
- (json.dig(:engine, :players) || []).map do |id, player_hash|
149
- player_opts = player_hash.merge(
156
+ (json.dig('engine', 'players') || []).map do |id, player_hash|
157
+ player_opts = {
150
158
  id:,
151
- position: Position.new(player_hash[:position])
152
- )
159
+ first_name: player_hash['first_name'],
160
+ last_name: player_hash['last_name'],
161
+ overall: player_hash['overall'],
162
+ position: Position.new(player_hash['position'])
163
+ }
153
164
 
154
165
  Player.new(**player_opts)
155
166
  end
156
167
  end
157
168
 
158
169
  def deserialize_events(json, players, front_offices)
159
- (json.dig(:engine, :events) || []).map do |event_hash|
160
- event_opts = event_hash.slice(:id, :pick, :round, :round_pick).merge(
161
- front_office: front_offices.find { |t| t.id == event_hash[:front_office] }
170
+ (json.dig('engine', 'events') || []).map do |event_hash|
171
+ event_opts = event_hash.slice('pick', 'round', 'round_pick').merge(
172
+ front_office: front_offices.find { |t| t.id == event_hash['front_office'] }
162
173
  )
163
174
 
164
- class_constant = EVENT_CLASSES.fetch(event_hash[:type])
175
+ class_constant = EVENT_CLASSES.fetch(event_hash['type'])
165
176
 
166
177
  if [PickEvent, SimEvent].include?(class_constant)
167
- event_opts[:player] = players.find { |p| p.id == event_hash[:player] }
178
+ event_opts[:player] = players.find { |p| p.id == event_hash['player'] }
168
179
  end
169
180
 
170
181
  class_constant.new(**event_opts)
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Basketball
4
4
  module Drafting
5
- class Event < Entity
6
- attr_reader :pick, :round, :round_pick, :front_office
5
+ class Event < ValueObject
6
+ attr_reader_value :pick, :round, :round_pick, :front_office
7
7
 
8
- def initialize(id:, front_office:, pick:, round:, round_pick:)
9
- super(id)
8
+ def initialize(front_office:, pick:, round:, round_pick:)
9
+ super()
10
10
 
11
11
  raise ArgumentError, 'front_office required' unless front_office
12
12
 
@@ -5,7 +5,6 @@ require_relative 'roster'
5
5
  module Basketball
6
6
  module Drafting
7
7
  class League
8
- class PlayerAlreadyRegisteredError < StandardError; end
9
8
  class RosterNotFoundError < StandardError; end
10
9
  class RosterAlreadyAddedError < StandardError; end
11
10
 
@@ -5,10 +5,10 @@ require_relative 'event'
5
5
  module Basketball
6
6
  module Drafting
7
7
  class PickEvent < Event
8
- attr_reader :player
8
+ attr_reader_value :player
9
9
 
10
- def initialize(id:, front_office:, player:, pick:, round:, round_pick:)
11
- super(id:, front_office:, pick:, round:, round_pick:)
10
+ def initialize(front_office:, player:, pick:, round:, round_pick:)
11
+ super(front_office:, pick:, round:, round_pick:)
12
12
 
13
13
  raise ArgumentError, 'player required' unless player
14
14
 
@@ -3,7 +3,6 @@
3
3
  module Basketball
4
4
  module Drafting
5
5
  class Roster < Entity
6
- class PlayerAlreadyRegisteredError < StandardError; end
7
6
  class PlayerRequiredError < StandardError; end
8
7
 
9
8
  attr_reader :name, :players
@@ -3,10 +3,10 @@
3
3
  module Basketball
4
4
  module Drafting
5
5
  class SimEvent < Event
6
- attr_reader :player
6
+ attr_reader_value :player
7
7
 
8
- def initialize(id:, front_office:, player:, pick:, round:, round_pick:)
9
- super(id:, front_office:, pick:, round:, round_pick:)
8
+ def initialize(front_office:, player:, pick:, round:, round_pick:)
9
+ super(front_office:, pick:, round:, round_pick:)
10
10
 
11
11
  raise ArgumentError, 'player required' unless player
12
12
 
@@ -1,3 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'drafting/cli'
4
+
5
+ module Basketball
6
+ module Drafting
7
+ class PlayerAlreadyRegisteredError < StandardError; end
8
+ end
9
+ end