basketball 0.0.17 → 0.0.18

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f2c7326c8bfa26bcedb1ccbedec191db4681bed0831d5f37bb7691782a12ae4
4
- data.tar.gz: c22558bd6733383f7926ee33506b86eb9bb8f4fa0807d8eb246d8a8b2912041b
3
+ metadata.gz: afad5b6023e9b0baf1dc11fe6874d4cc46430c1698aa4e97bf5dc2df8cbb314e
4
+ data.tar.gz: f98bb161b770d7148c4fb271ab1b58b2347cfe7b85f94acf1fb6332a4517e61b
5
5
  SHA512:
6
- metadata.gz: f04c5f0691974ae8750d3e66eaf2be925b792b771201ee727313e3f678ca7712f2f5e22878486a682cf17c0a31cac3f38428e5a1eae7337a5b0b7929596cbc22
7
- data.tar.gz: 1b6a61df353c5c4ec77935cd4a406839be050eed15ccd5f3f6c79aca701b2ed5ad09cb66efb4fda4f098e2e3fd75c76596170ed8359c2f5b6abbdc4b7ac8c194
6
+ metadata.gz: 439ca00c393c39e8535ffc21b504b66aaf2a987f09e424ba55b8d4d33d740c6ece187e8e2821239b1d2fa7512aa3743e8a8750be9c41d71259a6093eb2bff57a
7
+ data.tar.gz: 433fbfeaf16e28312b165ff2b293b9a529ea57e95f0e03e4637b730f1dc36c22c095717825da54da6e0549eeccbeedbb999caf7db5afed80e8e439b25a15d2cd
data/README.md CHANGED
@@ -14,18 +14,13 @@ Element | Description
14
14
  **Assessment** | When the Room needs to know who a Front Office wants to select, the Room will send the Front Office an Assessment. The Assessment is a report of where the team currently stands: players picked, players available, and round information.
15
15
  **Calendar** | Stores important boundary dates (exhibition start, exhibition end, season start, and season end).
16
16
  **Conference** | A collection of Divisions.
17
- **Coordinator Repository** | Understands how to save and load Coordinator objects.
18
17
  **Coordinator** | Object which can take a League, Calendar, Games, and an Arena and provide an iterable interface to enumerate through days and simulate games as results.
19
18
  **Detail** | Re-representation of a Result object but from a specific team's perspective.
20
19
  **Division** | A collection of teams.
21
20
  **Draft** | Bounded context (sub-module) dealing with running a round-robin player draft for teams.
22
21
  **Exhibition** | Pre-season game which has no impact to team record.
23
- **External Dependency** | Some outside system which this library or portions of this library are dependent on.
24
- **File Store** | Implements a store that can interact with the underlying File System.
25
- **File System** | Local operating system that repositories can use as their underlying persistence layer.
26
22
  **Front Office** | Identifiable as a team, contains logic for how to auto-pick draft selections. Meant to be subclassed and extended to include more intricate player selection logic as the base will simply randomly select a player.
27
23
  **Game** | Matches up a date with two teams (home and away) to represent a coordinatord match-up.
28
- **League Repository** | Understands how to save and load League objects from JSON files on disk.
29
24
  **League** | Describes a league in terms of structure composed of conferences, divisions, teams, and players.
30
25
  **Match** | When the Coordinator needs an Arena instance to select a game winner, it will send the Arena a Match. A match is Game but also includes the active roster (players) for both teams that will participate in the game.
31
26
  **Org** | Bounded context (sub-module) dealing with overall organizational structure of a sports assocation.
@@ -34,14 +29,12 @@ Element | Description
34
29
  **Record** | Represents a team's overall record.
35
30
  **Regular** | Game that counts towards regular season record.
36
31
  **Result** | The outcome of a game (typically with a home and away score).
37
- **Room Repository** | Understands how to save and load Room objects.
38
32
  **Room** | Main object responsible for providing an iterable interface capable of executing a draft, pick by pick.
39
33
  **Scheduler** | Knows how to take a League and a year and generate a game-populated calendar.
40
34
  **Scout** | Knows how to stack rank lists of players.
41
35
  **Season** | Bounded context (sub-module) dealing with calendar and matchup generation.
