basketball 0.0.19 → 0.0.21

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: cd49f58b9f207574c1d2d24dfbfbcc95aa19aa1b20dfef193e7ed5f76dc9c40b
4
- data.tar.gz: 27b5646e17b6e4e195938b6df2c5aa72afa5cd8d83c19abe9cbbe52d603b6399
3
+ metadata.gz: 0e5c1826475c5a5d9f7ff227034e533c17998a9dff9a1f71107eed48dd5cf176
4
+ data.tar.gz: edd7a5e117b6f5f17288220f788dc0c4f8a23f69d095d354521ed3834b1c3261
5
5
  SHA512:
6
- metadata.gz: '09133208c27fa5edf1667a669178703ce702a3b9f20a2d0bb5006dc4ba3260b9b9ccd51db7bbc53cf61d2df12806fd0241ca6cb8ede153ca3af2782c30eeddf9'
7
- data.tar.gz: 1e82cd3b7057c8e2ce63a1df77a4ecd4ea7ab8c64275db9d70c1e40d2f006b9b1e128d2a92311b3f3c3f99e35d5507f81ad8c5faec385906814ea53d32ce6583
6
+ metadata.gz: 76d04eb4fded2ca78f37f6b19cbed042beb8f206470e065bbe314a9cf67d2976a3283fab12c9de3f3932226098180bec18fb600c6cdab18fac030f75e3bf7687
7
+ data.tar.gz: 51069a1317e825eda9adfd980448651dc6e8f415b94e70709b4f9bea4c7f3a6569206d8b42fd32c55b6e9261973b47c7e735f3a3d651bdaace110fa2772c2cf9
data/README.md CHANGED
@@ -19,6 +19,7 @@ Element | Description
19
19
  **Division** | A collection of teams.
20
20
  **Draft** | Bounded context (sub-module) dealing with running a round-robin player draft for teams.
21
21
  **Exhibition** | Pre-season game which has no impact to team record.
22
+ **Free Agent** | A player who is not signed to any team but is able to be signed.
22
23
  **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.
23
24
  **Game** | Matches up a date with two teams (home and away) to represent a coordinatord match-up.
24
25
  **League** | Describes a league in terms of structure composed of conferences, divisions, teams, and players.
