tournament-system 1.0.2 → 2.0.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 +5 -5
- data/.reek +3 -0
- data/.rubocop.yml +1 -1
- data/.travis.yml +1 -1
- data/Gemfile +1 -1
- data/README.md +15 -6
- data/Rakefile +2 -2
- data/lib/tournament_system.rb +25 -0
- data/lib/{tournament → tournament_system}/algorithm.rb +2 -3
- data/lib/{tournament → tournament_system}/algorithm/group_pairing.rb +1 -1
- data/lib/{tournament → tournament_system}/algorithm/matching.rb +2 -2
- data/lib/{tournament → tournament_system}/algorithm/page_playoff.rb +1 -1
- data/lib/{tournament → tournament_system}/algorithm/round_robin.rb +3 -3
- data/lib/{tournament → tournament_system}/algorithm/single_bracket.rb +5 -11
- data/lib/{tournament → tournament_system}/algorithm/swiss.rb +1 -1
- data/lib/{tournament → tournament_system}/algorithm/util.rb +1 -1
- data/lib/{tournament → tournament_system}/driver.rb +90 -12
- data/lib/tournament_system/driver_proxy.rb +46 -0
- data/lib/{tournament → tournament_system}/page_playoff.rb +3 -3
- data/lib/{tournament → tournament_system}/round_robin.rb +3 -3
- data/lib/{tournament → tournament_system}/single_elimination.rb +3 -3
- data/lib/{tournament → tournament_system}/swiss.rb +14 -4
- data/lib/tournament_system/swiss/accelerated_dutch.rb +69 -0
- data/lib/{tournament → tournament_system}/swiss/dutch.rb +9 -8
- data/lib/tournament_system/version.rb +4 -0
- data/tournament-system.gemspec +3 -5
- metadata +23 -22
- data/lib/tournament-system.rb +0 -7
- data/lib/tournament.rb +0 -6
- data/lib/tournament/version.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 52196b11f89aad9f8e4dbf67094ba9e99dff805e6d7d95dc840213d802bfb511
|
4
|
+
data.tar.gz: 739375eaad6f1093c3e47ec6e630ea1394670582f1f6e84d85917327bc30358e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80e6f521ef7293504a69d2d0287200d535ce5833cbbc4d78c60878de30d18f1862aea1101460e9aeac0c396d18818c5a199764a875bcebbbc6298b8ab5f30ae3
|
7
|
+
data.tar.gz: 88b4831a41dea4acce69ffcde2e10eed2edbb5ec5a435c9d97b47fb5aad85e24beffb3aa76a809eadca053769c354611798edac2e79dd57382145c256d0d517a
|
data/.reek
CHANGED
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -14,7 +14,7 @@ It is designed to easily fit into any memory model you might already have.
|
|
14
14
|
Add this line to your application's Gemfile:
|
15
15
|
|
16
16
|
```ruby
|
17
|
-
gem 'tournament-system', '~>
|
17
|
+
gem 'tournament-system', '~> 2'
|
18
18
|
```
|
19
19
|
|
20
20
|
And then execute:
|
@@ -35,7 +35,7 @@ First you need to implement a driver to handle the interface between your data
|
|
35
35
|
and the tournament systems:
|
36
36
|
|
37
37
|
```ruby
|
38
|
-
class Driver <
|
38
|
+
class Driver < TournamentSystem::Driver
|
39
39
|
def matches
|
40
40
|
...
|
41
41
|
end
|
@@ -60,12 +60,18 @@ class Driver < Tournament::Driver
|
|
60
60
|
...
|
61
61
|
end
|
62
62
|
|
63
|
+
def get_team_matches(team)
|
64
|
+
...
|
65
|
+
end
|
66
|
+
|
63
67
|
def build_match(home_team, away_team)
|
64
68
|
...
|
65
69
|
end
|
66
70
|
end
|
67
71
|
```
|
68
72
|
|
73
|
+
Check the docs on [`TournamentSystem::Driver`](http://www.rubydoc.info/github/ozfortress/tournament-system/master/Tournament/Driver) for more information.
|
74
|
+
|
69
75
|
Then you can simply generate matches for any tournament system using a driver
|
70
76
|
instance:
|
71
77
|
|
@@ -73,18 +79,21 @@ instance:
|
|
73
79
|
driver = Driver.new
|
74
80
|
|
75
81
|
# Generate a round of a single elimination tournament
|
76
|
-
|
82
|
+
TournamentSystem::SingleElimination.generate driver
|
77
83
|
|
78
84
|
# Generate a round for a round robin tournament
|
79
|
-
|
85
|
+
TournamentSystem::RoundRobin.generate driver
|
80
86
|
|
81
87
|
# Generate a round for a swiss system tournament, pushing byes to the bottom
|
82
88
|
# half (bottom half teams will bye before the top half)
|
83
|
-
|
89
|
+
TournamentSystem::Swiss.generate driver, pairer: TournamentSystem::Swiss::Dutch,
|
84
90
|
pair_options: { push_byes_to: :bottom_half }
|
85
91
|
|
92
|
+
# Alternatively use the accelerated swiss system
|
93
|
+
TournamentSystem::Swiss.generate driver, pairer: TournamentSystem::Swiss::AcceleratedDutch
|
94
|
+
|
86
95
|
# Generate a round for a page playoff system, with an optional bronze match
|
87
|
-
|
96
|
+
TournamentSystem::PagePlayoff.generate driver, bronze_match: true
|
88
97
|
```
|
89
98
|
|
90
99
|
## Contributing
|
data/Rakefile
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'tournament_system/version'
|
2
|
+
require 'tournament_system/driver'
|
3
|
+
|
4
|
+
require 'tournament_system/swiss'
|
5
|
+
require 'tournament_system/round_robin'
|
6
|
+
require 'tournament_system/page_playoff'
|
7
|
+
require 'tournament_system/single_elimination'
|
8
|
+
|
9
|
+
# This library is split into two parts, there's the actual algorithms that implement various tournament systems
|
10
|
+
# ({Algorithm}) and a data abstraction layer for generating matches using various tournament systems in a
|
11
|
+
# data-independent way ({Driver}), along with matching implementations of tournament systems using drivers.
|
12
|
+
#
|
13
|
+
# TournamentSystem currently supports the following systems:
|
14
|
+
#
|
15
|
+
# * {https://en.wikipedia.org/wiki/Single-elimination_tournament Single elimination}
|
16
|
+
# ({TournamentSystem::SingleElimination})
|
17
|
+
# * {https://en.wikipedia.org/wiki/Page_playoff_system Page playoffs} ({TournamentSystem::PagePlayoff})
|
18
|
+
# * {https://en.wikipedia.org/wiki/Round-robin_tournament Round robin} ({TournamentSystem::RoundRobin})
|
19
|
+
# * {https://en.wikipedia.org/wiki/Swiss-system_tournament Swiss-system} ({TournamentSystem::Swiss}) with support for
|
20
|
+
# multiple types of pairing systems:
|
21
|
+
#
|
22
|
+
# * Dutch pairing (very popular) ({TournamentSystem::Swiss::Dutch})
|
23
|
+
# * Accelerated pairing (aka Accelerated swiss) ({TournamentSystem::Swiss::AcceleratedDutch})
|
24
|
+
module TournamentSystem
|
25
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
|
-
module
|
2
|
-
# This module provides abtraction-less implementations of all algorithms
|
3
|
-
# used for tournament systems.
|
1
|
+
module TournamentSystem
|
2
|
+
# This module provides abtraction-less implementations of all algorithms used for tournament systems.
|
4
3
|
module Algorithm
|
5
4
|
end
|
6
5
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'graph_matching'
|
2
2
|
|
3
|
-
module
|
3
|
+
module TournamentSystem
|
4
4
|
module Algorithm
|
5
5
|
# Implements graph matching algorithms for tournament systems.
|
6
6
|
module Matching
|
@@ -41,7 +41,7 @@ module Tournament
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
44
|
-
#
|
44
|
+
# rubocop:enable Metrics/MethodLength
|
45
45
|
|
46
46
|
# Performs maximum weight perfect matching of a undirected complete graph composed of the given vertices.
|
47
47
|
#
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'tournament_system/algorithm/util'
|
2
|
+
require 'tournament_system/algorithm/group_pairing'
|
3
3
|
|
4
|
-
module
|
4
|
+
module TournamentSystem
|
5
5
|
module Algorithm
|
6
6
|
# This module provides algorithms for dealing with round robin tournament
|
7
7
|
# systems.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
|
3
|
-
module
|
3
|
+
module TournamentSystem
|
4
4
|
module Algorithm
|
5
5
|
# This module provides algorithms for dealing with single bracket
|
6
6
|
# elimination tournament systems.
|
@@ -36,15 +36,11 @@ module Tournament
|
|
36
36
|
total_teams = max_teams(rounds)
|
37
37
|
|
38
38
|
# Make sure we don't have too many matches
|
39
|
-
unless total_teams >= matches_count
|
40
|
-
raise ArgumentError, 'Too many matches'
|
41
|
-
end
|
39
|
+
raise ArgumentError, 'Too many matches' unless total_teams >= matches_count
|
42
40
|
|
43
41
|
round = rounds - Math.log2(total_teams - matches_count)
|
44
|
-
|
45
|
-
|
46
|
-
raise ArgumentError, 'Invalid number of matches'
|
47
|
-
end
|
42
|
+
# Make sure we don't have some weird number of matches
|
43
|
+
raise ArgumentError, 'Invalid number of matches' unless (round % 1).zero?
|
48
44
|
|
49
45
|
round.to_i
|
50
46
|
end
|
@@ -72,9 +68,7 @@ module Tournament
|
|
72
68
|
# @return [Array<team>]
|
73
69
|
# @raise [ArgumentError] when the number of teams is not a power of 2
|
74
70
|
def seed(teams)
|
75
|
-
unless (Math.log2(teams.length) % 1).zero?
|
76
|
-
raise ArgumentError, 'Need power-of-2 teams'
|
77
|
-
end
|
71
|
+
raise ArgumentError, 'Need power-of-2 teams' unless (Math.log2(teams.length) % 1).zero?
|
78
72
|
|
79
73
|
teams = teams.map.with_index do |team, index|
|
80
74
|
OpenStruct.new(team: team, index: index)
|
@@ -1,22 +1,78 @@
|
|
1
|
-
module
|
1
|
+
module TournamentSystem
|
2
2
|
# :reek:UnusedParameters
|
3
3
|
|
4
4
|
# An interface for external tournament data.
|
5
5
|
#
|
6
|
-
# To use any tournament system implemented in this gem, simply subclass this
|
7
|
-
#
|
6
|
+
# To use any tournament system implemented in this gem, simply subclass this class and implement the interface
|
7
|
+
# functions.
|
8
8
|
#
|
9
|
-
# The interface is designed to be useable with arbitrary data,
|
10
|
-
#
|
11
|
-
# Be it Ruby on Rails Models or simply integers.
|
9
|
+
# The interface is designed to be useable with arbitrary data, meaning that as long as your data is consistent it will
|
10
|
+
# work with this gem. Be it Ruby on Rails Models or simply integers.
|
12
11
|
#
|
13
|
-
# Certain tournament systems will not make use of certain parts of this
|
14
|
-
#
|
15
|
-
# using the Swiss tournament system.
|
12
|
+
# Certain tournament systems will not make use of certain parts of this interface. You can for example leave out
|
13
|
+
# `#get_team_score` if you're not using the Swiss tournament system.
|
16
14
|
#
|
17
|
-
# This class caches certain calculations/objects, it is designed to be a
|
18
|
-
#
|
19
|
-
#
|
15
|
+
# This class caches certain calculations/objects, it is designed to be a one-time use with any one tournament system.
|
16
|
+
# Reusing an instance is undefined behaviour.
|
17
|
+
#
|
18
|
+
# @example Example of Rails models and a tournament system driver
|
19
|
+
# class Tournament < ActiveRecord::Base
|
20
|
+
# has_many :matches
|
21
|
+
# has_many :teams
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# class Match < ActiveRecord::Base
|
25
|
+
# belongs_to :tournament
|
26
|
+
# belongs_to :team1, class_name: 'Team'
|
27
|
+
# belongs_to :team2, class_name: 'Team'
|
28
|
+
# belongs_to :winner, class_name: 'Team'
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# class Team < ActiveRecord::Base
|
32
|
+
# belongs_to :tournament
|
33
|
+
#
|
34
|
+
# validates :seed, numericality: { only_integer: true }
|
35
|
+
# validates :points, numericality: { only_integer: true }
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# class Driver < TournamentSystem
|
39
|
+
# def initialize(tournament)
|
40
|
+
# @tournament = tournament
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# def matches
|
44
|
+
# @tournament.matches
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# def seeded_teams
|
48
|
+
# @tournament.teams.order(:seed).to_a
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# def ranked_teams
|
52
|
+
# @tournament.teams.order(:points).to_a
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# def get_match_winner(match)
|
56
|
+
# match.winner
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# def get_match_teams(match)
|
60
|
+
# [match.team1, match.team2]
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# def get_team_score(team)
|
64
|
+
# team.points
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# def get_team_matches(team)
|
68
|
+
# @tournament.matches.where(team1: team) +
|
69
|
+
# @tournament.matches.where(team2: team)
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# def build_match(home_team, away_team)
|
73
|
+
# @tournament.matches.create!(team1: home_team, team2: away_team)
|
74
|
+
# end
|
75
|
+
# end
|
20
76
|
class Driver
|
21
77
|
# rubocop:disable Lint/UnusedMethodArgument
|
22
78
|
# :nocov:
|
@@ -66,6 +122,14 @@ module Tournament
|
|
66
122
|
raise 'Not Implemented'
|
67
123
|
end
|
68
124
|
|
125
|
+
# Required to implement: Get the matches a team has participated in.
|
126
|
+
#
|
127
|
+
# @param team [] a team, eg. one returned by {#seeded_teams}
|
128
|
+
# @return [Array<match>] a list of matches the team has played in
|
129
|
+
def get_team_matches(team)
|
130
|
+
raise 'Not Implemented'
|
131
|
+
end
|
132
|
+
|
69
133
|
# Required to implement: Called when a match is created by a tournament system.
|
70
134
|
#
|
71
135
|
# @example rails
|
@@ -102,6 +166,13 @@ module Tournament
|
|
102
166
|
@matches_hash ||= build_matches_hash
|
103
167
|
end
|
104
168
|
|
169
|
+
# Get a hash of the matches teams have played in. Used by tournament systems.
|
170
|
+
#
|
171
|
+
# @return [Hash{team => Array<match>}]
|
172
|
+
def team_matches_hash
|
173
|
+
@team_matches_hash ||= build_team_matches_hash
|
174
|
+
end
|
175
|
+
|
105
176
|
# Count the number of times each pair of teams has played already. Used by tournament systems.
|
106
177
|
#
|
107
178
|
# @param matches [Array<match>]
|
@@ -152,5 +223,12 @@ module Tournament
|
|
152
223
|
counter[match] += 1
|
153
224
|
end
|
154
225
|
end
|
226
|
+
|
227
|
+
def build_team_matches_hash
|
228
|
+
seeded_teams.each_with_object({}) do |team, hash|
|
229
|
+
matches = get_team_matches(team)
|
230
|
+
hash[team] = matches
|
231
|
+
end
|
232
|
+
end
|
155
233
|
end
|
156
234
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module TournamentSystem
|
2
|
+
# Proxies a driver, allowing overriding of certain functions.
|
3
|
+
#
|
4
|
+
# Used by tournament systems that build on top of others, with special behaviour.
|
5
|
+
# By default the behaviour is identical to the proxied driver.
|
6
|
+
class DriverProxy < Driver
|
7
|
+
# :nocov:
|
8
|
+
|
9
|
+
# @param target [Driver] the driver to proxy
|
10
|
+
def initialize(target)
|
11
|
+
@target = target
|
12
|
+
end
|
13
|
+
|
14
|
+
def matches
|
15
|
+
@target.matches
|
16
|
+
end
|
17
|
+
|
18
|
+
def seeded_teams
|
19
|
+
@target.seeded_teams
|
20
|
+
end
|
21
|
+
|
22
|
+
def ranked_teams
|
23
|
+
@target.ranked_teams
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_match_winner(match)
|
27
|
+
@target.get_match_winner(match)
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_match_teams(match)
|
31
|
+
@target.get_match_teams(match)
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_team_score(team)
|
35
|
+
@target.get_team_score(team)
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_team_matches(team)
|
39
|
+
@target.get_team_matches(team)
|
40
|
+
end
|
41
|
+
|
42
|
+
def build_match(home_team, away_team)
|
43
|
+
@target.build_match(home_team, away_team)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'tournament_system/algorithm/page_playoff'
|
2
|
+
require 'tournament_system/algorithm/group_pairing'
|
3
3
|
|
4
|
-
module
|
4
|
+
module TournamentSystem
|
5
5
|
# Implements the page playoff system.
|
6
6
|
module PagePlayoff
|
7
7
|
extend self
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'tournament_system/algorithm/util'
|
2
|
+
require 'tournament_system/algorithm/round_robin'
|
3
3
|
|
4
|
-
module
|
4
|
+
module TournamentSystem
|
5
5
|
# Implements the round-robin tournament system.
|
6
6
|
module RoundRobin
|
7
7
|
extend self
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'tournament_system/algorithm/single_bracket'
|
2
|
+
require 'tournament_system/algorithm/group_pairing'
|
3
3
|
|
4
|
-
module
|
4
|
+
module TournamentSystem
|
5
5
|
# Implements the single bracket elimination tournament system.
|
6
6
|
module SingleElimination
|
7
7
|
extend self
|
@@ -1,8 +1,9 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'tournament_system/algorithm/swiss'
|
2
|
+
require 'tournament_system/swiss/dutch'
|
3
|
+
require 'tournament_system/swiss/accelerated_dutch'
|
3
4
|
|
4
|
-
module
|
5
|
-
#
|
5
|
+
module TournamentSystem
|
6
|
+
# Robust implementation of the swiss tournament system
|
6
7
|
module Swiss
|
7
8
|
extend self
|
8
9
|
|
@@ -23,6 +24,15 @@ module Tournament
|
|
23
24
|
driver.create_matches(pairings)
|
24
25
|
end
|
25
26
|
|
27
|
+
# Guesses the round number (starting from 0) from the maximum amount of matches any team has played.
|
28
|
+
# The guess will be wrong for long running competitions where teams are free to sign up and drop out at any time.
|
29
|
+
#
|
30
|
+
# @param driver [Driver]
|
31
|
+
# @return [Integer]
|
32
|
+
def guess_round(driver)
|
33
|
+
driver.team_matches_hash.values.map(&:length).max || 0
|
34
|
+
end
|
35
|
+
|
26
36
|
# The minimum number of rounds to determine a number of winners.
|
27
37
|
#
|
28
38
|
# @param driver [Driver]
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'tournament_system/swiss/dutch'
|
2
|
+
require 'tournament_system/driver_proxy'
|
3
|
+
|
4
|
+
module TournamentSystem
|
5
|
+
module Swiss
|
6
|
+
# A implementation of accelerated (dutch) swiss pairing
|
7
|
+
module AcceleratedDutch
|
8
|
+
extend self
|
9
|
+
|
10
|
+
# Pair teams using the accelerated (dutch) swiss pairing system.
|
11
|
+
#
|
12
|
+
# Behaves identical to the dutch pairing system, except that for the first N rounds the top half of the seeded
|
13
|
+
# teams is given a point bonus. This makes the first couple rounds of a tournament accelerate 1 round ahead of
|
14
|
+
# swiss.
|
15
|
+
#
|
16
|
+
# Options are passed to the dutch system and behave identically.
|
17
|
+
#
|
18
|
+
# @param driver [Driver]
|
19
|
+
# @option options [Integer] acceleration_rounds determines how many round to perform the acceleration for. This
|
20
|
+
# should be shorter than the length of the tournament in order to produce fair results.
|
21
|
+
# @option options [Number] acceleration_points determines how many points to grant the teams. This should be
|
22
|
+
# approximately equal to the number of points usually granted in one round.
|
23
|
+
# @return [Array<Array(team, team)>] the generated pairs of teams
|
24
|
+
def pair(driver, options = {})
|
25
|
+
acceleration_rounds = options[:acceleration_rounds] || 2
|
26
|
+
acceleration_points = options[:acceleration_points] || 1
|
27
|
+
|
28
|
+
# Accelerate for the first N rounds by replacing the driver with an accelerated one
|
29
|
+
driver = accelerate_driver(driver, acceleration_points) if Swiss.guess_round(driver) < acceleration_rounds
|
30
|
+
|
31
|
+
# Do a regular dutch pairing
|
32
|
+
Dutch.pair(driver, options)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def accelerate_driver(driver, acceleration_points)
|
38
|
+
teams = driver.seeded_teams
|
39
|
+
top_half = Set.new teams[0..teams.length / 2]
|
40
|
+
|
41
|
+
# Accelerated dutch is identical to dutch, except that we give the top half an extra point for the first 2
|
42
|
+
# rounds. To do that we just proxy the driver and add one point.
|
43
|
+
AcceleratedDutchDriverProxy.new(driver, top_half, acceleration_points)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Driver proxy for implementing a score bonus
|
47
|
+
class AcceleratedDutchDriverProxy < DriverProxy
|
48
|
+
def initialize(target, accelerated_teams, acceleration_points)
|
49
|
+
super(target)
|
50
|
+
|
51
|
+
@accelerated_teams = accelerated_teams
|
52
|
+
@acceleration_points = acceleration_points
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_team_score(team)
|
56
|
+
original_score = super(team)
|
57
|
+
|
58
|
+
if @accelerated_teams.include?(team)
|
59
|
+
original_score + @acceleration_points
|
60
|
+
else
|
61
|
+
original_score
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private_constant :AcceleratedDutchDriverProxy
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
require '
|
3
|
+
require 'tournament_system/algorithm/swiss'
|
4
|
+
require 'tournament_system/algorithm/matching'
|
5
|
+
require 'tournament_system/algorithm/group_pairing'
|
6
6
|
|
7
|
-
module
|
7
|
+
module TournamentSystem
|
8
8
|
module Swiss
|
9
|
-
# A
|
9
|
+
# A Dutch pairing system implementation.
|
10
10
|
module Dutch
|
11
11
|
extend self
|
12
12
|
|
13
13
|
# Pair teams using dutch pairing for a swiss system tournament.
|
14
14
|
#
|
15
|
-
# Teams are initially grouped by their score and then slide paired
|
16
|
-
# If that fails to produce unique matches it will match teams
|
17
|
-
# matches (default) and optionally pushing byes to a certain
|
15
|
+
# Teams are initially grouped by their score and then slide paired
|
16
|
+
# ({TournamentSystem::Algorithm::GroupPairing.slide}). If that fails to produce unique matches it will match teams
|
17
|
+
# by the minimum score difference, aniling duplicate matches (default) and optionally pushing byes to a certain
|
18
|
+
# side.
|
18
19
|
#
|
19
20
|
# @param driver [Driver]
|
20
21
|
# @option options [Boolean] allow_duplicates removes the penalty of duplicate matches from the pairing algorithm
|
data/tournament-system.gemspec
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
1
|
lib = File.expand_path('../lib', __FILE__)
|
4
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require '
|
3
|
+
require 'tournament_system/version'
|
6
4
|
|
7
5
|
Gem::Specification.new do |spec|
|
8
6
|
spec.name = 'tournament-system'
|
9
|
-
spec.version =
|
7
|
+
spec.version = TournamentSystem::VERSION
|
10
8
|
spec.authors = ['Benjamin Schaaf']
|
11
9
|
spec.email = ['ben.schaaf@gmail.com']
|
12
10
|
|
@@ -24,5 +22,5 @@ Gem::Specification.new do |spec|
|
|
24
22
|
spec.require_paths = ['lib']
|
25
23
|
|
26
24
|
spec.add_runtime_dependency 'graph_matching', '~> 0.1.1'
|
27
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.16.0'
|
28
26
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tournament-system
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Schaaf
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graph_matching
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.16.0
|
34
34
|
type: :development
|
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: 1.16.0
|
41
41
|
description:
|
42
42
|
email:
|
43
43
|
- ben.schaaf@gmail.com
|
@@ -54,23 +54,24 @@ files:
|
|
54
54
|
- LICENSE
|
55
55
|
- README.md
|
56
56
|
- Rakefile
|
57
|
-
- lib/
|
58
|
-
- lib/
|
59
|
-
- lib/
|
60
|
-
- lib/
|
61
|
-
- lib/
|
62
|
-
- lib/
|
63
|
-
- lib/
|
64
|
-
- lib/
|
65
|
-
- lib/
|
66
|
-
- lib/
|
67
|
-
- lib/
|
68
|
-
- lib/
|
69
|
-
- lib/
|
70
|
-
- lib/
|
71
|
-
- lib/
|
72
|
-
- lib/
|
73
|
-
- lib/
|
57
|
+
- lib/tournament_system.rb
|
58
|
+
- lib/tournament_system/algorithm.rb
|
59
|
+
- lib/tournament_system/algorithm/group_pairing.rb
|
60
|
+
- lib/tournament_system/algorithm/matching.rb
|
61
|
+
- lib/tournament_system/algorithm/page_playoff.rb
|
62
|
+
- lib/tournament_system/algorithm/round_robin.rb
|
63
|
+
- lib/tournament_system/algorithm/single_bracket.rb
|
64
|
+
- lib/tournament_system/algorithm/swiss.rb
|
65
|
+
- lib/tournament_system/algorithm/util.rb
|
66
|
+
- lib/tournament_system/driver.rb
|
67
|
+
- lib/tournament_system/driver_proxy.rb
|
68
|
+
- lib/tournament_system/page_playoff.rb
|
69
|
+
- lib/tournament_system/round_robin.rb
|
70
|
+
- lib/tournament_system/single_elimination.rb
|
71
|
+
- lib/tournament_system/swiss.rb
|
72
|
+
- lib/tournament_system/swiss/accelerated_dutch.rb
|
73
|
+
- lib/tournament_system/swiss/dutch.rb
|
74
|
+
- lib/tournament_system/version.rb
|
74
75
|
- tournament-system.gemspec
|
75
76
|
homepage: https://github.com/ozfortress/tournament-system
|
76
77
|
licenses:
|
@@ -92,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
93
|
version: '0'
|
93
94
|
requirements: []
|
94
95
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.
|
96
|
+
rubygems_version: 2.7.3
|
96
97
|
signing_key:
|
97
98
|
specification_version: 4
|
98
99
|
summary: Implements various tournament systems
|
data/lib/tournament-system.rb
DELETED
data/lib/tournament.rb
DELETED
@@ -1,6 +0,0 @@
|
|
1
|
-
# This library is split into two parts, there's the actual algorithms that
|
2
|
-
# implement various tournament systems ({Algorithm}) and a data abstraction
|
3
|
-
# layer for generating matches using various tournament systems in a
|
4
|
-
# data-independent way ({Driver}).
|
5
|
-
module Tournament
|
6
|
-
end
|
data/lib/tournament/version.rb
DELETED