42
36
  **Skip** | Result event emitted when a front office decides to skip a round.
43
37
  **Standings** | Synthesizes teams and results into team standings with win/loss records and more.
44
- **Standings Repository** | Understands how to save and load Standings objects.
45
38
  **Store** | Interface for the underlying Repository persistence layer. While a Document Repository is mainly responsible for serialization/de-serialization, the store actually knows how to read/write the data.
46
39
  **Team Group** | Set of rosters that together form a cohesive league.
47
40
  **Team** | Member of a league and signs players. Has games assigned and played.
@@ -6,12 +6,13 @@ module Basketball
6
6
  class Conference < Entity
7
7
  include HasDivisions
8
8
 
9
- attr_reader :divisions
9
+ attr_reader :divisions, :name
10
10
 
11
- def initialize(id:, divisions: [])
11
+ def initialize(id:, name: '', divisions: [])
12
12
  super(id)
13
13
 
14
14
  @divisions = []
15
+ @name = name.to_s
15
16
 
16
17
  divisions.each { |d| register_division!(d) }
17
18
 
@@ -19,7 +20,7 @@ module Basketball
19
20
  end
20
21
 
21
22
  def to_s
22
- ([super] + divisions.map(&:to_s)).join("\n")
23
+ (["[#{super}] #{name}"] + divisions.map(&:to_s)).join("\n")
23
24
  end
24
25
 
25
26
  def teams
@@ -6,12 +6,13 @@ module Basketball
6
6
  class Division < Entity
7
7
  include HasTeams
8
8
 
9
- attr_reader :teams
9
+ attr_reader :teams, :name
10
10
 
11
- def initialize(id:, teams: [])
11
+ def initialize(id:, name: '', teams: [])
12
12
  super(id)
13
13
 
14
14
  @teams = []
15
+ @name = name.to_s
15
16
 
16
17
  teams.each { |t| register_team!(t) }
17
18
 
@@ -19,7 +20,7 @@ module Basketball
19
20
  end
20
21
 
21
22
  def to_s
22
- ([super] + teams.map(&:to_s)).join("\n")
23
+ (["[#{super}] #{name}"] + teams.map(&:to_s)).join("\n")
23
24
  end
24
25
 
25
26
  def players
@@ -5,21 +5,27 @@ module Basketball
5
5
  # Base class describing a player.
6
6
  # A consumer application should extend these specific to their specific sports traits.
7
7
  class Player < Entity
8
- attr_reader :overall, :position
8
+ attr_reader :overall, :position, :first_name, :last_name
9
9
 
10
- def initialize(id:, overall: 0, position: nil)
10
+ def initialize(id:, overall: 0, position: nil, first_name: '', last_name: '')
11
11
  super(id)
12
12
 
13
13
  raise ArgumentError, 'position is required' unless position
14
14
 
15
- @overall = overall
16
- @position = position
15
+ @overall = overall
16
+ @position = position
17
+ @first_name = first_name
18
+ @last_name = last_name
17
19
 
18
20
  freeze
19
21
  end
20
22
 
23
+ def full_name
24
+ "#{first_name} #{last_name}".strip
25
+ end
26
+
21
27
  def to_s
22
- "[#{super}] (#{position}) #{overall}".strip
28
+ "[#{super}] #{full_name} (#{position}) #{overall}".strip
23
29
  end
24
30
  end
25
31
  end
@@ -5,12 +5,13 @@ module Basketball
5
5
  # Base class describing a team. A team here is bare metal and is just described by an ID
6
6
  # and a collection of Player objects.
7
7
  class Team < Entity
8
- attr_reader :players
8
+ attr_reader :players, :name
9
9
 
10
- def initialize(id:, players: [])
10
+ def initialize(id:, name: '', players: [])
11
11
  super(id)
12
12
 
13
13
  @players = []
14
+ @name = name.to_s
14
15
 
15
16
  players.each { |p| sign!(p) }
16
17
 
@@ -18,7 +19,7 @@ module Basketball
18
19
  end
19
20
 
20
21
  def to_s
21
- ([super.to_s] + players.map(&:to_s)).join("\n")
22
+ (["[#{super}] #{name}"] + players.map(&:to_s)).join("\n")
22
23
  end
