sorare-rewards 1.4.8 → 1.6.0

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: d6cf28260c062178e86145831e78dc6df1698d0dd5da71b9e912c43ad3490819
4
- data.tar.gz: b8568cee0173df5c1f6682f6ebc8381e10102bb4a1bee09ff11836098e6be6fa
3
+ metadata.gz: 7fdc6ffec6880ea7d786427427f64c3a360eddf15fc6b9d1fc116e714ba14c28
4
+ data.tar.gz: d65afecddd570ddcce250d98142dfa0928a85759afc2ab2b6be01f80ab51ee99
5
5
  SHA512:
6
- metadata.gz: c3e88fbd0e0075431410adfa570d3f491039eb7172a933cce94cfded653dfe6f03599c73f35c7caaf5a49964e6235e3ae2d761f316f4ad7278b4c84641a7aab6
7
- data.tar.gz: 6df7258e3b292a6ea86cf36d0602c08c4e8762c89629d50928fbc69feac19ac1c05fc2fc8dfcec6650c73f4067b573e15512967e0c52161d7312d33b53a0a722
6
+ metadata.gz: f1f39c17511050c7870261c524707001b48897d79d0ee1ab19fe699b8165202fce4345a62574d69132dfab3d81bf95000963af4b5318d4a8815b6c7b412e7d5d
7
+ data.tar.gz: d5a363cf277ecf27fa0f18a2ac3cb4e6f2eae071088985b53536b5ccbafb2761b1864678b250c996f6e79735bfee1407e646094fa9220e050656c02564bf2ef1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [1.6.0] - 2022-08-12
2
+
3
+ ### Added
4
+
5
+ - Expose `rarity_limit` and `cooldown_limit` on `GameWeekRewards`
6
+
7
+ ## [1.5.0] - 2022-03-07
8
+
9
+ ### Added
10
+
11
+ - Expose `CardPicker` as `picker_of(rarity, tier, **args)` on `League`. `args` can be used to toggle off `rarity_limit` and `cooldown_limit`
12
+
1
13
  ## [1.4.1] - 2021-12-14
2
14
 
3
15
  ### Fixes
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sorare-rewards (1.4.7)
4
+ sorare-rewards (1.6.0)
5
5
  activesupport (>= 6.1.4)
6
6
  interactor_with_steroids (>= 1.0.0)
7
7
  json (~> 2)
@@ -10,7 +10,7 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (7.0.1)
13
+ activesupport (7.0.2.2)
14
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
15
15
  i18n (>= 1.6, < 2)
16
16
  minitest (>= 5.1)
@@ -23,7 +23,7 @@ GEM
23
23
  rexml
24
24
  diff-lcs (1.4.4)
25
25
  hashdiff (1.0.1)
26
- i18n (1.9.1)
26
+ i18n (1.10.0)
27
27
  concurrent-ruby (~> 1.0)
28
28
  interactor_with_steroids (1.1.2)
29
29
  activesupport
@@ -1,39 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/module/delegation'
3
+ require './lib/sorare/rewards/flat_picker'
4
4
 
5
5
  module Sorare
6
6
  module Rewards
7
- # CardPicker allows to randomly pick a card
8
- class CardPicker
9
- attr_accessor :cards, :player_counter
10
-
11
- delegate :length, to: :cards
7
+ # CardPicker allows to randomly pick card rewards for a league
8
+ class CardPicker < FlatPicker
9
+ attr_reader :league, :rarity, :quality, :limits
10
+
11
+ def initialize(league, rarity, quality, rarity_limit: true, cooldown_limit: true)
12
+ super(league.public_seed, league.salt)
13
+ @league = league
14
+ @rarity = rarity
15
+ @quality = quality
16
+ @limits = %i[overall].tap do |l|
17
+ l << :cooldowned if cooldown_limit
18
+ l << :limited if rarity_limit
19
+ end
12
20
 
13
- def initialize(seed, salt)
14
- @random = Random.new(seed, salt)
15
- @cards = []
16
- @player_counter = Hash.new(0)
17
- @shuffled = false
21
+ load_picker
18
22
  end
