brackets 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef9e0f90d5ce9ae4ebd3193d0db4218463333415
4
- data.tar.gz: 563f99e283542007f9b6b7528ef3ab20a4a5fbd9
3
+ metadata.gz: 6c83d7fafb937ee94ed9ae54cefa98cb2ed830c4
4
+ data.tar.gz: 990b94f69f4e57cb5ecb43804fefbe7cb1565e1c
5
5
  SHA512:
6
- metadata.gz: 832d2402b34fe714a948d3aa71f79638617000d67d008fe9169b99606fb4b63b98e8d966f7f9891b112914dba4faf298edd8fe17cf6df75eb276946bbccfdb01
7
- data.tar.gz: d6834ca5434be898119361a5f29ed32fe65239bfff393926a5dc2488d68af400b6f328dd5eb9453910d8262a23f500da989c6273d4d15edfe6584035b651581c
6
+ metadata.gz: 8187f943dbc8be7e3c96501966e2f506637fa5f1814308224018ea864409758454589cd98d14621a766d2eba4bbca7970c6cc58bb40b5a84873d4a49703b8146
7
+ data.tar.gz: 53213ef11e8cc68488f95be647d9bd373b6b74e9c1985cbbc93e4b544966a5ebed66ac2a104cd965a99d98afdc41da5e53247adc36a07a3bf894750fbb0063f7
@@ -0,0 +1,2 @@
1
+ tmp/
2
+ *.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "rspec"
7
+ gem "guard-rspec"
8
+ gem "pry"
9
+ end
@@ -0,0 +1,67 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ brackets (0.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coderay (1.1.0)
10
+ diff-lcs (1.2.5)
11
+ ffi (1.9.10)
12
+ formatador (0.2.5)
13
+ guard (2.13.0)
14
+ formatador (>= 0.2.4)
15
+ listen (>= 2.7, <= 4.0)
16
+ lumberjack (~> 1.0)
17
+ nenv (~> 0.1)
18
+ notiffany (~> 0.0)
19
+ pry (>= 0.9.12)
20
+ shellany (~> 0.0)
21
+ thor (>= 0.18.1)
22
+ guard-compat (1.2.1)
23
+ guard-rspec (4.5.0)
24
+ guard (~> 2.1)
25
+ guard-compat (~> 1.1)
26
+ rspec (>= 2.99.0, < 4.0)
27
+ listen (3.0.4)
28
+ rb-fsevent (>= 0.9.3)
29
+ rb-inotify (>= 0.9)
30
+ lumberjack (1.0.9)
31
+ method_source (0.8.2)
32
+ nenv (0.2.0)
33
+ notiffany (0.0.8)
34
+ nenv (~> 0.1)
35
+ shellany (~> 0.0)
36
+ pry (0.10.3)
37
+ coderay (~> 1.1.0)
38
+ method_source (~> 0.8.1)
39
+ slop (~> 3.4)
40
+ rb-fsevent (0.9.6)
41
+ rb-inotify (0.9.5)
42
+ ffi (>= 0.5.0)
43
+ rspec (3.3.0)
44
+ rspec-core (~> 3.3.0)
45
+ rspec-expectations (~> 3.3.0)
46
+ rspec-mocks (~> 3.3.0)
47
+ rspec-core (3.3.2)
48
+ rspec-support (~> 3.3.0)
49
+ rspec-expectations (3.3.1)
50
+ diff-lcs (>= 1.2.0, < 2.0)
51
+ rspec-support (~> 3.3.0)
52
+ rspec-mocks (3.3.2)
53
+ diff-lcs (>= 1.2.0, < 2.0)
54
+ rspec-support (~> 3.3.0)
55
+ rspec-support (3.3.0)
56
+ shellany (0.0.1)
57
+ slop (3.6.0)
58
+ thor (0.19.1)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ brackets!
65
+ guard-rspec
66
+ pry
67
+ rspec
@@ -0,0 +1,47 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features)
6
+
7
+ ## Uncomment to clear the screen before every task
8
+ # clearing :on
9
+
10
+ ## Guard internally checks for changes in the Guardfile and exits.
11
+ ## If you want Guard to automatically start up again, run guard in a
12
+ ## shell loop, e.g.:
13
+ ##
14
+ ## $ while bundle exec guard; do echo "Restarting Guard..."; done
15
+ ##
16
+ ## Note: if you are using the `directories` clause above and you are not
17
+ ## watching the project directory ('.'), then you will want to move
18
+ ## the Guardfile to a watched dir and symlink it back, e.g.
19
+ #
20
+ # $ mkdir config
21
+ # $ mv Guardfile config/
22
+ # $ ln -s config/Guardfile .
23
+ #
24
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
25
+
26
+ # Note: The cmd option is now required due to the increasing number of ways
27
+ # rspec may be run, below are examples of the most common uses.
28
+ # * bundler: 'bundle exec rspec'
29
+ # * bundler binstubs: 'bin/rspec'
30
+ # * spring: 'bin/rspec' (This will use spring if running and you have
31
+ # installed the spring binstubs per the docs)
32
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
33
+ # * 'just' rspec: 'rspec'
34
+
35
+ guard :rspec, cmd: "bundle exec rspec" do
36
+ require "guard/rspec/dsl"
37
+ dsl = Guard::RSpec::Dsl.new(self)
38
+
39
+ # RSpec files
40
+ rspec = dsl.rspec
41
+ watch(rspec.spec_helper) { rspec.spec_dir }
42
+ watch(rspec.spec_support) { rspec.spec_dir }
43
+ watch(rspec.spec_files)
44
+
45
+ # Ruby files
46
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
47
+ end
@@ -0,0 +1,17 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'brackets'
5
+ s.version = '0.0.1'
6
+ s.date = '2015-11-08'
7
+ s.summary = "A gem to generate tournament brackets"
8
+ s.description = "A gem to generate tournament brackets"
9
+ s.authors = ["Vitor HP Bittencourt"]
10
+ s.email = 'vitorhp2@gmail.com'
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- test/*`.split("\n")
14
+ s.require_paths = ["lib"]
15
+ s.homepage = 'http://rubygems.org/gems/brackets'
16
+ s.license = 'MIT'
17
+ end
@@ -0,0 +1,8 @@
1
+ module Brackets
2
+ autoload :Tournament, 'brackets/tournament'
3
+ autoload :Match, 'brackets/match'
4
+
5
+ module Util
6
+ autoload :BooleanCounter, 'brackets/util/boolean_counter'
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ module Brackets
2
+ class Match
3
+ attr_reader :winner, :deph, :number, :red, :blue
4
+
5
+ def initialize(deph = 0, number, red, blue)
6
+ @red, @blue, @deph, @number = red, blue, deph, number
7
+
8
+ @winner = blue.nil? ? red : nil
9
+ end
10
+
11
+ def placeholder?
12
+ @red.nil? && @blue.nil?
13
+ end
14
+
15
+ def to_s
16
+ "-"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,76 @@
1
+ module Brackets
2
+ class Tournament
3
+ def initialize(counter = Brackets::Util::BooleanCounter.new)
4
+ @counter = counter
5
+ end
6
+
7
+ def generate(competitors)
8
+ generate_rounds(generate_first_round(competitors))
9
+ end
10
+
11
+ private
12
+
13
+ def generate_first_round(competitors)
14
+ c = competitors.dup
15
+
16
+ if c.size == 1
17
+ [build_match(1, [c.first, nil])]
18
+ else
19
+ placeholder_matches = generate_placeholder_matches(c)
20
+ exceeding_matches = generate_exceeding_matches(c)
21
+ normal_matches = c.each_slice(2).map do |slice|
22
+ build_match(1, slice)
23
+ end
24
+
25
+ placeholder_matches.concat(exceeding_matches).concat(normal_matches)
26
+ end
27
+ end
28
+
29
+ def generate_rounds(round, deph = 2)
30
+ if round.size == 1
31
+ round
32
+ else
33
+ matches = round.select{|m| m.deph == deph - 1 }.each_slice(2).map do |slice|
34
+ build_match(deph, slice)
35
+ end
36
+
37
+ round.concat(generate_rounds(matches, deph + 1))
38
+ end
39
+ end
40
+
41
+ def build_match(deph = 0, competitors)
42
+ red, blue = competitors
43
+
44
+ Match.new(deph, @counter.next_if(deph > 0, nil), red, blue)
45
+ end
46
+
47
+ def generate_exceeding_matches(competitors)
48
+ matches = exceeding_number_of_players_for(competitors.size).times.map do
49
+ build_match(0, competitors.slice!(0, 2))
50
+ end
51
+
52
+ exceeding_player_matches = matches.map do
53
+ build_match(1, [competitors.slice!(0)])
54
+ end
55
+
56
+ matches.concat(exceeding_player_matches)
57
+ end
58
+
59
+ def generate_placeholder_matches(competitors)
60
+ placeholder_matches_count = power_of_two_after(competitors.size) - competitors.size
61
+
62
+ placeholder_matches_count.times.map do
63
+ build_match(0, [nil, nil])
64
+ end
65
+ end
66
+
67
+ def power_of_two_after(x, pow = 1)
68
+ 2 ** pow >= x ? 2 ** pow : power_of_two_after(x, pow + 1)
69
+ end
70
+
71
+ def exceeding_number_of_players_for(size, pow = 1)
72
+ 2 ** pow > size ? size - (2 ** (pow - 1)) : exceeding_number_of_players_for(size, pow + 1)
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,13 @@
1
+ module Brackets
2
+ module Util
3
+ class BooleanCounter
4
+ def initialize
5
+ @counter = 0
6
+ end
7
+
8
+ def next_if(boolean, falsey_value = nil)
9
+ boolean ? @counter += 1 : falsey_value || @counter
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,113 @@
1
+ module Brackets
2
+ describe Tournament do
3
+ let(:anakin) { double("anakin") }
4
+ let(:obiwan) { double("obiwan") }
5
+ let(:maul) { double("maul") }
6
+ let(:mace) { double("mace") }
7
+ let(:yoda) { double("yoda") }
8
+ let(:shaak) { double("shaak") }
9
+ let(:kit) { double("kit") }
10
+ let(:plo) { double("plo") }
11
+
12
+ describe "#generate_round" do
13
+
14
+ subject { Tournament.new.generate(competitors) }
15
+
16
+ let(:competitors) { [anakin, obiwan, maul, mace] }
17
+
18
+ it "numbers the matches sequentially" do
19
+ expect(subject.map(&:number)).to eq([1, 2, 3])
20
+ end
21
+
22
+ context "with one participant" do
23
+ let(:competitors) { [anakin] }
24
+
25
+ it "generates one match with the only participant being the winner" do
26
+ expect(subject.length).to eq(1)
27
+ expect(subject.first).to be_a(Match)
28
+ expect(subject.first.winner).to eq(anakin)
29
+ end
30
+ end
31
+
32
+ context "with two competitors" do
33
+ let(:competitors) { [anakin, obiwan] }
34
+
35
+ it "generates one match with no winner" do
36
+ expect(subject.length).to eq(1)
37
+ expect(subject.first).to be_a(Match)
38
+ expect(subject.first.winner).to be(nil)
39
+ expect(subject.first.red).to be(anakin)
40
+ expect(subject.first.blue).to be(obiwan)
41
+ end
42
+ end
43
+
44
+ context "when number of competitors is a power of two" do
45
+ let(:competitors) { [yoda, mace, anakin, obiwan] }
46
+
47
+ it "generates matches from subsequent rounds" do
48
+ expect(subject.size).to eq(3)
49
+ expect(subject.last.red).to be_a(Match)
50
+ expect(subject.last.blue).to be_a(Match)
51
+ expect(subject.last.red.red).to be(yoda)
52
+ expect(subject.last.red.blue).to be(mace)
53
+ expect(subject.last.blue.red).to be(anakin)
54
+ expect(subject.last.blue.blue).to be(obiwan)
55
+ end
56
+ end
57
+
58
+ context "when number of competitors is not a power of two" do
59
+ let(:competitors) { [yoda, mace, anakin, obiwan, maul] }
60
+
61
+ it "puts the exceeding competitors against winners of the first round" do
62
+ expect(subject.select{ |m| m.deph == 0 }.size).to eq(4)
63
+ expect(subject.select{ |m| m.deph == 1 }.size).to eq(2)
64
+ expect(subject.select{ |m| m.deph == 2 }.size).to eq(1)
65
+ end
66
+
67
+ end
68
+
69
+
70
+ # context "with three competitors" do
71
+ # # TODO: Special case of three competitors
72
+ # subject { Tournament.new.generate_round([anakin, obiwan, maul], 0, 1) }
73
+
74
+ # it "generates three matches" do
75
+ # expect(subject.length).to eq(3)
76
+ # end
77
+
78
+ # it "has no winners on the first match" do
79
+ # expect(subject.first.winner).to eq(nil)
80
+ # end
81
+
82
+ # it "has a winner on the second match because there's only one guy" do
83
+ # expect(subject[1].winner).not_to eq(nil)
84
+ # end
85
+
86
+ # it "generates a final match with one participant from the second match", focus: true do
87
+ # expect(subject.last.red).to eq(nil)
88
+ # expect(subject.last.blue).not_to eq(nil)
89
+ # end
90
+
91
+ # it "sets deph of match accordingly" do
92
+ # expect(subject.first.deph).to eq(0)
93
+ # expect(subject[1].deph).to eq(0)
94
+ # expect(subject.last.deph).to eq(1)
95
+ # end
96
+
97
+ # it "numbers the matches sequentially" do
98
+ # expect(subject.first.number).to eq(1)
99
+ # expect(subject[1].number).to eq(2)
100
+ # expect(subject.last.number).to eq(3)
101
+ # end
102
+ # end
103
+
104
+ # context "when number of competitors is not a power of two" do
105
+ # subject { Tournament.new.generate_round([yoda, mace, anakin, obiwan, maul], 1, 1) }
106
+
107
+ # it "moves the remaining competitors to the second round" do
108
+ # expect(subject.size).to eq(4)
109
+ # end
110
+ # end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,22 @@
1
+ module Brackets::Util
2
+ describe BooleanCounter do
3
+ describe "#next_if" do
4
+ it "advances the counter when the param is true" do
5
+ expect(subject.next_if(true)).to eq(1)
6
+ end
7
+
8
+ it "keeps advancing if called multiple times" do
9
+ subject.next_if(true)
10
+ expect(subject.next_if(true)).to eq(2)
11
+ end
12
+
13
+ it "noes not advance the value when the param evals to false" do
14
+ expect(subject.next_if(false)).to eq(0)
15
+ end
16
+
17
+ it "returns the given value when param evals to false" do
18
+ expect(subject.next_if(false, "Nothing")).to eq("Nothing")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,7 @@
1
+ require 'pry'
2
+ require_relative "../lib/brackets.rb"
3
+
4
+ RSpec.configure do |config|
5
+ config.filter_run :focus
6
+ config.run_all_when_everything_filtered = true
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brackets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vitor HP Bittencourt
@@ -15,7 +15,20 @@ email: vitorhp2@gmail.com
15
15
  executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
- files: []
18
+ files:
19
+ - ".gitignore"
20
+ - ".rspec"
21
+ - Gemfile
22
+ - Gemfile.lock
23
+ - Guardfile
24
+ - brackets.gemspec
25
+ - lib/brackets.rb
26
+ - lib/brackets/match.rb
27
+ - lib/brackets/tournament.rb
28
+ - lib/brackets/util/boolean_counter.rb
29
+ - spec/brackets/tournament_spec.rb
30
+ - spec/brackets/util/boolean_counter_spec.rb
31
+ - spec/spec_helper.rb
19
32
  homepage: http://rubygems.org/gems/brackets
20
33
  licenses:
21
34
  - MIT