basketball 0.0.18 → 0.0.20

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: afad5b6023e9b0baf1dc11fe6874d4cc46430c1698aa4e97bf5dc2df8cbb314e
4
- data.tar.gz: f98bb161b770d7148c4fb271ab1b58b2347cfe7b85f94acf1fb6332a4517e61b
3
+ metadata.gz: 6742218e05c042c3cfe5c5ae155b4deaa22a8c1c1aeeac9c3ef2cdb69c38be42
4
+ data.tar.gz: 3d151a9df301c7160f0e3884ff961a984f64d5071e2081e3e01eddff557069ab
5
5
  SHA512:
6
- metadata.gz: 439ca00c393c39e8535ffc21b504b66aaf2a987f09e424ba55b8d4d33d740c6ece187e8e2821239b1d2fa7512aa3743e8a8750be9c41d71259a6093eb2bff57a
7
- data.tar.gz: 433fbfeaf16e28312b165ff2b293b9a529ea57e95f0e03e4637b730f1dc36c22c095717825da54da6e0549eeccbeedbb999caf7db5afed80e8e439b25a15d2cd
6
+ metadata.gz: d1a696a182a4b196030c79926591149d864c744fb27eab6c114800ee066f7edfb9cb340efda8ba96a96322d1bbf1dcf452e9777b678a91c71e9c31523743f165
7
+ data.tar.gz: 4aac8527166debde576f7c91ff7e40aaf7bde42ec33214f96e8f86b66a174d5d8f65db31cca44be04c0c003f1ae631ef0454b8f650ad66957c95eff0b9494133
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:
@@ -4,21 +4,20 @@ module Basketball
4
4
  module Draft
5
5
  # Describes what all Room events have to have to be considered an "event".
6
6
  class Event < Entity
7
- attr_reader :pick, :round, :round_pick, :front_office
7
+ attr_reader :round, :round_pick, :front_office
8
8
 
9
- def initialize(front_office:, pick:, round:, round_pick:)
10
- super()
9
+ def initialize(id:, front_office:, round:, round_pick:)
10
+ super(id)
11
11
 
12
12
  raise ArgumentError, 'front_office required' unless front_office
13
13
 
14
14
  @front_office = front_office
15
- @pick = pick.to_i
16
15
  @round = round.to_i
17
16
  @round_pick = round_pick.to_i
18
17
  end
19
18
 
20
19
  def to_s
21
- "[#{id}] ##{pick} R:#{round} P:#{round_pick} - #{front_office}"
20
+ "[#{id}] R:#{round} P:#{round_pick} - #{front_office}"
22
21
  end
23
22
  end
24
23
  end
@@ -6,8 +6,8 @@ module Basketball
6
6
  class Pick < Event
7
7
  attr_reader :player, :auto
8
8
 
9
- def initialize(front_office:, player:, pick:, round:, round_pick:, auto: false)
10
- super(front_office:, pick:, round:, round_pick:)
9
+ def initialize(id:, front_office:, player:, round:, round_pick:, auto: false)
10
+ super(id:, front_office:, round:, round_pick:)
11
11
 
12
12
  raise ArgumentError, 'player required' unless player
13
13
 
@@ -148,7 +148,7 @@ module Basketball
148
148
  def skip!
149
149
  return if done?
150
150
 
151
- event = Skip.new(front_office:, pick:, round:, round_pick:)
151
+ event = Skip.new(id: pick, front_office:, round:, round_pick:)
152
152
 
153
153
  add_event!(event)
154
154
 
@@ -159,7 +159,7 @@ module Basketball
159
159
  return if done?
160
160
 
161
161
  player = front_office.pick(assessment)
162
- event = Pick.new(front_office:, pick:, round:, round_pick:, player:, auto: true)
162
+ event = Pick.new(id: pick, front_office:, round:, round_pick:, player:, auto: true)
163
163
 
164
164
  add_event!(event)
165
165
 
@@ -183,7 +183,7 @@ module Basketball
183
183
  def pick!(player)
184
184
  return nil if done?
185
185
 
186
- event = Pick.new(front_office:, pick:, round:, round_pick:, player:)
186
+ event = Pick.new(id: pick, front_office:, round:, round_pick:, player:)
187
187
 
188
188
  add_event!(event)
189
189
  end
@@ -199,7 +199,7 @@ module Basketball
199
199
  raise EndOfDraftError, "#{total_picks} pick limit reached" if done?
200
200
  raise UnknownFrontOfficeError, "#{front_office} doesnt exist" unless front_offices.include?(event.front_office)
201
201
  raise EventOutOfOrderError, "#{event.front_office} cant pick right now" if event.front_office != front_office
202
- raise EventOutOfOrderError, "#{event} has wrong pick" if event.pick != pick
202
+ raise EventOutOfOrderError, "#{event} has wrong pick" if event.id != pick
203
203
  raise EventOutOfOrderError, "#{event} has wrong round" if event.round != round
204
204
  raise EventOutOfOrderError, "#{event} has wrong round_pick" if event.round_pick != round_pick
205
205
 
@@ -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,8 @@ 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
+
8
10
  attr_reader :players, :name
9
11
 
10
12
  def initialize(id:, name: '', players: [])
@@ -26,6 +28,15 @@ module Basketball
26
28
  players.include?(player)
27
29
  end
28
30
 
31
+ def release!(player)
32
+ raise ArgumentError, 'player is required' unless player
33
+ raise PlayerNotSignedError, "#{player} id not signed by #{self}" unless signed?(player)
34
+
35
+ players.delete(player)
36
+
37
+ self
38
+ end
39
+
29
40
  def sign!(player)
30
41
  raise ArgumentError, 'player is required' unless player
31
42
  raise PlayerAlreadySignedError, "#{player} already signed by #{self}" if signed?(player)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Basketball
4
- VERSION = '0.0.18'
4
+ VERSION = '0.0.20'
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.18
4
+ version: 0.0.20
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,