19
23
 
20
- def add_player(slug, count)
21
- raise "Can't add a player to a started draw" if @shuffled
24
+ def pick
25
+ player = super
26
+ return player if valid_pick?(player)
22
27
 
23
- @cards += Array.new(count, slug)
28
+ pick
24
29
  end
25
30
 
26
- def pick
27
- shuffle! unless @shuffled
31
+ def valid_pick?(player)
32
+ current_player_limit = limits.map { |l| supply_for(player).send(l) }.min
33
+ picked_count(player) <= current_player_limit
34
+ end
28
35
 
29
- @cards.shift.tap do |card|
30
- @player_counter[card] += 1 if card
31
- end
36
+ private
37
+
38
+ def supply_for(player_slug)
39
+ league.game_week.player(player_slug).supply_for(league, rarity)
32
40
  end
33
41
 
34
- def shuffle!
35
- @cards.shuffle!(random: @random)
36
- @shuffled = true
42
+ def load_picker
43
+ league.qualified_supply(rarity, quality).each do |player_slug|
44
+ add(player_slug, supply_for(player_slug).overall)
45
+ end
37
46
  end
38
47
  end
39
48
  end
@@ -11,7 +11,7 @@ module Sorare
11
11
 
12
12
  def initialize
13
13
  @tiers = 4
14
- @gateway = 'https://gateway.pinata.cloud/ipfs/'
14
+ @gateway = 'https://sorare.mypinata.cloud/ipfs/'
15
15
  @transform_tier = ->(tier) { "tier_#{tier}" }
16
16
  @transform_division = ->(division) { "D#{division}" }
17
17
  @allocation_configuration = load_yaml_configuration_file('allocation_configuration.yml')['leagues']
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/module/delegation'
4
+
5
+ module Sorare
6
+ module Rewards
7
+ # FlatPicker allows to randomly pick an element in a flat array
8
+ class FlatPicker
9
+ attr_accessor :elements, :counter
10
+
11
+ class NoSupplyError < StandardError; end
12
+
13
+ delegate :length, to: :elements
14
+
15
+ def initialize(seed, salt)
16
+ @random = Random.new(seed, salt)
17
+ @elements = []
18
+ @counter = Hash.new(0)
19
+ @shuffled = false
20
+ end
21
+
22
+ def add(slug, count)
23
+ raise "Can't add an element to a started draw" if @shuffled
24
+
25
+ @elements += Array.new(count, slug)
26
+ end
27
+
28
+ def pick
29
+ shuffle! unless @shuffled
30
+
31
+ @elements.shift.tap do |element|
32
+ @counter[element] += 1 if element
33
+ end
34
+ end
35
+
36
+ def pick!
37
+ pick.tap do |picked|
38
+ raise NoSupplyError unless picked
39
+ end
40
+ end
41
+
42
+ def picked_count(element)
43
+ @counter[element]
44
+ end
45
+
46
+ private
47
+
48
+ def shuffle!
49
+ return if @shuffled
50
+
51
+ @elements.shuffle!(random: @random)
52
+ @shuffled = true
53
+ end
54
+ end
55
+ end
56
+ end
@@ -56,6 +56,14 @@ module Sorare
56
56
  def player(slug)
57
57
  Player.new(slug, self)
58
58
  end
59
+
60
+ def inspect
61
+ format('#<%<class>s %<data>s>', { class: self.class.name, data: { loaded: loaded?, hash: hash, salt: salt } })
62
+ end
63
+
64
+ def loaded?
65
+ data.present?
66
+ end
59
67
  end
60
68
  end
61
69
  end
@@ -12,21 +12,25 @@ module Sorare
12
12
  # }
13
13
  # }
14
14
  class GameWeekRewards
15
- attr_reader :game_week, :salt, :card_allocations
15
+ attr_reader :game_week, :salt, :card_allocations, :rarity_limit, :cooldown_limit
16
16
 
17
17
  MISSING_PARAMETER = '%s parameter required'
18
18
 
