sorare-rewards 1.1.1 → 1.3.0.beta0
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/.gitlab-ci.yml +1 -1
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +28 -29
- data/README.md +26 -9
- data/lib/sorare/rewards/{picker.rb → card_picker.rb} +2 -2
- data/lib/sorare/rewards/game_week.rb +1 -14
- data/lib/sorare/rewards/game_week_config.rb +6 -0
- data/lib/sorare/rewards/game_week_rewards.rb +54 -0
- data/lib/sorare/rewards/interactors/build.rb +4 -5
- data/lib/sorare/rewards/interactors/cards/pick_for_division.rb +2 -2
- data/lib/sorare/rewards/interactors/cards/pick_for_division_and_rarity.rb +1 -1
- data/lib/sorare/rewards/interactors/cards/pick_for_game_week.rb +1 -1
- data/lib/sorare/rewards/interactors/cards/pick_for_league.rb +2 -2
- data/lib/sorare/rewards/interactors/pick.rb +3 -7
- data/lib/sorare/rewards/interactors/supply/compute_for_game_week.rb +2 -2
- data/lib/sorare/rewards/interactors/supply/compute_for_rarity.rb +21 -12
- data/lib/sorare/rewards/interactors/tiers/qualify_players.rb +3 -3
- data/lib/sorare/rewards/player.rb +10 -4
- data/lib/sorare/rewards/version.rb +1 -1
- data/sorare-rewards.gemspec +7 -7
- metadata +22 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f21a3d6ed4a19177ff92d64b89a4f605f76de64f3f7d1cc077d9d59a5f241c7c
|
4
|
+
data.tar.gz: cdfc9b29382f52800871f27533b1d5dcfa7795bc35c7f223d9a19f02287d245b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d4d20f37c3072805b4d6927936f959b7639ae0904fbd327e9aa709fd33d8c1360aa0d45d949402c250f57878bd06b19b8d1406d9a11999b62322c3d05276b8e
|
7
|
+
data.tar.gz: 6deb5eb9c375f07b3f6c20107155019782dc3fab546de56bf7979fc131a927077575822b5111235cd16bcc842b851f74524848bf12c4436c2f3514e738f6ae8b
|
data/.gitlab-ci.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
## [1.3.0] - 2021-11-02
|
2
|
+
### Breaking
|
3
|
+
- Removed rewards method from `GameWeek` (`card_rewards`, `cards_picked`, `reward_allocations`, `prize_pools`, `card_allocations`)
|
4
|
+
- `Picker` has been renamed to `CardPicker`
|
5
|
+
### Added
|
6
|
+
- Added a `GameWeekRewards` class that provides all rewards related methods
|
7
|
+
- Added a way to pick cards with a custom `card_allocations`
|
8
|
+
|
9
|
+
## [1.2.0] - 2021-11-02
|
10
|
+
### Added
|
11
|
+
- Enable cross leagues cooldown using `per_league` configuration flag
|
data/Gemfile.lock
CHANGED
@@ -1,40 +1,40 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
sorare-rewards (1.
|
5
|
-
activesupport (~> 6.1)
|
6
|
-
interactor (~> 3.
|
4
|
+
sorare-rewards (1.3.0.beta0)
|
5
|
+
activesupport (~> 6.1.4)
|
6
|
+
interactor (~> 3.1.2)
|
7
7
|
json (~> 2)
|
8
8
|
net-http (~> 0.1.1)
|
9
|
-
yaml (~> 0.
|
9
|
+
yaml (~> 0.2.0)
|
10
10
|
|
11
11
|
GEM
|
12
12
|
remote: https://rubygems.org/
|
13
13
|
specs:
|
14
|
-
activesupport (6.1.
|
14
|
+
activesupport (6.1.4.1)
|
15
15
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
16
16
|
i18n (>= 1.6, < 2)
|
17
17
|
minitest (>= 5.1)
|
18
18
|
tzinfo (~> 2.0)
|
19
19
|
zeitwerk (~> 2.3)
|
20
20
|
ast (2.4.2)
|
21
|
-
concurrent-ruby (1.1.
|
21
|
+
concurrent-ruby (1.1.9)
|
22
22
|
diff-lcs (1.4.4)
|
23
23
|
i18n (1.8.10)
|
24
24
|
concurrent-ruby (~> 1.0)
|
25
25
|
interactor (3.1.2)
|
26
26
|
io-wait (0.1.0)
|
27
|
-
json (2.
|
27
|
+
json (2.6.0)
|
28
28
|
minitest (5.14.4)
|
29
29
|
net-http (0.1.1)
|
30
30
|
net-protocol
|
31
31
|
uri
|
32
|
-
net-protocol (0.1.
|
32
|
+
net-protocol (0.1.2)
|
33
33
|
io-wait
|
34
34
|
timeout
|
35
|
-
ostruct (0.
|
36
|
-
parallel (1.
|
37
|
-
parser (3.0.
|
35
|
+
ostruct (0.4.0)
|
36
|
+
parallel (1.21.0)
|
37
|
+
parser (3.0.2.0)
|
38
38
|
ast (~> 2.4.1)
|
39
39
|
rainbow (3.0.0)
|
40
40
|
rake (12.3.3)
|
@@ -53,42 +53,41 @@ GEM
|
|
53
53
|
diff-lcs (>= 1.2.0, < 2.0)
|
54
54
|
rspec-support (~> 3.10.0)
|
55
55
|
rspec-support (3.10.2)
|
56
|
-
rubocop (1.
|
56
|
+
rubocop (1.22.1)
|
57
57
|
parallel (~> 1.10)
|
58
58
|
parser (>= 3.0.0.0)
|
59
59
|
rainbow (>= 2.2.2, < 4.0)
|
60
60
|
regexp_parser (>= 1.8, < 3.0)
|
61
61
|
rexml
|
62
|
-
rubocop-ast (>= 1.
|
62
|
+
rubocop-ast (>= 1.12.0, < 2.0)
|
63
63
|
ruby-progressbar (~> 1.7)
|
64
64
|
unicode-display_width (>= 1.4.0, < 3.0)
|
65
|
-
rubocop-ast (1.
|
66
|
-
parser (>=
|
67
|
-
rubocop-rake (0.
|
68
|
-
rubocop
|
69
|
-
rubocop-rspec (2.2.0)
|
65
|
+
rubocop-ast (1.12.0)
|
66
|
+
parser (>= 3.0.1.1)
|
67
|
+
rubocop-rake (0.6.0)
|
70
68
|
rubocop (~> 1.0)
|
71
|
-
|
69
|
+
rubocop-rspec (2.5.0)
|
70
|
+
rubocop (~> 1.19)
|
72
71
|
ruby-progressbar (1.11.0)
|
73
|
-
timeout (0.
|
72
|
+
timeout (0.2.0)
|
74
73
|
tzinfo (2.0.4)
|
75
74
|
concurrent-ruby (~> 1.0)
|
76
|
-
unicode-display_width (2.
|
77
|
-
uri (0.
|
78
|
-
yaml (0.
|
79
|
-
zeitwerk (2.
|
75
|
+
unicode-display_width (2.1.0)
|
76
|
+
uri (0.11.0)
|
77
|
+
yaml (0.2.0)
|
78
|
+
zeitwerk (2.5.0)
|
80
79
|
|
81
80
|
PLATFORMS
|
82
81
|
ruby
|
83
82
|
|
84
83
|
DEPENDENCIES
|
85
|
-
ostruct (~> 0.
|
84
|
+
ostruct (~> 0.4.0)
|
86
85
|
rake (~> 12.0)
|
87
86
|
rspec (~> 3.10)
|
88
|
-
rubocop (~> 1.
|
89
|
-
rubocop-rake (~> 0.
|
90
|
-
rubocop-rspec (~> 2.
|
87
|
+
rubocop (~> 1.22.1)
|
88
|
+
rubocop-rake (~> 0.6.0)
|
89
|
+
rubocop-rspec (~> 2.5.0)
|
91
90
|
sorare-rewards!
|
92
91
|
|
93
92
|
BUNDLED WITH
|
94
|
-
2.
|
93
|
+
2.2.22
|
data/README.md
CHANGED
@@ -10,11 +10,11 @@ gem 'sorare-rewards'
|
|
10
10
|
|
11
11
|
And then execute:
|
12
12
|
|
13
|
-
|
13
|
+
$ bundle install
|
14
14
|
|
15
15
|
Or install it yourself as:
|
16
16
|
|
17
|
-
|
17
|
+
$ gem install sorare-rewards
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
@@ -28,20 +28,37 @@ game_week = Sorare::Rewards::GameWeek.new(hash: 'QmbwCo1fuhRN1T2DyEQtETefsBH6yCj
|
|
28
28
|
Game Week's `hash` and `salt` can be retrieved using the GQL API, the salt is made public after the rewards have been distributed.
|
29
29
|
|
30
30
|
|
31
|
-
To compute
|
31
|
+
To compute rewards for a game week :
|
32
32
|
|
33
33
|
```ruby
|
34
|
-
|
35
|
-
game_week.card_allocations
|
34
|
+
rewards = Sorare::Rewards::GameWeekRewards.new(game_week: game_week)
|
36
35
|
|
37
|
-
#
|
38
|
-
|
36
|
+
# Cards allocations :
|
37
|
+
rewards.card_allocations
|
38
|
+
|
39
|
+
# Cards :
|
40
|
+
rewards.cards
|
41
|
+
|
42
|
+
# Prize pools :
|
43
|
+
rewards.prize_pools
|
39
44
|
```
|
40
45
|
|
41
|
-
|
46
|
+
By default it uses the computed card allocations to pick the rewards. To override it :
|
42
47
|
|
43
48
|
```ruby
|
44
|
-
|
49
|
+
card_allocations = {
|
50
|
+
'global_all-star' => {
|
51
|
+
'D1' => {
|
52
|
+
'rare' => {
|
53
|
+
'tier_0' => 1,
|
54
|
+
...
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
rewards = Sorare::Rewards::GameWeekRewards.new(game_week: game_week, card_allocations: card_allocations)
|
61
|
+
|
45
62
|
```
|
46
63
|
|
47
64
|
## Development
|
@@ -4,8 +4,8 @@ require 'active_support/core_ext/module/delegation'
|
|
4
4
|
|
5
5
|
module Sorare
|
6
6
|
module Rewards
|
7
|
-
#
|
8
|
-
class
|
7
|
+
# CardPicker allows to randomly pick a card
|
8
|
+
class CardPicker
|
9
9
|
attr_accessor :cards, :player_counter
|
10
10
|
|
11
11
|
delegate :length, to: :cards
|
@@ -6,13 +6,10 @@ require 'active_support/core_ext/module/delegation'
|
|
6
6
|
|
7
7
|
module Sorare
|
8
8
|
module Rewards
|
9
|
-
# GameWeek stores the
|
9
|
+
# GameWeek stores the data of a game week
|
10
10
|
class GameWeek
|
11
11
|
attr_reader :salt
|
12
12
|
|
13
|
-
delegate :card_allocations, :prize_pools, to: :reward_allocations
|
14
|
-
delegate :cards_picked, to: :card_rewards
|
15
|
-
|
16
13
|
def initialize(data: nil, hash: nil, salt: nil)
|
17
14
|
@uri = URI("#{Sorare::Rewards.configuration.gateway}#{hash}")
|
18
15
|
@data = data
|
@@ -48,16 +45,6 @@ module Sorare
|
|
48
45
|
end
|
49
46
|
end
|
50
47
|
|
51
|
-
def reward_allocations
|
52
|
-
raise 'Salt required' unless salt
|
53
|
-
|
54
|
-
@reward_allocations ||= Sorare::Rewards::Build.call!(game_week: self, salt: salt)
|
55
|
-
end
|
56
|
-
|
57
|
-
def card_rewards
|
58
|
-
@card_rewards ||= Sorare::Rewards::Pick.call!(reward_allocations.to_h)
|
59
|
-
end
|
60
|
-
|
61
48
|
def league(name)
|
62
49
|
raise 'Unknown league' unless (leagues || {})[name]
|
63
50
|
|
@@ -30,6 +30,12 @@ module Sorare
|
|
30
30
|
cooldown.dig(rarity, 'quantity')
|
31
31
|
end
|
32
32
|
|
33
|
+
def cooldown_per_league?(rarity)
|
34
|
+
per_league = cooldown.dig(rarity, 'per_league')
|
35
|
+
|
36
|
+
per_league.nil? ? true : per_league
|
37
|
+
end
|
38
|
+
|
33
39
|
def cooldown_since(rarity)
|
34
40
|
cooldown.dig(rarity, 'since')
|
35
41
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sorare
|
4
|
+
module Rewards
|
5
|
+
# GameWeekRewards stores rewards related data for a specified GameWeek, salt,
|
6
|
+
# And a card allocations hash
|
7
|
+
# {
|
8
|
+
# 'global-all_star' => {
|
9
|
+
# 'D1' => {
|
10
|
+
# 'rare' => { 'tier_0' => 0, 'tier_1' => 1 }
|
11
|
+
# }
|
12
|
+
# }
|
13
|
+
# }
|
14
|
+
class GameWeekRewards
|
15
|
+
attr_reader :game_week, :salt, :card_allocations
|
16
|
+
|
17
|
+
MISSING_PARAMETER = '%s parameter required'
|
18
|
+
|
19
|
+
def initialize(game_week:, salt: nil, card_allocations: nil)
|
20
|
+
@game_week = game_week
|
21
|
+
@salt = salt || game_week.salt
|
22
|
+
@card_allocations = card_allocations || computed_card_allocations
|
23
|
+
end
|
24
|
+
|
25
|
+
def cards
|
26
|
+
@cards ||= Sorare::Rewards::Pick.call!(
|
27
|
+
salt: salt,
|
28
|
+
game_week: game_week,
|
29
|
+
card_allocations: card_allocations
|
30
|
+
).cards_picked
|
31
|
+
end
|
32
|
+
|
33
|
+
def prize_pools
|
34
|
+
@prize_pools ||= reward_allocations.prize_pools
|
35
|
+
end
|
36
|
+
|
37
|
+
def reward_allocations
|
38
|
+
validate!(:salt)
|
39
|
+
|
40
|
+
@reward_allocations ||= Sorare::Rewards::Build.call!(game_week: game_week, salt: salt)
|
41
|
+
end
|
42
|
+
|
43
|
+
def computed_card_allocations
|
44
|
+
Transposer.transpose_allocations(reward_allocations.card_allocations)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def validate!(field)
|
50
|
+
raise format(MISSING_PARAMETER, field) unless send(field)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -8,27 +8,26 @@ module Sorare
|
|
8
8
|
class Build
|
9
9
|
include Interactor
|
10
10
|
|
11
|
-
delegate :game_week,
|
11
|
+
delegate :game_week, to: :context
|
12
12
|
|
13
13
|
def call
|
14
14
|
context.card_allocations = allocate!
|
15
15
|
context.prize_pools = prize_pools!
|
16
|
-
context.prize_pool_currency = game_week.config.prize_pool_currency
|
17
16
|
end
|
18
17
|
|
19
18
|
def game_week_supply
|
20
|
-
@game_week_supply ||= Supply::ComputeForGameWeek.call!(game_week: game_week
|
19
|
+
@game_week_supply ||= Supply::ComputeForGameWeek.call!(game_week: game_week)
|
21
20
|
.game_week_supply
|
22
21
|
end
|
23
22
|
|
24
23
|
def allocate!
|
25
24
|
Allocations::ComputeForGameWeek.call!(
|
26
|
-
|
25
|
+
supply: game_week_supply, public_seed: game_week.public_seed, salt: game_week.salt
|
27
26
|
).game_week_allocations
|
28
27
|
end
|
29
28
|
|
30
29
|
def prize_pools!
|
31
|
-
PrizePools::ComputeForGameWeek.call!(game_week: game_week
|
30
|
+
PrizePools::ComputeForGameWeek.call!(game_week: game_week).prize_pools
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|
@@ -10,8 +10,8 @@ module Sorare
|
|
10
10
|
# PickForDivision picks the rewards for a given division
|
11
11
|
# Receive a list of pickers for each tiers and quality
|
12
12
|
# {
|
13
|
-
# 'rare' => { 'tier_0' =>
|
14
|
-
# 'super_rare' => { 'tier_0' =>
|
13
|
+
# 'rare' => { 'tier_0' => CardPicker, 'tier_1' => CardPicker },
|
14
|
+
# 'super_rare' => { 'tier_0' => CardPicker, 'tier_1' => CardPicker }
|
15
15
|
# }
|
16
16
|
# And a reward allocations
|
17
17
|
# {
|
@@ -9,7 +9,7 @@ module Sorare
|
|
9
9
|
# PickForDivisionAndRarity picks the rewards for a given division and rarity
|
10
10
|
# Receive a list of pickers for each tiers
|
11
11
|
# {
|
12
|
-
# 'tier_0' =>
|
12
|
+
# 'tier_0' => CardPicker, 'tier_1' => CardPicker
|
13
13
|
# }
|
14
14
|
# A game week data
|
15
15
|
# And a reward allocations
|
@@ -17,7 +17,7 @@ module Sorare
|
|
17
17
|
class PickForLeague
|
18
18
|
include Interactor
|
19
19
|
|
20
|
-
delegate :
|
20
|
+
delegate :league, :allocations, :pickers, to: :context
|
21
21
|
delegate :game_week, to: :league
|
22
22
|
|
23
23
|
def call
|
@@ -48,7 +48,7 @@ module Sorare
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def initialize_tier_picker(players, rarity, tier)
|
51
|
-
pickers[rarity][tier] =
|
51
|
+
pickers[rarity][tier] = CardPicker.new(game_week.public_seed, game_week.salt)
|
52
52
|
|
53
53
|
players.each do |slug, _|
|
54
54
|
pickers[rarity][tier].add_player(slug, player_supply(rarity, slug))
|
@@ -11,8 +11,8 @@ module Sorare
|
|
11
11
|
# And a reward allocations
|
12
12
|
# {
|
13
13
|
# 'global-all_star' => {
|
14
|
-
# '
|
15
|
-
# '
|
14
|
+
# 'D1' => {
|
15
|
+
# 'rare' => { 'tier_0' => 0, 'tier_1' => 1 }
|
16
16
|
# }
|
17
17
|
# }
|
18
18
|
# }
|
@@ -27,13 +27,9 @@ module Sorare
|
|
27
27
|
context.cards_picked = Sorare::Rewards::Cards::PickForGameWeek.call!(
|
28
28
|
**context.to_h,
|
29
29
|
salt: salt,
|
30
|
-
allocations:
|
30
|
+
allocations: Sorare::Rewards::GameWeekAllocations.new(card_allocations)
|
31
31
|
).cards_picked
|
32
32
|
end
|
33
|
-
|
34
|
-
def transposed_allocations
|
35
|
-
Sorare::Rewards::GameWeekAllocations.new(Transposer.transpose_allocations(card_allocations))
|
36
|
-
end
|
37
33
|
end
|
38
34
|
end
|
39
35
|
end
|
@@ -10,7 +10,7 @@ module Sorare
|
|
10
10
|
class ComputeForGameWeek
|
11
11
|
include Interactor
|
12
12
|
|
13
|
-
delegate :
|
13
|
+
delegate :game_week, :game_week_supply, to: :context
|
14
14
|
|
15
15
|
def call
|
16
16
|
context.game_week_supply = game_week_supply!
|
@@ -31,7 +31,7 @@ module Sorare
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def randomizer
|
34
|
-
@randomizer ||= Sorare::Rewards::Random.new(game_week.public_seed, salt)
|
34
|
+
@randomizer ||= Sorare::Rewards::Random.new(game_week.public_seed, game_week.salt)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -21,37 +21,46 @@ module Sorare
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def rewardable_supply
|
24
|
-
total_float_supply = supply.keys.sum { |player|
|
24
|
+
total_float_supply = supply.keys.sum { |player| player_contribution(player) }
|
25
25
|
|
26
|
-
|
26
|
+
round_and_cap_league_supply(total_float_supply)
|
27
27
|
end
|
28
28
|
|
29
29
|
def distribute_in_tiers!
|
30
30
|
ctx = Tiers::QualifySupply.call!(sorted_supply: supply)
|
31
|
-
|
31
|
+
qualified_players = Tiers::QualifyPlayers.call!(sorted_supply: supply).players
|
32
|
+
ctx.supply.each_with_index do |tier_supply, index|
|
32
33
|
rarity_supply.push(
|
33
|
-
|
34
|
-
randomizer: randomizer,
|
35
|
-
total_supply: ctx.count,
|
36
|
-
tier_supply: tier_supply,
|
37
|
-
rewardable: rewardable,
|
38
|
-
rewarded: rarity_supply
|
39
|
-
).quality_supply
|
34
|
+
capped_tier_supply(ctx.count, tier_supply, rewardable, qualified_players[index])
|
40
35
|
)
|
41
36
|
end
|
42
37
|
end
|
43
38
|
|
44
|
-
|
39
|
+
# Cap with the actual pickable supply for the tier
|
40
|
+
def capped_tier_supply(total_supply, tier_supply, rewardable, tier_players)
|
41
|
+
target = ComputeForQuality.call!(
|
42
|
+
randomizer: randomizer, total_supply: total_supply,
|
43
|
+
tier_supply: tier_supply, rewardable: rewardable, rewarded: rarity_supply
|
44
|
+
).quality_supply
|
45
|
+
|
46
|
+
[target, tier_players.sum { |player| player_pickable_supply(player) }].min
|
47
|
+
end
|
48
|
+
|
49
|
+
def round_and_cap_league_supply(float_supply)
|
45
50
|
[
|
46
51
|
float_supply.floor + remaining_supply(float_supply.modulo(1)), # Supply limit
|
47
52
|
league.cards_in_circulation_limit(rarity) # Circulation limit
|
48
53
|
].compact.min
|
49
54
|
end
|
50
55
|
|
51
|
-
def
|
56
|
+
def player_contribution(slug)
|
52
57
|
game_week.player(slug).reward_pool_supply_contribution(league, rarity)
|
53
58
|
end
|
54
59
|
|
60
|
+
def player_pickable_supply(slug)
|
61
|
+
game_week.player(slug).pickable_supply(league, rarity)
|
62
|
+
end
|
63
|
+
|
55
64
|
def remaining_supply(reward_probability)
|
56
65
|
probability = randomizer.rand
|
57
66
|
return 0 unless probability < reward_probability
|
@@ -33,13 +33,13 @@ module Sorare
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def tier_depth
|
36
|
-
@tier_depth ||= sorted_supply.keys.length / (nb_of_tiers**2 - 1)
|
36
|
+
@tier_depth ||= sorted_supply.keys.length / ((nb_of_tiers**2) - 1)
|
37
37
|
end
|
38
38
|
|
39
39
|
def nb_of_tiers
|
40
40
|
@nb_of_tiers ||= begin
|
41
41
|
default = Sorare::Rewards.configuration.tiers
|
42
|
-
default -= 1 while (default**2 - 1) > sorted_supply.keys.length
|
42
|
+
default -= 1 while ((default**2) - 1) > sorted_supply.keys.length
|
43
43
|
|
44
44
|
default
|
45
45
|
end
|
@@ -49,7 +49,7 @@ module Sorare
|
|
49
49
|
return 0 unless tier.positive?
|
50
50
|
return sorted_supply.keys.length if tier == nb_of_tiers
|
51
51
|
|
52
|
-
tier_index(tier - 1) + tier_depth * tier_size(tier - 1)
|
52
|
+
tier_index(tier - 1) + (tier_depth * tier_size(tier - 1))
|
53
53
|
end
|
54
54
|
|
55
55
|
def tier_size(tier)
|
@@ -55,16 +55,22 @@ module Sorare
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def available_during_cooldown(league, rarity)
|
58
|
-
[@config.cooldown_limit(rarity) -
|
58
|
+
[@config.cooldown_limit(rarity) - rewarded_under_cooldown(league, rarity), 0].max
|
59
59
|
end
|
60
60
|
|
61
|
-
def
|
62
|
-
(
|
61
|
+
def rewarded_under_cooldown(league, rarity)
|
62
|
+
rewarded(league, rarity).count do |at|
|
63
63
|
(Time.parse(at) + @config.cooldown_since(rarity)) > Time.now
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
|
67
|
+
def rewarded(league, rarity)
|
68
|
+
return (@game_data&.dig(league.name, rarity) || []) if @config.cooldown_per_league?(rarity)
|
69
|
+
|
70
|
+
latest_rewarded&.dig(rarity) || []
|
71
|
+
end
|
72
|
+
|
73
|
+
%w[remaining_games_for_supply remaining_games latest_rewarded].each do |key|
|
68
74
|
define_method(key) do
|
69
75
|
@game_data&.dig(key)
|
70
76
|
end
|
data/sorare-rewards.gemspec
CHANGED
@@ -30,15 +30,15 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
31
|
spec.require_paths = ['lib']
|
32
32
|
|
33
|
-
spec.add_dependency 'activesupport', '~> 6.1'
|
34
|
-
spec.add_dependency 'interactor', '~> 3.
|
33
|
+
spec.add_dependency 'activesupport', '~> 6.1.4'
|
34
|
+
spec.add_dependency 'interactor', '~> 3.1.2'
|
35
35
|
spec.add_dependency 'json', '~> 2'
|
36
36
|
spec.add_dependency 'net-http', '~> 0.1.1'
|
37
|
-
spec.add_dependency 'yaml', '~> 0.
|
38
|
-
spec.add_development_dependency 'ostruct', '~> 0.
|
37
|
+
spec.add_dependency 'yaml', '~> 0.2.0'
|
38
|
+
spec.add_development_dependency 'ostruct', '~> 0.4.0'
|
39
39
|
spec.add_development_dependency 'rspec', '~> 3.10'
|
40
|
-
spec.add_development_dependency 'rubocop', '~> 1.
|
41
|
-
spec.add_development_dependency 'rubocop-rake', '~> 0.
|
42
|
-
spec.add_development_dependency 'rubocop-rspec', '~> 2.
|
40
|
+
spec.add_development_dependency 'rubocop', '~> 1.22.1'
|
41
|
+
spec.add_development_dependency 'rubocop-rake', '~> 0.6.0'
|
42
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.5.0'
|
43
43
|
end
|
44
44
|
# rubocop:enable Metrics/BlockLength
|
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
|
+
version: 1.3.0.beta0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pierre
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 6.1.4
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 6.1.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: interactor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 3.1.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 3.1.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: json
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,28 +72,28 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.2.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: 0.2.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: ostruct
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
89
|
+
version: 0.4.0
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
96
|
+
version: 0.4.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,42 +114,42 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 1.
|
117
|
+
version: 1.22.1
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 1.
|
124
|
+
version: 1.22.1
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: rubocop-rake
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 0.
|
131
|
+
version: 0.6.0
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 0.
|
138
|
+
version: 0.6.0
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: rubocop-rspec
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 2.
|
145
|
+
version: 2.5.0
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 2.
|
152
|
+
version: 2.5.0
|
153
153
|
description:
|
154
154
|
email:
|
155
155
|
- pierre@sorare.com
|
@@ -161,6 +161,7 @@ files:
|
|
161
161
|
- ".gitlab-ci.yml"
|
162
162
|
- ".rspec"
|
163
163
|
- ".rubocop.yml"
|
164
|
+
- CHANGELOG.md
|
164
165
|
- Gemfile
|
165
166
|
- Gemfile.lock
|
166
167
|
- LICENSE.txt
|
@@ -171,10 +172,12 @@ files:
|
|
171
172
|
- data.patch
|
172
173
|
- lib/sorare/rewards.rb
|
173
174
|
- lib/sorare/rewards/allocation_configuration.yml
|
175
|
+
- lib/sorare/rewards/card_picker.rb
|
174
176
|
- lib/sorare/rewards/configuration.rb
|
175
177
|
- lib/sorare/rewards/game_week.rb
|
176
178
|
- lib/sorare/rewards/game_week_allocations.rb
|
177
179
|
- lib/sorare/rewards/game_week_config.rb
|
180
|
+
- lib/sorare/rewards/game_week_rewards.rb
|
178
181
|
- lib/sorare/rewards/interactor.rb
|
179
182
|
- lib/sorare/rewards/interactors/allocations/compute_for_game_week.rb
|
180
183
|
- lib/sorare/rewards/interactors/allocations/compute_for_league.rb
|
@@ -196,7 +199,6 @@ files:
|
|
196
199
|
- lib/sorare/rewards/interactors/tiers/qualify_players.rb
|
197
200
|
- lib/sorare/rewards/interactors/tiers/qualify_supply.rb
|
198
201
|
- lib/sorare/rewards/league.rb
|
199
|
-
- lib/sorare/rewards/picker.rb
|
200
202
|
- lib/sorare/rewards/player.rb
|
201
203
|
- lib/sorare/rewards/prize_pool_configuration.yml
|
202
204
|
- lib/sorare/rewards/random.rb
|
@@ -220,11 +222,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
220
222
|
version: 2.7.1
|
221
223
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
222
224
|
requirements:
|
223
|
-
- - "
|
225
|
+
- - ">"
|
224
226
|
- !ruby/object:Gem::Version
|
225
|
-
version:
|
227
|
+
version: 1.3.1
|
226
228
|
requirements: []
|
227
|
-
rubygems_version: 3.
|
229
|
+
rubygems_version: 3.2.22
|
228
230
|
signing_key:
|
229
231
|
specification_version: 4
|
230
232
|
summary: '["Sorare", "reward", "allocation", "algorithm"]'
|