Permalink
Browse files

BracketTree::Bracket implementation

  • Loading branch information...
0 parents commit eb7f431e1dac32c4b0a30e04ba8e7b3a6c5bf9da @cadwallion cadwallion committed May 10, 2012
Showing with 299 additions and 0 deletions.
  1. +4 −0 .gitignore
  2. +4 −0 Gemfile
  3. +74 −0 README.md
  4. +8 −0 Rakefile
  5. +24 −0 bracket_tree.gemspec
  6. +5 −0 lib/bracket_tree.rb
  7. +74 −0 lib/bracket_tree/bracket.rb
  8. +14 −0 lib/bracket_tree/node.rb
  9. +3 −0 spec/spec_helper.rb
  10. +89 −0 spec/unit/bracket_tree/bracket_spec.rb
4 .gitignore
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
4 Gemfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in bracket_tree.gemspec
+gemspec
74 README.md
@@ -0,0 +1,74 @@
+BracketTree.new(@bracket)
+
+```
+bracket = BracketTree::Bracket.generate(size: 16, type: 'single-elim')
+```
+
+Advanced
+```
+template = BracketTree::Templates::DoubleElimination.new(16)
+players = []
+16.times { |n| players << {player: "RandomPlayer#{n}" } }
+bracket = BracketTree::Bracket.generate(template: template, players: players)
+```
+
+Already have your seats mapped? Great!
+
+```
+array_of_seats = [
+ { position: 1, player: 'RandomPlayer1' },
+ { position: 3, player: 'RandomPlayer2' },
+ { position: 2, player: 'RandomPlayer1' }
+]
+
+bracket = BracketTree::Bracket.generate(size: 2, type: 'single-elim', seats: array_of_seats)
+```
+
+
+Crazy experimental shit, takes games and maps them to seats in a bracket template.
+By default, it fills in the order of seats, which means the top half will fill entirely
+before the bottom half, but you can optionally pass the `half` key to tell it to fill
+from the bottom half.
+
+
+```
+games = [
+ {
+ top_seed: {
+ player: 'Player 1',
+ seed_value: 1
+ },
+ bottom_seed: {
+ player: 'Player 4',
+ seed_value: 4
+ },
+ winner: 1
+ },
+ {
+ top_seed: {
+ player: 'Player 3',
+ seed_value: 3
+ },
+ bottom_seed: {
+ player: 'Player 2',
+ seed_value: 2
+ },
+ winner: 2
+ },
+ {
+ top_seed: {
+ player: 'Player 1',
+ seed_value: 1
+ },
+ bottom_seed: {
+ player: 'Player 2',
+ seed_value: 2
+ },
+ winner: 1
+ }
+]
+bracket = BracketTree::Bracket.generate_blank(size: 16, type: 'single-elim')
+bracket.add_game(games[0])
+bracket.add_game(games[1], half: :bottom)
+bracket.add_game(games[2])
+```
8 Rakefile
@@ -0,0 +1,8 @@
+require "bundler/gem_tasks"
+require 'rspec/core/rake_task'
+
+
+task :default => :spec
+
+desc "Run specs"
+RSpec::Core::RakeTask.new(:spec)
24 bracket_tree.gemspec
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+
+Gem::Specification.new do |s|
+ s.name = "bracket_tree"
+ s.version = '0.0.1'
+ s.authors = ["Andrew Nordman"]
+ s.email = ["cadwallion@gmail.com"]
+ s.homepage = ""
+ s.summary = %q{TODO: Write a gem summary}
+ s.description = %q{TODO: Write a gem description}
+
+ s.rubyforge_project = "bracket_tree"
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+
+ # specify any dependencies here; for example:
+ s.add_development_dependency "rspec"
+ s.add_development_dependency "rake"
+ # s.add_runtime_dependency "rest-client"
+end
5 lib/bracket_tree.rb
@@ -0,0 +1,5 @@
+require 'json'
+require 'bracket_tree/bracket'
+
+module BracketTree
+end
74 lib/bracket_tree/bracket.rb
@@ -0,0 +1,74 @@
+require 'bracket_tree/node'
+
+module BracketTree
+ class Bracket
+ include Enumerable
+ attr_accessor :root, :insertion_order
+
+ def initialize
+ @insertion_order = []
+ end
+
+ def add position, data
+ node = Node.new position, data
+ @insertion_order << position
+
+ if @root.nil?
+ @root = node
+ else
+ current = @root
+ loop do
+ if node.position < current.position
+ if current.left.nil?
+ current.left = node
+ break
+ else
+ current = current.left
+ end
+ elsif node.position > current.position
+ if current.right.nil?
+ current.right = node
+ break
+ else
+ current = current.right
+ end
+ else
+ break
+ end
+ end
+ end
+ end
+
+ def add_winner winner
+ @root.payload.seed_value = winner.seed_position
+ @root.payload.race = winner.race
+ @root.payload.player = winner.user.login
+ end
+
+ def each(&block)
+ in_order(@root, block)
+ end
+
+ def nodes
+ to_a.sort_by { |node| @insertion_order.index(node.position) }
+ end
+
+ def size
+ @insertion_order.size
+ end
+
+ def in_order(node, block)
+ if node
+ unless node.left.nil?
+ in_order(node.left, block)
+ end
+
+ block.call(node)
+
+ unless node.right.nil?
+ in_order(node.right, block)
+ end
+ end
+ end
+ end
+end
14 lib/bracket_tree/node.rb
@@ -0,0 +1,14 @@
+module BracketTree
+ class Node
+ attr_accessor :left, :right, :position, :payload
+
+ def initialize position, payload = nil
+ @position = position
+ @payload = payload
+ end
+
+ def method_missing(sym, *args, &block)
+ @payload.send sym, *args, &block
+ end
+ end
+end
3 spec/spec_helper.rb
@@ -0,0 +1,3 @@
+$:.push File.join(File.dirname(__FILE__), '..', 'lib')
+
+require 'bracket_tree'
89 spec/unit/bracket_tree/bracket_spec.rb
@@ -0,0 +1,89 @@
+require 'spec_helper'
+
+describe BracketTree::Bracket do
+ describe '#add' do
+ let(:root_payload) { { bar: 'bar' } }
+ let(:payload) { { foo: 'foo' } }
+
+ context 'no nodes present' do
+ before do
+ subject.root.should be_nil
+ subject.add 4, root_payload
+ end
+
+ it 'should create a new Node at root' do
+ subject.root.should be_a_kind_of BracketTree::Node
+ end
+
+ it 'should set the payload of the new node to the passed object' do
+ subject.root.payload.should == root_payload
+ end
+
+ it 'should set the position of the root node to the passed position' do
+ subject.root.position.should == 4
+ end
+ end
+
+ context 'root node present' do
+ before do
+ subject.add 4, root_payload
+ subject.add 2, payload
+ end
+
+ it 'should add a node to the left position of root' do
+ subject.root.left.should be_a_kind_of BracketTree::Node
+ end
+
+ it 'should have the payload of the new node' do
+ subject.root.left.payload.should == payload
+ end
+
+ it 'should have the position of the new node' do
+ subject.root.left.position.should == 2
+ end
+ end
+
+ context 'two nodes present' do
+ let(:new_payload) { { baz: 'baz' } }
+ before do
+ subject.add 4, root_payload
+ subject.add 2, payload
+
+ subject.root.left.right.should be_nil
+ subject.add 3, new_payload
+ end
+
+ it 'should add the new node to the left node right' do
+ subject.root.left.right.should be_a_kind_of BracketTree::Node
+ end
+
+ it 'should add the payload of the new node' do
+ subject.root.left.right.payload.should == new_payload
+ end
+
+ it 'should add the position of the new node' do
+ subject.root.left.right.position.should == 3
+ end
+ end
+ end
+
+ describe '#nodes' do
+ let(:payload1) { { foo: 'foo' } }
+ let(:payload2) { { bar: 'bar' } }
+ let(:payload3) { { baz: 'baz' } }
+
+ before do
+ subject.add 4, payload1
+ subject.add 2, payload2
+ subject.add 3, payload3
+ end
+
+ it 'should return 3 node objects' do
+ subject.nodes.should have(3).nodes
+ end
+
+ it 'should return them in insertion order' do
+ subject.nodes.map { |n| n.position }.should == [4,2,3]
+ end
+ end
+end

0 comments on commit eb7f431

Please sign in to comment.