19
- def initialize(game_week:, salt: nil, card_allocations: nil)
19
+ def initialize(game_week:, salt: nil, card_allocations: nil, rarity_limit: true, cooldown_limit: true)
20
20
  @game_week = game_week
21
21
  @salt = salt || game_week.salt
22
22
  @card_allocations = card_allocations || computed_card_allocations
23
+ @rarity_limit = rarity_limit
24
+ @cooldown_limit = cooldown_limit
23
25
  end
24
26
 
25
27
  def cards
26
28
  @cards ||= Sorare::Rewards::Pick.call!(
27
29
  salt: salt,
28
30
  game_week: game_week,
29
- card_allocations: card_allocations
31
+ card_allocations: card_allocations,
32
+ rarity_limit: rarity_limit,
33
+ cooldown_limit: cooldown_limit
30
34
  ).cards_picked
31
35
  end
32
36
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'active_support/concern'
4
4
  require 'interactor'
5
+ require './lib/sorare/rewards/interactors/concerns/with_picker_options'
5
6
 
6
7
  module Sorare
7
8
  module Rewards
@@ -7,13 +7,8 @@ require 'yaml'
7
7
  module Sorare
8
8
  module Rewards
9
9
  module Cards
10
- # PickForDivision picks the rewards for a given division
11
- # Receive a list of pickers for each tiers and quality
12
- # {
13
- # 'rare' => { 'tier_0' => CardPicker, 'tier_1' => CardPicker },
14
- # 'super_rare' => { 'tier_0' => CardPicker, 'tier_1' => CardPicker }
15
- # }
16
- # And a reward allocations
10
+ # PickForDivision picks the rewards for a given league
11
+ # And a division reward allocations
17
12
  # {
18
13
  # 'rare' => [5, 15, 0, 0],
19
14
  # 'super_rare' => [1, 4, 0, 0],
@@ -21,8 +16,9 @@ module Sorare
21
16
  # }
22
17
  class PickForDivision
23
18
  include Interactor
19
+ include WithPickerOptions
24
20
 
25
- receive :league, :allocations, :pickers
21
+ receive :league, :allocations
26
22
  hold :cards_picked
27
23
 
28
24
  def call
@@ -30,7 +26,6 @@ module Sorare
30
26
  PickForDivisionAndRarity.call!(
31
27
  **context.to_h,
32
28
  rarity: rarity,
33
- pickers: pickers[rarity],
34
29
  allocations: allocations[rarity]
35
30
  ).cards_picked
36
31
  end
@@ -7,17 +7,14 @@ module Sorare
7
7
  module Rewards
8
8
  module Cards
9
9
  # PickForDivisionAndRarity picks the rewards for a given division and rarity
10
- # Receive a list of pickers for each tiers
11
- # {
12
- # 'tier_0' => CardPicker, 'tier_1' => CardPicker
13
- # }
14
10
  # A game week data
15
11
  # And a reward allocations
16
12
  # { 'tier_0' => 1, 'tier_1' => 2 }
17
13
  class PickForDivisionAndRarity
18
14
  include Interactor
15
+ include WithPickerOptions
19
16
 
20
- receive :league, :rarity, :allocations, :pickers
17
+ receive :league, :rarity, :allocations
21
18
  hold :cards_picked
22
19
 
23
20
  def call
@@ -26,10 +23,12 @@ module Sorare
26
23
 
27
24
  def supply!
28
25
  allocations.keys.index_with do |tier|
29
- next [] if pickers&.dig(tier).nil?
26
+ picker = league.picker_of(rarity, tier, rarity_limit: rarity_limit, cooldown_limit: cooldown_limit)
27
+ next [] unless picker
30
28
 
31
- PickForDivisionRarityAndQuality.call!(**context.to_h, allocations: allocations[tier],
32
- picker: pickers[tier]).cards_picked
29
+ PickForDivisionRarityAndQuality.call!(
30
+ **context.to_h, allocations: allocations[tier], picker: picker
31
+ ).cards_picked
33
32
  end
34
33
  end
35
34
  end
@@ -34,7 +34,7 @@ module Sorare
34
34
 
