killer_queen_scene_scoring 0.3.1 → 0.3.2
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/Gemfile.lock +1 -1
- data/lib/killer_queen_scene_scoring.rb +1 -4
- data/lib/killer_queen_scene_scoring/base.rb +43 -0
- data/lib/killer_queen_scene_scoring/bracket.rb +23 -23
- data/lib/killer_queen_scene_scoring/config.rb +2 -0
- data/lib/killer_queen_scene_scoring/tournament.rb +11 -19
- data/lib/killer_queen_scene_scoring/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f2624dd8d6e07571ec2723fdf15598e2cbe1e8b2538559bec4b7a1855aadb546
|
|
4
|
+
data.tar.gz: 8fa7d60d1cee314eadc18a4253a2928a61d2eb31b83b30f662f3b3166f4fdc37
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 41e3e9de1c70de42055ce87e3c1287d6927364aefb9cb035b04e7e20ef889828a5120655e49fe795864bc1c686cd9ad9e6d64bdb48d2839f337011ef91213ee4
|
|
7
|
+
data.tar.gz: 7f5fc09649d1681840b1f90e39eff167672c823a2b75de38e0b43332fa7f0bb6335d9ff660a415e3cf08daeaa1980e6205a43aa72e5fa2367d875a9f04c84808
|
data/Gemfile.lock
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require "dotenv/load"
|
|
2
2
|
require "json"
|
|
3
3
|
require "rest-client"
|
|
4
|
+
require "killer_queen_scene_scoring/base.rb"
|
|
4
5
|
require "killer_queen_scene_scoring/bracket.rb"
|
|
5
6
|
require "killer_queen_scene_scoring/config"
|
|
6
7
|
require "killer_queen_scene_scoring/match"
|
|
@@ -11,8 +12,4 @@ require "killer_queen_scene_scoring/tournament"
|
|
|
11
12
|
require "killer_queen_scene_scoring/version"
|
|
12
13
|
|
|
13
14
|
module KillerQueenSceneScoring
|
|
14
|
-
# Creates a hash whose values are arrays.
|
|
15
|
-
def self.hash_of_arrays
|
|
16
|
-
Hash.new { |h, k| h[k] = [] }
|
|
17
|
-
end
|
|
18
15
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KillerQueenSceneScoring
|
|
4
|
+
|
|
5
|
+
class Base
|
|
6
|
+
attr_reader :api_key, :logger
|
|
7
|
+
|
|
8
|
+
def initialize(api_key, logger = nil)
|
|
9
|
+
@api_key = api_key
|
|
10
|
+
|
|
11
|
+
@logger = case logger
|
|
12
|
+
when true
|
|
13
|
+
Logger.new(STDOUT, progname: "KillerQueenSceneScoring")
|
|
14
|
+
when Logger
|
|
15
|
+
logger
|
|
16
|
+
else
|
|
17
|
+
nil
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Creates a hash whose values are arrays.
|
|
22
|
+
def hash_of_arrays
|
|
23
|
+
Hash.new { |h, k| h[k] = [] }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def log_debug(msg)
|
|
27
|
+
@logger&.debug msg
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def log_info(msg)
|
|
31
|
+
@logger&.info msg
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def log_warn(msg)
|
|
35
|
+
@logger&.warn msg
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def log_error(msg)
|
|
39
|
+
@logger&.error msg
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module KillerQueenSceneScoring
|
|
4
4
|
|
|
5
|
-
class Bracket
|
|
5
|
+
class Bracket < Base
|
|
6
6
|
attr_reader :players, :config
|
|
7
7
|
|
|
8
8
|
# `id` can be the slug or the challonge ID of the bracket. If you pass a
|
|
9
9
|
# and the bracket is owned by an organization, it must be of the form
|
|
10
10
|
# "<org name>-<slug>". `api_key` is your Challonge API key.
|
|
11
11
|
def initialize(id:, api_key:, logger:)
|
|
12
|
+
super(api_key, logger)
|
|
13
|
+
|
|
12
14
|
@id = id
|
|
13
|
-
@api_key = api_key
|
|
14
|
-
@logger = logger
|
|
15
15
|
@loaded = false
|
|
16
16
|
@state == ""
|
|
17
17
|
end
|
|
@@ -32,7 +32,7 @@ class Bracket
|
|
|
32
32
|
rescue RestClient::NotFound
|
|
33
33
|
# Bail out if we got a 404 error. The bracket doesn't exist on
|
|
34
34
|
# Challonge right now, but it might be created in the future.
|
|
35
|
-
|
|
35
|
+
log_warn "The bracket does not exist."
|
|
36
36
|
return false
|
|
37
37
|
end
|
|
38
38
|
|
|
@@ -49,7 +49,7 @@ class Bracket
|
|
|
49
49
|
# bracket, and set `next_bracket` in the wild card bracket to the ID
|
|
50
50
|
# of the finals bracket before the wild card bracket has finished.
|
|
51
51
|
if @challonge_bracket.started_at.nil?
|
|
52
|
-
|
|
52
|
+
log_warn "The bracket has not been started yet."
|
|
53
53
|
return false
|
|
54
54
|
end
|
|
55
55
|
|
|
@@ -86,7 +86,7 @@ class Bracket
|
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
def raise_error(msg)
|
|
89
|
-
|
|
89
|
+
log_error "ERROR: #{msg}"
|
|
90
90
|
raise msg
|
|
91
91
|
end
|
|
92
92
|
|
|
@@ -118,7 +118,7 @@ class Bracket
|
|
|
118
118
|
# instead start with "//". Default to HTTPS.
|
|
119
119
|
uri.scheme ||= "https"
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
log_debug "Reading the config file from #{uri}"
|
|
122
122
|
|
|
123
123
|
# Read the config file from the attchment.
|
|
124
124
|
config = send_get_request(uri.to_s)
|
|
@@ -141,8 +141,8 @@ class Bracket
|
|
|
141
141
|
@teams << Team.new(team[:participant])
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
log_info "#{@teams.size} teams are in the bracket: " +
|
|
145
|
+
@teams.sort_by(&:name).map { |t| %("#{t.name}") }.join(", ")
|
|
146
146
|
|
|
147
147
|
# Check that all of the teams in the bracket are also in the config file.
|
|
148
148
|
# We do case-insensitive name comparisons to allow for different
|
|
@@ -205,7 +205,7 @@ class Bracket
|
|
|
205
205
|
# Each key is a Challonge ID of a team, and each value is an array of
|
|
206
206
|
# `Player` objects for the players on that team.
|
|
207
207
|
def read_players
|
|
208
|
-
@players =
|
|
208
|
+
@players = hash_of_arrays
|
|
209
209
|
|
|
210
210
|
# Read the team list from the config file and create structs for each
|
|
211
211
|
# player on each team.
|
|
@@ -218,7 +218,7 @@ class Bracket
|
|
|
218
218
|
# isn't in the bracket. We allow this so that multiple brackets can
|
|
219
219
|
# use the same master team list during a tournament.
|
|
220
220
|
if team_obj.nil?
|
|
221
|
-
|
|
221
|
+
log_info "Skipping a team that isn't in the bracket: #{team[:name]}"
|
|
222
222
|
next
|
|
223
223
|
end
|
|
224
224
|
|
|
@@ -226,8 +226,8 @@ class Bracket
|
|
|
226
226
|
@players[team_obj.id] << Player.new(player)
|
|
227
227
|
end
|
|
228
228
|
|
|
229
|
-
|
|
230
|
-
|
|
229
|
+
log_info "#{team[:name]} (ID #{team_obj.id}) has: " +
|
|
230
|
+
@players[team_obj.id].map { |p| "#{p.name} (#{p.scene})" }.join(", ")
|
|
231
231
|
end
|
|
232
232
|
|
|
233
233
|
# Bail out if any team doesn't have exactly 5 players.
|
|
@@ -264,12 +264,12 @@ class Bracket
|
|
|
264
264
|
@teams.each do |team|
|
|
265
265
|
matches_with_team = @matches.select { |match| match.has_team?(team.id) }
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
log_info "Team #{team.name} was in #{matches_with_team.size} matches"
|
|
268
268
|
|
|
269
269
|
points_earned = matches_with_team.max_by(&:points).points
|
|
270
270
|
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
log_info "The largest point value of those matches is #{points_earned}" \
|
|
272
|
+
"#{" + #{base_point_value} base" if base_point_value > 0}"
|
|
273
273
|
|
|
274
274
|
team.points = points_earned + base_point_value
|
|
275
275
|
end
|
|
@@ -282,8 +282,8 @@ class Bracket
|
|
|
282
282
|
# the debug output will follow the teams' finishing order, which will be
|
|
283
283
|
# easier to read.
|
|
284
284
|
@teams.sort_by(&:points).reverse_each do |team|
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
log_info "Awarding #{team.points} points to #{team.name}: " +
|
|
286
|
+
@players[team.id].map(&:to_s).join(", ")
|
|
287
287
|
|
|
288
288
|
@players[team.id].each do |player|
|
|
289
289
|
player.points = team.points
|
|
@@ -302,7 +302,7 @@ class Bracket
|
|
|
302
302
|
# points respectively. The two teams in 5th get 1.5, the average of 2 and 1.
|
|
303
303
|
sorted_teams = @teams.sort_by(&:final_rank)
|
|
304
304
|
num_teams = sorted_teams.size.to_f
|
|
305
|
-
final_rank_points =
|
|
305
|
+
final_rank_points = hash_of_arrays
|
|
306
306
|
|
|
307
307
|
sorted_teams.each_with_index do |team, idx|
|
|
308
308
|
final_rank_points[team.final_rank] << num_teams - idx
|
|
@@ -314,9 +314,9 @@ class Bracket
|
|
|
314
314
|
points_earned = final_rank_points[team.final_rank].sum /
|
|
315
315
|
final_rank_points[team.final_rank].size
|
|
316
316
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
317
|
+
log_info "#{team.name} finished in position #{team.final_rank}" \
|
|
318
|
+
" and gets #{points_earned} points" \
|
|
319
|
+
"#{" + #{base_point_value} base" if base_point_value > 0}"
|
|
320
320
|
|
|
321
321
|
team.points = points_earned + base_point_value
|
|
322
322
|
end
|
|
@@ -325,7 +325,7 @@ class Bracket
|
|
|
325
325
|
# Sends a GET request to `url`, treats the returned data as JSON, parses it
|
|
326
326
|
# into an object, and returns that object.
|
|
327
327
|
def send_get_request(url, params = {})
|
|
328
|
-
params[:api_key] =
|
|
328
|
+
params[:api_key] = api_key
|
|
329
329
|
resp = RestClient.get(url, params: params)
|
|
330
330
|
|
|
331
331
|
JSON.parse(resp, symbolize_names: true)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module KillerQueenSceneScoring
|
|
4
4
|
|
|
5
|
-
class Tournament
|
|
5
|
+
class Tournament < Base
|
|
6
6
|
attr_reader :scene_scores, :complete
|
|
7
7
|
|
|
8
8
|
# `id` can be the slug or the challonge ID of the first bracket in the
|
|
@@ -11,21 +11,13 @@ class Tournament
|
|
|
11
11
|
# `api_key` is your Challonge API key.
|
|
12
12
|
# `logger` can be a `Logger` object, or `true` to log to standard output.
|
|
13
13
|
def initialize(id:, api_key:, logger: nil)
|
|
14
|
+
super(api_key, logger)
|
|
15
|
+
|
|
14
16
|
@brackets = []
|
|
15
17
|
@scene_scores = []
|
|
16
18
|
@loaded = false
|
|
17
19
|
@complete = false
|
|
18
20
|
@id = id
|
|
19
|
-
@api_key = api_key
|
|
20
|
-
|
|
21
|
-
@logger = case logger
|
|
22
|
-
when true
|
|
23
|
-
Logger.new(STDOUT, progname: "KillerQueenSceneScoring")
|
|
24
|
-
when Logger
|
|
25
|
-
logger
|
|
26
|
-
else
|
|
27
|
-
nil
|
|
28
|
-
end
|
|
29
21
|
end
|
|
30
22
|
|
|
31
23
|
# Reads the Challonge bracket with the ID that was passed to the constructor,
|
|
@@ -39,10 +31,10 @@ class Tournament
|
|
|
39
31
|
all_brackets_loaded = true
|
|
40
32
|
|
|
41
33
|
while tournament_id
|
|
42
|
-
|
|
34
|
+
log_debug "Reading the bracket \"#{tournament_id}\""
|
|
43
35
|
|
|
44
36
|
# Load the next bracket in the chain. Bail out if we can't load it.
|
|
45
|
-
bracket = Bracket.new(id: tournament_id, api_key:
|
|
37
|
+
bracket = Bracket.new(id: tournament_id, api_key: api_key, logger: logger)
|
|
46
38
|
|
|
47
39
|
if !bracket.load
|
|
48
40
|
all_brackets_loaded = false
|
|
@@ -53,7 +45,7 @@ class Tournament
|
|
|
53
45
|
@brackets << bracket
|
|
54
46
|
|
|
55
47
|
# For debugging purposes, log the players in each scene ->
|
|
56
|
-
scenes =
|
|
48
|
+
scenes = hash_of_arrays
|
|
57
49
|
|
|
58
50
|
bracket.players.each_value do |team|
|
|
59
51
|
team.each do |player|
|
|
@@ -66,7 +58,7 @@ class Tournament
|
|
|
66
58
|
players.map(&:name).join(", ")
|
|
67
59
|
end
|
|
68
60
|
|
|
69
|
-
|
|
61
|
+
log_info scene_list.join("\n")
|
|
70
62
|
# <- end debug logging
|
|
71
63
|
|
|
72
64
|
# Go to the next bracket in the chain.
|
|
@@ -80,7 +72,7 @@ class Tournament
|
|
|
80
72
|
|
|
81
73
|
if values.count(values[0]) != values.size
|
|
82
74
|
msg = "ERROR: All brackets must have the same \"max_players_to_count\"."
|
|
83
|
-
|
|
75
|
+
log_error msg
|
|
84
76
|
raise msg
|
|
85
77
|
end
|
|
86
78
|
|
|
@@ -133,7 +125,7 @@ class Tournament
|
|
|
133
125
|
# Assemble the scores from the players in each scene.
|
|
134
126
|
# `scene_players_scores` is a hash from a scene name to an array that
|
|
135
127
|
# holds the scores of all the players in that scene.
|
|
136
|
-
scene_players_scores =
|
|
128
|
+
scene_players_scores = hash_of_arrays
|
|
137
129
|
|
|
138
130
|
player_scores.each_value do |player|
|
|
139
131
|
scene_players_scores[player.scene] << player.points
|
|
@@ -150,8 +142,8 @@ class Tournament
|
|
|
150
142
|
if scores.size > max_players_to_count
|
|
151
143
|
dropped = scores.slice!(max_players_to_count..-1)
|
|
152
144
|
|
|
153
|
-
|
|
154
|
-
|
|
145
|
+
log_info "Dropping the #{dropped.size} lowest scores from #{scene}:" +
|
|
146
|
+
dropped.join(", ")
|
|
155
147
|
end
|
|
156
148
|
|
|
157
149
|
# Add up the scores for this scene.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: killer_queen_scene_scoring
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michael Dunn
|
|
@@ -142,6 +142,7 @@ files:
|
|
|
142
142
|
- exe/killer_queen_scene_scoring
|
|
143
143
|
- killer_queen_scene_scoring.gemspec
|
|
144
144
|
- lib/killer_queen_scene_scoring.rb
|
|
145
|
+
- lib/killer_queen_scene_scoring/base.rb
|
|
145
146
|
- lib/killer_queen_scene_scoring/bracket.rb
|
|
146
147
|
- lib/killer_queen_scene_scoring/config.rb
|
|
147
148
|
- lib/killer_queen_scene_scoring/match.rb
|