@@ -62,6 +63,13 @@ The input for the main object `Basketball::Draft::Room` is an array of teams (`B
62
63
  * **Basketball::Draft::Room#pick!(player)**: Pick an exact player for the current front office.
63
64
  * **Basketball::Draft::Room#sim_rest!**: Simulate the rest of the picks.
64
65
 
66
+ ### Org Module
67
+
68
+ The Org module contains all the structural and transactional for the basketball league as a whole. A League can be made up of free agents and conferences, conferences can have divisions, divisions can have teams, and teams can have players. The main object: `Basketball::Org::League` allows for the control through its API:
69
+
70
+ * **Basketball::Org::League#sign!**: Sign a player to a team.
71
+ * **Basketball::Org::League#release!**: Release a player from a team and place them in the free agent pool.
72
+
65
73
  ### Season Module
66
74
 
67
75
  The Season module knows how to execute a calendar of games for a League and generate results. The main object is the `Basketball::Season::Coordinator` class. Once instantiated there are four main methods:
@@ -16,16 +16,18 @@ module Basketball
16
16
 
17
17
  private_constant :DEFAULT_MAX_STAR_LEVEL, :DEFAULT_MAX_RISK_LEVEL, :MAX_POSITIONS
18
18
 
19
- attr_reader :prioritized_positions, :risk_level, :star_level, :scout
19
+ attr_reader :name, :prioritized_positions, :risk_level, :star_level, :scout
20
20
 
21
21
  def initialize(
22
22
  id:,
23
+ name: '',
23
24
  prioritized_positions: [],
24
25
  risk_level: rand(0..DEFAULT_MAX_RISK_LEVEL),
25
26
  star_level: rand(0..DEFAULT_MAX_STAR_LEVEL)
26
27
  )
27
28
  super(id)
28
29
 
30
+ @name = name.to_s
29
31
  @risk_level = risk_level.to_i
30
32
  @star_level = star_level.to_i
31
33
  @prioritized_positions = prioritized_positions
@@ -13,28 +13,69 @@ module Basketball
13
13
  include HasDivisions
14
14
 
15
15
  class ConferenceAlreadyRegisteredError < StandardError; end
16
+ class NotSignedError < StandardError; end
16
17
 
17
- alias signed? player?
18
+ attr_reader :conferences, :free_agents
18
19
 
19
- attr_reader :conferences
20
-
21
- def initialize(conferences: [])
20
+ def initialize(conferences: [], free_agents: [])
22
21
  super()
23
22
 
24
23
  @conferences = []
24
+ @free_agents = []
25
25
 
26
26
  conferences.each { |c| register!(c) }
27
+ free_agents.each { |p| free_agent!(p) }
27
28
  end
28
29
 
29
30
  def to_s
30
31
  conferences.map(&:to_s).join("\n")
31
32
  end
32
33
 
34
+ def free_agent?(player)
35
+ free_agents.include?(player)
36
+ end
37
+
38
+ def free_agent!(player)
39
+ raise ArgumentError, 'player is required' unless player
40
+ raise PlayerAlreadySignedError, "#{player} already registered" if player?(player)
41
+
42
+ @free_agents << player
43
+
44
+ self
45
+ end
46
+
47
+ def release!(player)
48
+ raise ArgumentError, 'player is required' unless player
49
+ raise NotSignedError, 'player is currently a free agent' if free_agent?(player)
50
+
51
+ team = team_for_player(player)
52
+
53
+ raise NotSignedError, 'player was not found to be signed by any team' unless team
54
+
55
+ team.release!(player)
56
+
57
+ free_agents << player
58
+
59
+ self
60
+ end
61
+
62
+ def signed?(player)
63
+ signed_players.include?(player)
64
+ end
65
+
66
+ def signed_players
67
+ conferences.flat_map(&:players)
68
+ end
69
+
33
70
  def sign!(player:, team:)
34
71
  raise ArgumentError, 'player is required' unless player
35
72
  raise ArgumentError, 'team is required' unless team
36
73
  raise UnregisteredTeamError, "#{team} not registered" unless team?(team)
37
- raise PlayerAlreadySignedError, "#{player} already registered" if player?(player)
74
+ raise PlayerAlreadySignedError, "#{player} already registered" if signed?(player)
75
+
76
+ # If this player was a free agent then make sure we remove them from the free agent pool.
77
+ # It is OK if they weren't, they can still be directly signed.
78
+ free_agents.delete(player) if free_agent?(player)
38
79
 
39
80
  # It is OK to pass in a detached team as long as its equivalent resides in this
40
81
  # League's object graph.
@@ -67,7 +108,7 @@ module Basketball
67
108
  end
68
109
 
69
110
  def players
70
- conferences.flat_map(&:players)
111
+ conferences.flat_map(&:players) + free_agents
71
112
  end
72
113
 
73
114
  def conference_for(team)
@@ -93,6 +134,10 @@ module Basketball
93
134
  def team_for(id)
94
135
  teams.find { |team| team.id == id }
95
136
  end
137
+
138
+ def team_for_player(player)
139
+ teams.find { |t| t.signed?(player) }
140
+ end
96
141
  end
97
142
  end
98
143
  end
@@ -5,6 +5,11 @@ 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
+ class PlayerNotSignedError < StandardError; end
9
+ class MaxPlayerCountError < StandardError; end
10
+
11
+ MAX_PLAYER_COUNT = 18
12
+
8
13
  attr_reader :players, :name
9
14
 
10
15
  def initialize(id:, name: '', players: [])
@@ -26,10 +31,23 @@ module Basketball
26
31
  players.include?(player)
27
32
  end
28
33
 
34
+ def release!(player)
35
+ raise ArgumentError, 'player is required' unless player
36
+ raise PlayerNotSignedError, "#{player} id not signed by #{self}" unless signed?(player)
37
+
38
+ players.delete(player)
39
+
40
+ self
41
+ end
42
+
29
43
  def sign!(player)
30
44
  raise ArgumentError, 'player is required' unless player
31
45
  raise PlayerAlreadySignedError, "#{player} already signed by #{self}" if signed?(player)
32
46
 
47
+ if (players.length + 1) >= MAX_PLAYER_COUNT
48
+ raise MaxPlayerCountError, "max player count reached: #{MAX_PLAYER_COUNT}"
49
+ end
50
+
33
51
  players << player
34
52
 
35
53
  self
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Basketball
4
- VERSION = '0.0.19'
4
+ VERSION = '0.0.21'
5
5
  end
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.19
4
+ version: 0.0.21
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-14 00:00:00.000000000 Z
11
+ date: 2023-06-16 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,