35
35
  def pick_if_available!
36
36
  player = picker.pick
37
- return if picker.player_counter[player] > game_week.player(player).pickable_supply(league, rarity)
37
+ return if picker.picked_count(player) > game_week.player(player).supply_for(league, rarity).available
38
38
 
39
39
  cards_picked.push(player)
40
40
  end
@@ -18,6 +18,7 @@ module Sorare
18
18
  # }
19
19
  class PickForGameWeek
20
20
  include Interactor
21
+ include WithPickerOptions
21
22
 
22
23
  receive :game_week, :allocations
23
24
  hold :cards_picked
@@ -16,51 +16,21 @@ module Sorare
16
16
  # }
17
17
  class PickForLeague
18
18
  include Interactor
19
+ include WithPickerOptions
19
20
 
20
21
  receive :league, :allocations
21
- hold :pickers, :cards_picked
22
+ hold :cards_picked
22
23
 
23
24
  delegate :game_week, to: :league
24
25
  delegate :public_seed, :salt, to: :game_week
25
26
 
26
27
  def call
27
- context.pickers = {}
28
- add_pickers!
29
-
30
28
  context.cards_picked = allocations.keys.index_with do |division|
31
29
  PickForDivision.call!(
32
- **context.to_h, pickers: pickers, allocations: allocations[division]
30
+ **context.to_h, allocations: allocations[division]
33
31
  ).cards_picked
34
32
  end
35
33
  end
36
-
37
- def add_pickers!
38
- league.supply.keys.index_with do |rarity|
39
- pickers[rarity] = {}
40
- qualify_and_add!(rarity)
41
- end
42
- end
43
-
44
- def qualify_and_add!(rarity)
45
- sorted_supply = league.supply[rarity]
46
- qualified_players = Tiers::QualifyPlayers.call!(sorted_supply: sorted_supply).players
47
- qualified_players.each_with_index.map do |players, tier|
48
- transformed_tier = Sorare::Rewards.configuration.transform_tier.call(tier)
49
- initialize_tier_picker(players, rarity, transformed_tier)
50
- end
51
- end
52
-
53
- def initialize_tier_picker(players, rarity, tier)
54
- pickers[rarity][tier] = CardPicker.new(public_seed, salt)
55
-
56
- players.each do |slug, _|
57
- pickers[rarity][tier].add_player(slug, player_supply(rarity, slug))
58
- end
59
- end
60
-
61
- def player_supply(rarity, slug)
62
- game_week.player(slug).overall_supply(league, rarity)
63
- end
64
34
  end
65
35
  end
66
36
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+
5
+ module Sorare
6
+ module Rewards
7
+ # WithPickerOptions is included by interactor that takes picker options as a parameter
8
+ module WithPickerOptions
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ receive rarity_limit: true, cooldown_limit: true
13
+ end
14
+ end
15
+ end
16
+ end
@@ -55,11 +55,11 @@ module Sorare
55
55
  end
56
56
 
57
57
  def player_contribution(slug)
58
- game_week.player(slug).reward_pool_supply_contribution(league, rarity)
58
+ game_week.player(slug).supply_for(league, rarity).pool_contribution
59
59
  end
60
60
 
61
61
  def player_pickable_supply(slug)
62
- game_week.player(slug).pickable_supply(league, rarity)
62
+ game_week.player(slug).supply_for(league, rarity).available
63
63
  end
64
64
 
65
65
  def remaining_supply(reward_probability)
@@ -8,7 +8,7 @@ module Sorare
8
8
  class League
9
9
  attr_reader :name, :supply, :config, :game_week
10
10
 
11
- delegate :salt, to: :game_week
11
+ delegate :salt, :public_seed, to: :game_week
12
12
 
13
13
  def initialize(name:, config:, supply:, game_week:)
14
14
  @name = name
@@ -54,16 +54,32 @@ module Sorare
54
54
  end
55
55
 
56
56
  def each_rarity_tier_supply
