basketball 0.0.2 → 0.0.3
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/CHANGELOG.md +6 -1
- data/lib/basketball/drafting/engine.rb +8 -2
- data/lib/basketball/drafting/engine_serializer.rb +1 -1
- data/lib/basketball/drafting/event.rb +0 -2
- data/lib/basketball/drafting/front_office.rb +13 -19
- data/lib/basketball/drafting/player.rb +0 -2
- data/lib/basketball/drafting/position.rb +8 -15
- data/lib/basketball/drafting/roster.rb +4 -2
- data/lib/basketball/drafting/sim_event.rb +0 -2
- data/lib/basketball/drafting/team.rb +4 -6
- data/lib/basketball/entity.rb +31 -0
- data/lib/basketball/value_object.rb +53 -0
- data/lib/basketball/version.rb +1 -1
- data/lib/basketball.rb +5 -0
- metadata +4 -3
- data/lib/basketball/drafting/entity.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29805ef216312c25dee77d7f7c2a82bf220287404e9e241d24e16dddfb895fcc
|
4
|
+
data.tar.gz: 3d8a0038acf62e4e1aa230299cc1b2d7d777596bc133b159b1e661639c75c76d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae3baac2215dbfee6b9cf70a44b2bdf9257d7dade811c6a30bf37b22f840bd85621f6441d137e07f38b615210092d0cede011a2e9f4655aa1e05c6281411a856
|
7
|
+
data.tar.gz: 4bcb67de94178f2945376faa2cb57c5f5884d60b24479d73e12d1145c7c20c1b9f3dd547f321c578f39d43868fb2f8d158859020b14d7e436fbface8a89b2809
|
data/CHANGELOG.md
CHANGED
@@ -98,12 +98,13 @@ module Basketball
|
|
98
98
|
|
99
99
|
def sim!(times = nil)
|
100
100
|
counter = 0
|
101
|
+
events = []
|
101
102
|
|
102
103
|
until done? || (times && counter >= times)
|
103
104
|
team = current_team
|
104
105
|
|
105
106
|
player = team.pick(
|
106
|
-
|
107
|
+
undrafted_player_search:,
|
107
108
|
drafted_players: drafted_players(team),
|
108
109
|
round: current_round
|
109
110
|
)
|
@@ -122,9 +123,10 @@ module Basketball
|
|
122
123
|
yield(event) if block_given?
|
123
124
|
|
124
125
|
counter += 1
|
126
|
+
events << event
|
125
127
|
end
|
126
128
|
|
127
|
-
|
129
|
+
events
|
128
130
|
end
|
129
131
|
|
130
132
|
def pick!(player)
|
@@ -146,6 +148,10 @@ module Basketball
|
|
146
148
|
players - drafted_players
|
147
149
|
end
|
148
150
|
|
151
|
+
def undrafted_player_search
|
152
|
+
PlayerSearch.new(undrafted_players)
|
153
|
+
end
|
154
|
+
|
149
155
|
private
|
150
156
|
|
151
157
|
attr_reader :players_by_id, :teams_by_id
|
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
module Basketball
|
4
4
|
module Drafting
|
5
|
-
class FrontOffice
|
5
|
+
class FrontOffice < ValueObject
|
6
6
|
MAX_DEPTH = 3
|
7
7
|
MAX_FUZZ = 2
|
8
8
|
MAX_POSITIONS = 12
|
9
9
|
|
10
10
|
private_constant :MAX_DEPTH, :MAX_FUZZ, :MAX_POSITIONS
|
11
11
|
|
12
|
-
|
12
|
+
attr_reader_value :prioritized_positions, :fuzz, :depth
|
13
13
|
|
14
14
|
def initialize(prioritized_positions: [], fuzz: rand(0..MAX_FUZZ), depth: rand(0..MAX_DEPTH))
|
15
|
+
super()
|
16
|
+
|
15
17
|
@fuzz = fuzz.to_i
|
16
18
|
@depth = depth.to_i
|
17
19
|
@prioritized_positions = prioritized_positions
|
@@ -24,44 +26,36 @@ module Basketball
|
|
24
26
|
freeze
|
25
27
|
end
|
26
28
|
|
27
|
-
def
|
28
|
-
"#{prioritized_positions.map(&:to_s).join(',')} (F:#{fuzz} D:#{depth})"
|
29
|
-
end
|
30
|
-
|
31
|
-
def pick(undrafted_players:, drafted_players:, round:)
|
29
|
+
def pick(undrafted_player_search:, drafted_players:, round:)
|
32
30
|
players = []
|
33
31
|
|
34
|
-
players = adaptive_search(
|
35
|
-
players = balanced_search(
|
36
|
-
players = top_players(
|
32
|
+
players = adaptive_search(undrafted_player_search:, drafted_players:) if depth >= round
|
33
|
+
players = balanced_search(undrafted_player_search:, drafted_players:) if players.empty?
|
34
|
+
players = top_players(undrafted_player_search:) if players.empty?
|
37
35
|
|
38
36
|
players[0..fuzz].sample
|
39
37
|
end
|
40
38
|
|
41
39
|
private
|
42
40
|
|
43
|
-
def adaptive_search(
|
44
|
-
search = PlayerSearch.new(undrafted_players)
|
45
|
-
|
41
|
+
def adaptive_search(undrafted_player_search:, drafted_players:)
|
46
42
|
drafted_positions = drafted_players.map(&:position)
|
47
43
|
|
48
|
-
|
44
|
+
undrafted_player_search.query(exclude_positions: drafted_positions)
|
49
45
|
end
|
50
46
|
|
51
|
-
def balanced_search(
|
52
|
-
search = PlayerSearch.new(undrafted_players)
|
53
|
-
|
47
|
+
def balanced_search(undrafted_player_search:, drafted_players:)
|
54
48
|
players = []
|
55
49
|
|
56
50
|
# Try to find best pick for exact desired position.
|
57
51
|
# If you cant find one, then move to the next desired position until the end of the queue
|
58
52
|
available_prioritized_positions(drafted_players:).each do |position|
|
59
|
-
players =
|
53
|
+
players = undrafted_player_search.query(position:)
|
60
54
|
|
61
55
|
break if players.any?
|
62
56
|
end
|
63
57
|
|
64
|
-
players = players.any? ? players :
|
58
|
+
players = players.any? ? players : undrafted_player_search.query
|
65
59
|
end
|
66
60
|
|
67
61
|
def all_random_positions
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Basketball
|
4
4
|
module Drafting
|
5
|
-
class Position
|
5
|
+
class Position < ValueObject
|
6
6
|
extend Forwardable
|
7
7
|
|
8
8
|
class << self
|
@@ -17,25 +17,18 @@ module Basketball
|
|
17
17
|
FRONT_COURT_VALUES = %w[PF C].to_set.freeze
|
18
18
|
ALL_VALUES = (BACK_COURT_VALUES.to_a + FRONT_COURT_VALUES.to_a).to_set.freeze
|
19
19
|
|
20
|
-
|
20
|
+
attr_reader_value :code
|
21
21
|
|
22
|
-
def_delegators :
|
22
|
+
def_delegators :code, :to_s
|
23
23
|
|
24
|
-
def initialize(
|
25
|
-
|
24
|
+
def initialize(code)
|
25
|
+
super()
|
26
26
|
|
27
|
-
|
27
|
+
@code = code.to_s.upcase
|
28
28
|
|
29
|
-
|
30
|
-
end
|
29
|
+
raise InvalidPositionError, "Unknown position code: #{@code}" unless ALL_VALUES.include?(@code)
|
31
30
|
|
32
|
-
|
33
|
-
value == other.value
|
34
|
-
end
|
35
|
-
alias eql? ==
|
36
|
-
|
37
|
-
def hash
|
38
|
-
value.hash
|
31
|
+
freeze
|
39
32
|
end
|
40
33
|
end
|
41
34
|
end
|
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
module Basketball
|
4
4
|
module Drafting
|
5
|
-
class Roster
|
5
|
+
class Roster < ValueObject
|
6
6
|
extend Forwardable
|
7
7
|
|
8
8
|
class WrongTeamEventError < StandardError; end
|
9
9
|
|
10
|
-
|
10
|
+
attr_reader_value :team, :events
|
11
11
|
|
12
12
|
def_delegators :team, :id
|
13
13
|
|
14
14
|
def initialize(team:, events: [])
|
15
|
+
super()
|
16
|
+
|
15
17
|
raise ArgumentError, 'team is required' unless team
|
16
18
|
|
17
19
|
other_teams_pick_event_ids = events.reject { |e| e.team == team }.map(&:id)
|
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'entity'
|
4
|
-
|
5
3
|
module Basketball
|
6
4
|
module Drafting
|
7
5
|
class Team < Entity
|
6
|
+
extend Forwardable
|
7
|
+
|
8
8
|
attr_reader :name, :front_office
|
9
9
|
|
10
|
+
def_delegators :front_office, :pick
|
11
|
+
|
10
12
|
def initialize(id:, name: '', front_office: FrontOffice.new)
|
11
13
|
super(id)
|
12
14
|
|
@@ -21,10 +23,6 @@ module Basketball
|
|
21
23
|
def to_s
|
22
24
|
"[#{super}] #{name}"
|
23
25
|
end
|
24
|
-
|
25
|
-
def pick(undrafted_players:, drafted_players:, round:)
|
26
|
-
front_office.pick(undrafted_players:, drafted_players:, round:)
|
27
|
-
end
|
28
26
|
end
|
29
27
|
end
|
30
28
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Basketball
|
4
|
+
class Entity
|
5
|
+
extend Forwardable
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
attr_reader :id
|
9
|
+
|
10
|
+
def_delegators :id, :to_s
|
11
|
+
|
12
|
+
def initialize(id)
|
13
|
+
raise ArgumentError, 'id is required' if id.to_s.empty?
|
14
|
+
|
15
|
+
@id = id.to_s.upcase
|
16
|
+
end
|
17
|
+
|
18
|
+
def <=>(other)
|
19
|
+
id <=> other.id
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
id == other.id
|
24
|
+
end
|
25
|
+
alias eql? ==
|
26
|
+
|
27
|
+
def hash
|
28
|
+
id.hash
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Basketball
|
4
|
+
class ValueObject
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
# NOTE: This current implementation most likely does not work for deep inheritance trees.
|
8
|
+
class << self
|
9
|
+
def value_keys
|
10
|
+
@value_keys ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def sorted_value_keys
|
14
|
+
value_keys.sort
|
15
|
+
end
|
16
|
+
|
17
|
+
def attr_reader_value(*keys)
|
18
|
+
keys.each { |k| value_keys << k.to_sym }
|
19
|
+
|
20
|
+
attr_reader(*keys)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
to_h.map { |k, v| "#{k}: #{v}" }.join(', ')
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_h
|
29
|
+
self.class.sorted_value_keys.to_h { |k| [k, send(k)] }
|
30
|
+
end
|
31
|
+
|
32
|
+
def [](key)
|
33
|
+
to_h[key]
|
34
|
+
end
|
35
|
+
|
36
|
+
def <=>(other)
|
37
|
+
all_sorted_values <=> other.all_sorted_values
|
38
|
+
end
|
39
|
+
|
40
|
+
def ==(other)
|
41
|
+
to_h == other.to_h
|
42
|
+
end
|
43
|
+
alias eql? ==
|
44
|
+
|
45
|
+
def hash
|
46
|
+
all_sorted_values.map(&:hash).hash
|
47
|
+
end
|
48
|
+
|
49
|
+
def all_sorted_values
|
50
|
+
self.class.sorted_value_keys.map { |k| self[k] }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/basketball/version.rb
CHANGED
data/lib/basketball.rb
CHANGED
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.
|
4
|
+
version: 0.0.3
|
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-05-
|
11
|
+
date: 2023-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faker
|
@@ -207,7 +207,6 @@ files:
|
|
207
207
|
- lib/basketball/drafting/cli.rb
|
208
208
|
- lib/basketball/drafting/engine.rb
|
209
209
|
- lib/basketball/drafting/engine_serializer.rb
|
210
|
-
- lib/basketball/drafting/entity.rb
|
211
210
|
- lib/basketball/drafting/event.rb
|
212
211
|
- lib/basketball/drafting/front_office.rb
|
213
212
|
- lib/basketball/drafting/pick_event.rb
|
@@ -217,6 +216,8 @@ files:
|
|
217
216
|
- lib/basketball/drafting/roster.rb
|
218
217
|
- lib/basketball/drafting/sim_event.rb
|
219
218
|
- lib/basketball/drafting/team.rb
|
219
|
+
- lib/basketball/entity.rb
|
220
|
+
- lib/basketball/value_object.rb
|
220
221
|
- lib/basketball/version.rb
|
221
222
|
homepage: https://github.com/mattruggio/basketball
|
222
223
|
licenses:
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Basketball
|
4
|
-
module Drafting
|
5
|
-
class Entity
|
6
|
-
extend Forwardable
|
7
|
-
include Comparable
|
8
|
-
|
9
|
-
attr_reader :id
|
10
|
-
|
11
|
-
def_delegators :id, :to_s
|
12
|
-
|
13
|
-
def initialize(id)
|
14
|
-
raise ArgumentError, 'id is required' if id.to_s.empty?
|
15
|
-
|
16
|
-
@id = id.to_s.upcase
|
17
|
-
end
|
18
|
-
|
19
|
-
def <=>(other)
|
20
|
-
id <=> other.id
|
21
|
-
end
|
22
|
-
|
23
|
-
def ==(other)
|
24
|
-
id == other.id
|
25
|
-
end
|
26
|
-
alias eql? ==
|
27
|
-
|
28
|
-
def hash
|
29
|
-
id.hash
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|