23
24
 
24
25
  def signed?(player)
@@ -16,7 +16,8 @@ module Basketball
16
16
  attr_reader :calendar,
17
17
  :current_date,
18
18
  :arena,
19
- :results
19
+ :results,
20
+ :league
20
21
 
21
22
  def_delegators :calendar,
22
23
  :exhibition_start_date,
@@ -28,29 +29,32 @@ module Basketball
28
29
  :regulars_for,
29
30
  :games_for
30
31
 
31
- def initialize(calendar:, current_date:, results: [])
32
+ def initialize(calendar:, league:, current_date:, results: [])
32
33
  super()
33
34
 
34
- raise ArgumentError, 'calendar is required' unless calendar
35
+ raise ArgumentError, 'calendar is required' unless calendar
35
36
  raise ArgumentError, 'current_date is required' if current_date.to_s.empty?
37
+ raise ArgumentError, 'league is required' unless league
36
38
 
37
39
  @calendar = calendar
38
40
  @current_date = current_date
39
41
  @arena = Arena.new
40
42
  @results = []
43
+ @league = league
41
44
 
42
45
  results.each { |result| replay!(result) }
43
46
 
44
47
  assert_current_date
45
48
  assert_all_past_dates_are_played
46
49
  assert_all_future_dates_arent_played
50
+ assert_all_known_teams
47
51
  end
48
52
 
49
- def sim_rest!(league, &)
53
+ def sim_rest!(&)
50
54
  events = []
51
55
 
52
56
  while not_done?
53
- new_events = sim!(league, &)
57
+ new_events = sim!(&)
54
58
 
55
59
  events += new_events
56
60
  end
@@ -68,7 +72,7 @@ module Basketball
68
72
  raise OutOfBoundsError, "current date #{current_date} should be on or after #{exhibition_start_date}"
69
73
  end
70
74
 
71
- def sim!(league)
75
+ def sim!
72
76
  raise ArgumentError, 'league is required' unless league
73
77
 
74
78
  return [] if done?
@@ -77,8 +81,8 @@ module Basketball
77
81
  games = games_for(date: current_date)
78
82
 
79
83
  games.each do |game|
80
- home_players = opponent_team(league, game.home_opponent).players
81
- away_players = opponent_team(league, game.away_opponent).players
84
+ home_players = opponent_team(game.home_opponent).players
85
+ away_players = opponent_team(game.away_opponent).players
82
86
  matchup = Matchup.new(game:, home_players:, away_players:)
83
87
  event = arena.play(matchup)
84
88
 
@@ -156,7 +160,7 @@ module Basketball
156
160
 
157
161
  attr_writer :arena
158
162
 
159
- def opponent_team(league, opponent)
163
+ def opponent_team(opponent)
160
164
  league.teams.find { |t| t == opponent }
161
165
  end
162
166
 
@@ -220,6 +224,18 @@ module Basketball
220
224
 
221
225
  result
222
226
  end
227
+
228
+ def assert_known_teams(game)
229
+ raise UnknownTeamError, "unknown opponent: #{game.home_opponent}" unless league.team?(game.home_opponent)
230
+
231
+ return if league.team?(game.away_opponent)
232
+
233
+ raise UnknownTeamError, "unknown opponent: #{game.away_opponent}"
234
+ end
235
+
236
+ def assert_all_known_teams
237
+ calendar.games.each { |game| assert_known_teams(game) }
238
+ end
223
239
  end
224
240
  end
225
241
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Basketball
4
- VERSION = '0.0.17'
4
+ VERSION = '0.0.18'
5
5
  end
data/lib/basketball.rb CHANGED
@@ -15,6 +15,3 @@ require_relative 'basketball/org'
15
15
  # Dependent on Org
16
16
  require_relative 'basketball/draft'
17
17
  require_relative 'basketball/season'
18
-
19
- # Dependent on All
20
- require_relative 'basketball/app'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: basketball
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.17
4
+ version: 0.0.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Ruggio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-12 00:00:00.000000000 Z
11
+ date: 2023-06-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: " This library is meant to serve as the domain for a basketball league/season
14
14
  simulator/turn-based game. It models core ideas such as: players, general managers,