57
- each_rarity_supply do |rarity, rarity_supply|
58
- qualified_supply = Tiers::QualifyPlayers.call!(sorted_supply: rarity_supply).players
59
- qualified_supply.each_key.map do |tier|
57
+ each_rarity_supply do |rarity, _|
58
+ qualified_supply(rarity).each do |tier, qualified_supply|
60
59
  return to_enum(:each_rarity_tier_supply) unless block_given?
61
60
 
62
- transformed_tier = Sorare::Rewards.configuration.transform_tier.call(tier)
63
- yield(rarity, transformed_tier, qualified_supply[tier])
61
+ yield(rarity, tier, qualified_supply)
64
62
  end
65
63
  end
66
64
  end
65
+
66
+ def qualified_supply(rarity, tier = nil)
67
+ @qualified_supplies ||= {}
68
+ @qualified_supplies[rarity] ||= Tiers::QualifyPlayers.call!(sorted_supply: supply[rarity]).players
69
+ .each_with_index.to_h do |supply, supply_tier|
70
+ [Sorare::Rewards.configuration.transform_tier.call(supply_tier), supply]
71
+ end
72
+ tier ? @qualified_supplies[rarity][tier] : @qualified_supplies[rarity]
73
+ end
74
+
75
+ def picker_of(rarity, tier, **kwargs)
76
+ scenario = kwargs.sort.to_h.to_json
77
+
78
+ @pickers ||= {}
79
+ @pickers[rarity] ||= {}
80
+ @pickers[rarity][tier] ||= {}
81
+ @pickers[rarity][tier][scenario] ||= CardPicker.new(self, rarity, tier, **kwargs)
82
+ end
67
83
  end
68
84
  end
69
85
  end
@@ -7,7 +7,21 @@ module Sorare
7
7
  module Rewards
8
8
  # Player stores the reward data of a player for a game week
9
9
  class Player
10
- attr_reader :slug
10
+ attr_reader :slug, :supply
11
+
12
+ Supply = Struct.new(:overall, :projected, :cooldowned, :limited, keyword_init: true) do
13
+ def initialize(overall: 0, projected: 0, cooldowned: 0, limited: 0)
14
+ super(overall: overall, projected: projected, cooldowned: cooldowned, limited: limited)
15
+ end
16
+
17
+ def pool_contribution
18
+ [projected, available].min || 0
19
+ end
20
+
21
+ def available
22
+ [overall, cooldowned, limited].min || 0
23
+ end
24
+ end
11
25
 
12
26
  def initialize(slug, reward_data)
13
27
  @slug = slug
@@ -17,45 +31,22 @@ module Sorare
17
31
  load_supply(reward_data)
18
32
  end
19
33
 
20
- def rewardable?(league, rarity)
21
- !@config.cooldown?(rarity, @game_data.dig(league, rarity) || [])
34
+ %w[remaining_games_for_supply remaining_games latest_rewarded].each do |key|
35
+ define_method(key) do
36
+ @game_data&.dig(key)
37
+ end
22
38
  end
23
39
 
24
40
  def playing?
25
41
  @game_data.present?
26
42
  end
27
43
 
28
- def reward_pool_supply_contribution(league, rarity)
29
- return 0 unless playing? && remaining_games_for_supply.positive?
30
-
31
- [
32
- uncapped_supply_for_game_week(league, rarity),
33
- pickable_supply(league, rarity)
34
- ].min
35
- end
36
-
37
- def pickable_supply(league, rarity)
38
- [
39
- overall_supply(league, rarity), # Remaining supply
40
- available_during_cooldown(league, rarity), # Cooldown limit
41
- @config.distribution_limit(rarity) # Hard limit
42
- ].min
43
- end
44
-
45
44
  def rank(league, rarity)
46
45
  @supply.dig(league.name, rarity, 'rank')
47
46
  end
48
47
 
49
- def overall_supply(league, rarity)
50
- @supply.dig(league.name, rarity, 'supply') || 0
51
- end
52
-
53
- def uncapped_supply_for_game_week(league, rarity)
54
- overall_supply(league, rarity) / remaining_games_for_supply.to_f
55
- end
56
-
57
- def available_during_cooldown(league, rarity)
58
- [@config.cooldown_limit(rarity) - rewarded_under_cooldown(league, rarity), 0].max
48
+ def supply_for(league, rarity)
49
+ supply.dig(league.name, rarity, 'supply') || Supply.new
59
50
  end
