tournament-system 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -8
- data/lib/tournament/driver.rb +8 -5
- data/lib/tournament/seeder/single_bracket.rb +23 -8
- data/lib/tournament/single_elimination.rb +27 -8
- data/lib/tournament/swiss/common.rb +1 -1
- data/lib/tournament/swiss/dutch.rb +1 -0
- data/lib/tournament/version.rb +1 -1
- data/tournament-system.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e2feaf11e43d4582382ab6702fee535a796e00c
|
4
|
+
data.tar.gz: 79c8750797f63e42658afcbbc05b240308801209
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11128da929528638694f487a17aa28baa25fc4dd090ea88b7a378553f3894ffcd8c3c8c4c30f30cff2388dbf6d71872e74532e4ecf6c1e891051ac280483f1de
|
7
|
+
data.tar.gz: 8991877ed078ae29d705d630fb8fad9a828f52264b6546109ff74fbf6e460fce6599516318a13598177251ded7c0bf3e895aa729046b7985e6df66586a8884b9
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
[![Build Status](https://travis-ci.org/ozfortress/tournament-system.svg?branch=master)](https://travis-ci.org/ozfortress/tournament-system)
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/github/ozfortress/tournament-system/badge.svg?branch=master)](https://coveralls.io/github/ozfortress/tournament-system?branch=master)
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/tournament-system.svg)](https://badge.fury.io/rb/tournament-system)
|
6
|
+
[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/github/ozfortress/tournament-system/master)
|
6
7
|
|
7
8
|
This is a simple gem that implements numerous tournament systems.
|
8
9
|
|
@@ -39,10 +40,6 @@ class Driver < Tournament::Driver
|
|
39
40
|
...
|
40
41
|
end
|
41
42
|
|
42
|
-
def matches_for_round(round)
|
43
|
-
...
|
44
|
-
end
|
45
|
-
|
46
43
|
def seeded_teams
|
47
44
|
...
|
48
45
|
end
|
@@ -75,14 +72,14 @@ instance:
|
|
75
72
|
```ruby
|
76
73
|
driver = Driver.new
|
77
74
|
|
78
|
-
# Generate
|
79
|
-
Tournament::SingleElimination.generate driver
|
75
|
+
# Generate a round of a single elimination tournament
|
76
|
+
Tournament::SingleElimination.generate driver
|
80
77
|
|
81
|
-
# Generate a round for a round robin tournament
|
78
|
+
# Generate a round for a round robin tournament
|
82
79
|
Tournament::RoundRobin.generate driver
|
83
80
|
|
84
81
|
# Generate a round for a swiss system tournament
|
85
|
-
# with Dutch pairings (default) with a minimum pair size of 6
|
82
|
+
# with Dutch pairings (default) with a minimum pair size of 6 (default 4)
|
86
83
|
Tournament::Swiss.generate driver, pairer: Tournament::Swiss::Dutch,
|
87
84
|
pair_options: { min_pair_size: 6 }
|
88
85
|
|
data/lib/tournament/driver.rb
CHANGED
@@ -3,6 +3,14 @@ module Tournament
|
|
3
3
|
#
|
4
4
|
# To use any tournament system implemented in this gem, simply subclass this
|
5
5
|
# class and implement the interface functions.
|
6
|
+
#
|
7
|
+
# The interface is designed to be useable with arbitrary data,
|
8
|
+
# meaning that as long as your data is consistent it will work with this gem.
|
9
|
+
# Be it Ruby on Rails Models or simply integers.
|
10
|
+
#
|
11
|
+
# Certain tournament systems will not make use of certain parts of this
|
12
|
+
# interface. You can for example leave out `#get_team_score` if you're not
|
13
|
+
# using the Swiss tournament system.
|
6
14
|
# :reek:UnusedParameters
|
7
15
|
class Driver
|
8
16
|
# rubocop:disable Lint/UnusedMethodArgument
|
@@ -12,11 +20,6 @@ module Tournament
|
|
12
20
|
raise 'Not Implemented'
|
13
21
|
end
|
14
22
|
|
15
|
-
# Get the matches played for a particular round
|
16
|
-
def matches_for_round(round)
|
17
|
-
raise 'Not Implemented'
|
18
|
-
end
|
19
|
-
|
20
23
|
# Get the teams playing with their initial seedings
|
21
24
|
def seeded_teams
|
22
25
|
raise 'Not Implemented'
|
@@ -7,17 +7,32 @@ module Tournament
|
|
7
7
|
extend self
|
8
8
|
|
9
9
|
def seed(teams)
|
10
|
-
|
10
|
+
unless (Math.log2(teams.length) % 1).zero?
|
11
|
+
raise ArgumentError, 'Need power-of-2 teams'
|
12
|
+
end
|
13
|
+
|
14
|
+
teams = teams.map.with_index { |team, index| SeedTeam.new(team, index) }
|
15
|
+
seed_bracket(teams).map(&:team)
|
16
|
+
end
|
11
17
|
|
12
|
-
|
13
|
-
bottom_half = groups.map { |pair| pair[1] }
|
18
|
+
private
|
14
19
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
# Structure for wrapping a team with it's seed index
|
21
|
+
SeedTeam = Struct.new(:team, :index)
|
22
|
+
|
23
|
+
# Recursively seed the top half of the teams
|
24
|
+
# and match teams reversed by index to the bottom half
|
25
|
+
def seed_bracket(teams)
|
26
|
+
return teams if teams.length <= 2
|
27
|
+
|
28
|
+
top_half, bottom_half = teams.each_slice(teams.length / 2).to_a
|
29
|
+
top_half = seed top_half
|
30
|
+
|
31
|
+
top_half.map do |team|
|
32
|
+
match = bottom_half[-team.index - 1]
|
19
33
|
|
20
|
-
|
34
|
+
[team, match]
|
35
|
+
end.flatten
|
21
36
|
end
|
22
37
|
end
|
23
38
|
end
|
@@ -4,12 +4,12 @@ module Tournament
|
|
4
4
|
extend self
|
5
5
|
|
6
6
|
def generate(driver, options = {})
|
7
|
-
round =
|
7
|
+
round = guess_round(driver)
|
8
8
|
|
9
9
|
teams = if driver.matches.empty?
|
10
10
|
seed_teams driver.seeded_teams, options
|
11
11
|
else
|
12
|
-
last_matches = driver
|
12
|
+
last_matches = previous_round_matches driver, round
|
13
13
|
get_match_winners driver, last_matches
|
14
14
|
end
|
15
15
|
|
@@ -20,6 +20,20 @@ module Tournament
|
|
20
20
|
total_rounds_for_teams(driver.seeded_teams)
|
21
21
|
end
|
22
22
|
|
23
|
+
def guess_round(driver)
|
24
|
+
rounds = total_rounds(driver)
|
25
|
+
teams_count = 2**rounds
|
26
|
+
matches_count = driver.matches.length
|
27
|
+
|
28
|
+
# Make sure we don't have too many matches
|
29
|
+
raise ArgumentError, 'Too many matches' unless teams_count > matches_count
|
30
|
+
|
31
|
+
round = rounds - Math.log2(teams_count - matches_count)
|
32
|
+
# Make sure we don't have some weird number of matches
|
33
|
+
raise ArgumentError, 'Invalid number of matches' unless (round % 1).zero?
|
34
|
+
round.to_i
|
35
|
+
end
|
36
|
+
|
23
37
|
private
|
24
38
|
|
25
39
|
def seed_teams(teams, options)
|
@@ -30,13 +44,11 @@ module Tournament
|
|
30
44
|
end
|
31
45
|
|
32
46
|
def padd_teams(teams)
|
33
|
-
|
34
|
-
|
35
|
-
half = total / 2
|
47
|
+
required = 2**total_rounds_for_teams(teams)
|
48
|
+
padding = required - teams.length
|
36
49
|
|
37
|
-
padding
|
38
|
-
|
39
|
-
teams[0...half] + [nil] * padding + teams[half...teams.length]
|
50
|
+
# Insert the padding at the bottom to give top teams byes
|
51
|
+
teams + [nil] * padding
|
40
52
|
end
|
41
53
|
|
42
54
|
def total_rounds_for_teams(teams)
|
@@ -49,6 +61,13 @@ module Tournament
|
|
49
61
|
matches.map { |match| driver.get_match_winner(match) }
|
50
62
|
end
|
51
63
|
|
64
|
+
def previous_round_matches(driver, round)
|
65
|
+
rounds_left = total_rounds(driver) - round - 1
|
66
|
+
previous_matches_count = 2**rounds_left
|
67
|
+
|
68
|
+
driver.matches[-previous_matches_count, previous_matches_count]
|
69
|
+
end
|
70
|
+
|
52
71
|
def create_matches(driver, teams)
|
53
72
|
teams.each_slice(2) do |slice|
|
54
73
|
next if slice.all?(&:nil?)
|
@@ -44,7 +44,7 @@ module Tournament
|
|
44
44
|
groups[new_key] = group + groups[new_key]
|
45
45
|
# If there isn't, merge into the adjacent greater group
|
46
46
|
else
|
47
|
-
new_key =
|
47
|
+
new_key = new_keys[-1]
|
48
48
|
groups[new_key] += group
|
49
49
|
end
|
50
50
|
# Leave larger groups the way they are
|
data/lib/tournament/version.rb
CHANGED
data/tournament-system.gemspec
CHANGED
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: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Schaaf
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|