@@ -33,14 +33,6 @@ files:
33
33
  - Rakefile
34
34
  - basketball.gemspec
35
35
  - lib/basketball.rb
36
- - lib/basketball/app.rb
37
- - lib/basketball/app/coordinator_repository.rb
38
- - lib/basketball/app/document_repository.rb
39
- - lib/basketball/app/file_store.rb
40
- - lib/basketball/app/in_memory_store.rb
41
- - lib/basketball/app/league_repository.rb
42
- - lib/basketball/app/room_repository.rb
43
- - lib/basketball/app/standings_repository.rb
44
36
  - lib/basketball/draft.rb
45
37
  - lib/basketball/draft/assessment.rb
46
38
  - lib/basketball/draft/event.rb
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Basketball
4
- module App
5
- # Knows how to flatten a Coordinator instance and rehydrate one from JSON and/or a Ruby hash.
6
- class CoordinatorRepository < DocumentRepository
7
- GAME_CLASSES = {
8
- 'Exhibition' => Season::Exhibition,
9
- 'Regular' => Season::Regular
10
- }.freeze
11
-
12
- private_constant :GAME_CLASSES
13
-
14
- private
15
-
16
- def from_h(hash)
17
- Season::Coordinator.new(
18
- calendar: deserialize_calendar(hash[:calendar]),
19
- current_date: Date.parse(hash[:current_date]),
20
- results: deserialize_results(hash[:results])
21
- )
22
- end
23
-
24
- def to_h(coordinator)
25
- {
26
- id: coordinator.id,
27
- calendar: serialize_calendar(coordinator.calendar),
28
- current_date: coordinator.current_date.to_s,
29
- results: serialize_results(coordinator.results)
30
- }
31
- end
32
-
33
- # Serialization
34
-
35
- def serialize_games(games)
36
- games.map { |game| serialize_game(game) }
37
- end
38
-
39
- def serialize_calendar(calendar)
40
- {
41
- exhibition_start_date: calendar.exhibition_start_date.to_s,
42
- exhibition_end_date: calendar.exhibition_end_date.to_s,
43
- regular_start_date: calendar.regular_start_date.to_s,
44
- regular_end_date: calendar.regular_end_date.to_s,
45
- games: serialize_games(calendar.games)
46
- }
47
- end
48
-
49
- def serialize_game(game)
50
- {
51
- type: game.class.name.split('::').last,
52
- date: game.date.to_s,
53
- home_opponent: game.home_opponent.id,
54
- away_opponent: game.away_opponent.id
55
- }
56
- end
57
-
58
- def serialize_result(result)
59
- {
60
- game: serialize_game(result.game),
61
- home_score: result.home_score,
62
- away_score: result.away_score
63
- }
64
- end
65
-
66
- def serialize_results(results)
67
- results.map do |result|
68
- serialize_result(result)
69
- end
70
- end
71
-
72
- # Deserialization
73
-
74
- def deserialize_calendar(calendar_hash)
75
- Season::Calendar.new(
76
- exhibition_start_date: Date.parse(calendar_hash[:exhibition_start_date]),
77
- exhibition_end_date: Date.parse(calendar_hash[:exhibition_end_date]),
78
- regular_start_date: Date.parse(calendar_hash[:regular_start_date]),
79
- regular_end_date: Date.parse(calendar_hash[:regular_end_date]),
80
- games: deserialize_games(calendar_hash[:games])
81
- )
82
- end
83
-
84
- def deserialize_games(game_hashes)
85
- (game_hashes || []).map { |game_hash| deserialize_game(game_hash) }
86
- end
87
-
88
- def deserialize_game(game_hash)
89
- GAME_CLASSES.fetch(game_hash[:type]).new(
90
- date: Date.parse(game_hash[:date]),
91
- home_opponent: Season::Opponent.new(id: game_hash[:home_opponent]),
92
- away_opponent: Season::Opponent.new(id: game_hash[:away_opponent])
93
- )
94
- end
95
-
96
- def deserialize_results(result_hashes)
97
- (result_hashes || []).map do |result_hash|
98
- deserialize_result(result_hash)
99
- end
100
- end
101
-
102
- def deserialize_result(result_hash)
103
- Season::Result.new(
104
- game: deserialize_game(result_hash[:game]),
105
- home_score: result_hash[:home_score],
106
- away_score: result_hash[:away_score]
107
- )
108
- end
109
- end
110
- end
111
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Basketball
4
- module App
5
- # Base class for all repositories which are based on a flat document.
6
- # At the very minimum sub-classes should implement #to_h(object) and #from_h(hash).
7
- class DocumentRepository
8
- attr_reader :store
9
-
10
- def initialize(store = InMemoryStore.new)
11
- super()
12
-
13
- @store = store
14
- end
15
-
16
- def load(id)
17
- contents = store.read(id)
18
-
19
- deserialize(contents).tap do |object|
20
- object.send('id=', id)
21
- end
22
- end
23
-
24
- def save(id, object)
25
- object.send('id=', id)
26
-
27
- contents = serialize(object)
28
-
29
- store.write(id, contents)
30
-
31
- object
32
- end
33
-
34
- def delete(object)
35
- return false unless object.id
36
-
37
- store.delete(object.id)
38
-
39
- object.send('id=', nil)
40
-
41
- true
42
- end
43
-
44
- def exist?(id)
45
- store.exist?(id)
46
- end
47
-
48
- protected
49
-
50
- def from_h(hash)
51
- Entity.new(hash[:id])
52
- end
53
-
54
- def to_h(entity)
55
- { id: entity.id }
56
- end
57
-
58
- private
59
-
60
- def deserialize(string)
61
- hash = JSON.parse(string, symbolize_names: true)
62
-
63
- from_h(hash)
64
- end
65
-
66
- def serialize(object)
67
- to_h(object).to_json
68
- end
69
- end
70
- end
71
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Basketball
4
- module App
5
- # Knows how to read and write documents to disk.
6
- class FileStore
7
- class PathNotFoundError < StandardError; end
8
-
9
- def exist?(path)
10
- File.exist?(path)
11
- end
12
-
13
- def read(path)
14
- raise PathNotFoundError, "'#{path}' not found" unless exist?(path)
15
-
16
- File.read(path)
17
- end
18
-
19
- def write(path, contents)
20
- dir = File.dirname(path)
21
-
22
- FileUtils.mkdir_p(dir)
23
-
24
- File.write(path, contents)
25
-
26
- nil
27
- end
28
-
29
- def delete(path)
30
- raise PathNotFoundError, "'#{path}' not found" unless exist?(path)
31
-
32
- File.delete(path)
33
-
34
- nil
35
- end
36
- end
37
- end
38
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Basketball
4
- module App
5
- # Knows how to read and write documents to a Ruby Hash.
6
- class InMemoryStore
7
- class KeyNotFoundError < StandardError; end
8
-
9
- attr_reader :data
10
-
11
- def initialize(data = {})
12
- @data = data
13
-
14
- freeze
15
- end
16
-
17
- def exist?(key)
18
- data.key?(key.to_s)
19
- end
20
-
21
- def read(key)
22
- raise KeyNotFoundError, "'#{key}' not found" unless exist?(key)
23
-
24
- data[key.to_s]
25
- end
26
-
27
- def write(key, contents)
28
- data[key.to_s] = contents
29
-
30
- nil
31
- end
32
-
33
- def delete(key)
34
- raise KeyNotFoundError, "'#{key}' not found" unless exist?(key)
35
-
36
- data.delete(key)
37
-
38
- nil
39
- end
40
- end
41
- end
42
- end
@@ -1,109 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Basketball
4
- module App
5
- # Knows how to flatten a League instances and rehydrate one from JSON and/or a Ruby hash.
6
- class LeagueRepository < DocumentRepository
7
- private
8
-
9
- def from_h(hash)
10
- deserialize_league(hash)
11
- end
12
-
13
- def to_h(league)
14
- serialize_league(league)
15
- end
16
-
17
- # Serialization
18
-
19
- def serialize_league(league)
20
- {
21
- id: league.id,
22
- conferences: serialize_conferences(league.conferences)
23
- }
24
- end
25
-
26
- def serialize_conferences(conferences)
27
- conferences.map do |conference|
28
- {
29
- id: conference.id,
30
- divisions: serialize_divisions(conference.divisions)
31
- }
32
- end
33
- end
34
-
35
- def serialize_divisions(divisions)
36
- divisions.map do |division|
37
- {
38
- id: division.id,
39
- teams: serialize_teams(division.teams)
40
- }
41
- end
42
- end
43
-
44
- def serialize_teams(teams)
45
- teams.map do |team|
46
- {
47
- id: team.id,
48
- players: serialize_players(team.players)
49
- }
50
- end
51
- end
52
-
53
- def serialize_players(players)
54
- players.map do |player|
55
- {
56
- id: player.id,
57
- overall: player.overall,
58
- position: player.position&.code
59
- }
60
- end
61
- end
62
-
63
- # Deserialization
64
-
65
- def deserialize_league(league_hash)
66
- Org::League.new(
67
- conferences: deserialize_conferences(league_hash[:conferences])
68
- )
69
- end
70
-
71
- def deserialize_conferences(conference_hashes)
72
- (conference_hashes || []).map do |conference_hash|
73
- Org::Conference.new(
74
- id: conference_hash[:id],
75
- divisions: deserialize_divisions(conference_hash[:divisions])
76
- )
77
- end
78
- end
79
-
80
- def deserialize_divisions(division_hashes)
81
- (division_hashes || []).map do |division_hash|
82
- Org::Division.new(
83
- id: division_hash[:id],
84
- teams: deserialize_teams(division_hash[:teams])
85
- )
86
- end
87
- end
88
-
89
- def deserialize_teams(team_hashes)
90
- (team_hashes || []).map do |team_hash|
91
- Org::Team.new(
92
- id: team_hash[:id],
93
- players: deserialize_players(team_hash[:players])
94
- )
95
- end
96
- end
97
-
98
- def deserialize_players(player_hashes)
99
- (player_hashes || []).map do |player_hash|
100
- Org::Player.new(
101
- id: player_hash[:id],
102
- overall: player_hash[:overall],
103
- position: Org::Position.new(player_hash[:position])
104
- )
105
- end
106
- end
107
- end
108
- end
109
- end
@@ -1,161 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Basketball
4
- module App
5
- # Can load and save Room objects as JSON Documents.
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
- id: room.id,
30
- rounds: room.rounds,
31
- front_offices: room.front_offices.map { |fo| serialize_front_office(fo) },
32
- players: room.players.map { |p| serialize_player(p) },
33
- events: serialize_events(room.events)
34
- }
35
- end
36
-
37
- # Serialization
38
-
39
- def serialize_player(player)
40
- {
41
- id: player.id,
42
- overall: player.overall,
43
- position: player.position&.code
44
- }
45
- end
46
-
47
- def serialize_front_office(front_office)
48
- {
49
- id: front_office.id,
50
- risk_level: front_office.risk_level,
51
- prioritized_positions: front_office.prioritized_positions.map(&:code),
52
- star_level: front_office.star_level
53
- }
54
- end
55
-
56
- def serialize_events(events)
57
- events.map do |event|
58
- case event
59
- when Draft::Pick
60
- serialize_pick(event)
61
- when Draft::Skip
62
- serialize_skip(event)
63
- end
64
- end
65
- end
66
-
67
- def serialize_pick(event)
68
- {
69
- id: event.id || event.pick,
70
- type: PICK_EVENT,
71
- front_office: event.front_office.id,
72
- pick: event.pick,
73
- round: event.round,
74
- round_pick: event.round_pick,
75
- auto: event.auto,
76
- player: event.player.id
77
- }
78
- end
79
-
80
- def serialize_skip(event)
81
- {
82
- id: event.id || event.pick,
83
- type: SKIP_EVENT,
84
- front_office: event.front_office.id,
85
- pick: event.pick,
86
- round: event.round,
87
- round_pick: event.round_pick
88
- }
89
- end
90
-
91
- # Deserialization
92
-
93
- def deserialize_player(player_hash)
94
- Org::Player.new(
95
- id: player_hash[:id],
96
- overall: player_hash[:overall],
97
- position: Org::Position.new(player_hash[:position])
98
- )
99
- end
100
-
101
- def deserialize_front_office(hash)
102
- Draft::FrontOffice.new(
103
- id: hash[:id],
104
- risk_level: hash[:risk_level].to_i,
105
- prioritized_positions: (hash[:prioritized_positions] || []).map { |c| Org::Position.new(c) },
106
- star_level: hash[:star_level].to_i
107
- )
108
- end
109
-
110
- def deserialize_front_offices(hashes)
111
- (hashes || []).map { |fo| deserialize_front_office(fo) }
112
- end
113
-
114
- def deserialize_players(hashes)
115
- (hashes || []).map { |hash| deserialize_player(hash) }
116
- end
117
-
118
- def deserialize_pick(hash, players:, front_office:)
119
- player_id = hash[:player]
120
- player = players.find { |p| p.id == player_id }
121
-
122
- Draft::Pick.new(
123
- front_office:,
124
- pick: hash[:pick],
125
- round: hash[:round],
126
- round_pick: hash[:round_pick],
127
- player:,
128
- auto: hash[:auto]
129
- )
130
- end
131
-
132
- def deserialize_skip(hash, front_office:)
133
- Draft::Skip.new(
134
- front_office:,
135
- pick: hash[:pick],
136
- round: hash[:round],
137
- round_pick: hash[:round_pick]
138
- )
139
- end
140
-
141
- def deserialize_events(hashes, players:, front_offices:)
142
- (hashes || []).map do |hash|
143
- front_office_id = hash[:front_office]
144
- front_office = front_offices.find { |fo| fo.id == front_office_id }
145
-
146
- event =
147
- case hash[:type]
148
- when PICK_EVENT
149
- deserialize_pick(hash, players:, front_office:)
150
- when SKIP_EVENT
151
- deserialize_skip(hash, front_office:)
152
- end
153
-
154
- event.tap do |e|
155
- e.send('id=', hash[:id])
156
- end
157
- end
158
- end
159
- end
160
- end
161
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Basketball
4
- module App
5
- # Can load and save Standings objects as JSON Documents.
6
- class StandingsRepository < DocumentRepository
7
- private
8
-
9
- def from_h(hash)
10
- Season::Standings.new(
11
- records: deserialize_records(hash[:records])
12
- )
13
- end
14
-
15
- def to_h(standings)
16
- {
17
- id: standings.id,
18
- records: serialize_records(standings.records)
19
- }
20
- end
21
-
22
- # Serialization
23
-
24
- def serialize_records(records)
25
- (records || []).map do |record|
26
- {
27
- id: record.id,
28
- details: serialize_details(record.details)
29
- }
30
- end
31
- end
32
-
33
- def serialize_details(details)
34
- (details || []).map do |detail|
35
- {
36
- date: detail.date.to_s,
37
- home: detail.home,
38
- opponent: detail.opponent.id,
39
- opponent_score: detail.opponent_score,
40
- score: detail.score
41
- }
42
- end
43
- end
44
-
45
- # Deserialization
46
-
47
- def deserialize_records(record_hashes)
48
- (record_hashes || []).map do |record_hash|
49
- Season::Record.new(
50
- id: record_hash[:id],
51
- details: deserialize_details(record_hash[:details])
52
- )
53
- end
54
- end
55
-
56
- def deserialize_details(detail_hashes)
57
- (detail_hashes || []).map do |detail_hash|
58
- Season::Detail.new(
59
- date: Date.parse(detail_hash[:date]),
60
- home: detail_hash[:home],
61
- opponent: Season::Opponent.new(id: detail_hash[:opponent]),
62
- opponent_score: detail_hash[:opponent_score].to_i,
63
- score: detail_hash[:score].to_i
64
- )
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Stores
4
- require_relative 'app/file_store'
5
- require_relative 'app/in_memory_store'
6
-
7
- # Repositories / Common
8
- require_relative 'app/document_repository'
9
-
10
- # Repositories / Implementations
11
- require_relative 'app/coordinator_repository'
12
- require_relative 'app/league_repository'
13
- require_relative 'app/room_repository'
14
- require_relative 'app/standings_repository'