60
51
 
61
52
  def rewarded_under_cooldown(league, rarity)
@@ -64,28 +55,45 @@ module Sorare
64
55
  end
65
56
  end
66
57
 
67
- def rewarded(league, rarity)
68
- return (@game_data&.dig(league.name, rarity) || []) if @config.cooldown_per_league?(rarity)
58
+ private
69
59
 
70
- latest_rewarded&.dig(rarity) || []
60
+ def load_supply(reward_data)
61
+ reward_data.each_league do |league|
62
+ league.each_rarity_supply do |rarity, league_supply|
63
+ next unless league_supply[slug]
64
+
65
+ player_cards = league_supply.dig(slug, 'supply') || 0
66
+ @supply[league.name][rarity] = {
67
+ **league_supply[slug],
68
+ supply: parse_supply(league, rarity, player_cards)
69
+ }.with_indifferent_access
70
+ end
71
+ end
71
72
  end
72
73
 
73
- %w[remaining_games_for_supply remaining_games latest_rewarded].each do |key|
74
- define_method(key) do
75
- @game_data&.dig(key)
76
- end
74
+ def parse_supply(league, rarity, total_cards)
75
+ Supply.new(
76
+ overall: total_cards,
77
+ projected: projected_for_game_week(total_cards),
78
+ cooldowned: available_during_cooldown(league, rarity),
79
+ limited: @config.distribution_limit(rarity)
80
+ )
77
81
  end
78
82
 
79
- private
83
+ def projected_for_game_week(total_cards)
84
+ return 0 unless playing? && remaining_games_for_supply.positive?
80
85
 
81
- def load_supply(reward_data)
82
- reward_data.each_league do |league|
83
- league.each_rarity_supply do |rarity, supply|
84
- next unless supply[slug]
86
+ total_cards / remaining_games_for_supply.to_f
87
+ end
85
88
 
86
- @supply[league.name][rarity] = supply[slug]
87
- end
88
- end
89
+ def available_during_cooldown(league, rarity)
90
+ [@config.cooldown_limit(rarity) - rewarded_under_cooldown(league, rarity), 0].max
91
+ end
92
+
93
+ def rewarded(league, rarity)
94
+ return (@game_data&.dig(league.name, rarity) || []) if @config.cooldown_per_league?(rarity)
95
+
96
+ latest_rewarded&.dig(rarity) || []
89
97
  end
90
98
  end
91
99
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sorare
4
4
  module Rewards
5
- VERSION = '1.4.8'
5
+ VERSION = '1.6.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorare-rewards
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.8
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sorare team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-22 00:00:00.000000000 Z
11
+ date: 2022-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -174,6 +174,7 @@ files:
174
174
  - lib/sorare/rewards/allocation_configuration.yml
175
175
  - lib/sorare/rewards/card_picker.rb
176
176
  - lib/sorare/rewards/configuration.rb
177
+ - lib/sorare/rewards/flat_picker.rb
177
178
  - lib/sorare/rewards/game_week.rb
178
179
  - lib/sorare/rewards/game_week_allocations.rb
179
180
  - lib/sorare/rewards/game_week_config.rb
@@ -189,6 +190,7 @@ files:
189
190
  - lib/sorare/rewards/interactors/cards/pick_for_division_rarity_and_quality.rb
190
191
  - lib/sorare/rewards/interactors/cards/pick_for_game_week.rb
191
192
  - lib/sorare/rewards/interactors/cards/pick_for_league.rb
193
+ - lib/sorare/rewards/interactors/concerns/with_picker_options.rb
192
194
  - lib/sorare/rewards/interactors/pick.rb
193
195
  - lib/sorare/rewards/interactors/prize_pools/compute_for_division.rb
194
196
  - lib/sorare/rewards/interactors/prize_pools/compute_for_game_week.rb