Skip to content

Instantly share code, notes, and snippets.

@cadwallion
Created August 23, 2012 02:30
Show Gist options
  • Select an option

  • Save cadwallion/3431526 to your computer and use it in GitHub Desktop.

Select an option

Save cadwallion/3431526 to your computer and use it in GitHub Desktop.
BracketTree Template Generator
module BracketGenerator
class Node < Struct.new(:left, :right, :position, :depth, :render)
def initialize
self.render = true
end
def add
self.left = Node.new
self.right = Node.new
end
def children
left = self.left ? self.left.position : nil
right = self.right ? self.right.position : nil
[left, right]
end
end
class Base
attr_reader :size, :root, :rounds, :node_count
def initialize size
@size = size
@root = Node.new
end
def generate
add_nodes
calculate_positions
end
def add_nodes
raise NotImplementedError
end
def in_order(node, &block)
if node
in_order(node.left, &block) unless node.left.nil?
block.call(node)
in_order(node.right, &block) unless node.right.nil?
end
end
def top_down(node, &block)
if node
block.call(node)
top_down(node.left, &block) unless node.left.nil?
top_down(node.right, &block) unless node.right.nil?
end
end
def calculate_positions
counter = 1
in_order @root do |node|
node.position = counter
counter += 1
end
@node_count = counter
end
def to_a
nodes = []
top_down(root) do |node|
nodes << { position: node.position}
end
nodes
end
end
class SingleElimination < Base
def initialize size
super
@rounds = (Math.log(size) / Math.log(2)).to_i
end
def add_nodes
add_to @root, 0
@root
end
def add_to node, depth
if depth < @rounds
node.left = Node.new
node.right = Node.new
node.depth = depth
add_to(node.left, depth+1)
add_to(node.right, depth+1)
end
node
end
end
class DoubleElimination < Base
def initialize size
super
@rounds = 1
remaining = size / 2
counter = 0
while remaining > 1
@rounds += 1
counter += 1
if counter % 2 == 0
remaining = remaining / 2
end
end
end
def add_nodes
generate_winners_bracket
generate_losers_bracket
end
def generate_winners_bracket
winners_bracket = SingleElimination.new(@size)
@root.left = winners_bracket.add_nodes
end
def generate_losers_bracket
@root.right = Node.new
add_to @root.right, 1
end
def add_to node, depth
if depth < @rounds
node.left = Node.new
node.right = Node.new
left = true
add_to(node.left, depth+1) if depth % 2 == 0 || !left
add_to(node.right, depth+1) if depth % 2 == 0 || left
left = !left if depth % 2 == 1
end
node
end
end
class Bullshit < Base
def add_nodes
@root = generate_bullshit
@root.left.left.left.left = generate_section
@root.left.left.left.right = generate_section
@root.left.left.right.left = generate_section
@root.left.left.right.right = generate_section
@root.left.right.left.left = generate_section
@root.left.right.left.right = generate_section
@root.left.right.right.left = generate_section
@root.left.right.right.right = generate_section
end
def generate_bullshit
node = Node.new
node.render = false
node.add
node.left.render = false
node.left.add
node.right.render = false
node.right.add
node.left.left.render = false
node.left.left.add
node.left.right.render = false
node.left.right.add
node.right.left.render = false
node.right.left.add
node.right.right.render = false
node.right.right.add
node
end
end
class WinnerBullshit < Bullshit
def generate_section
node = Node.new
node.left = generate_left
node.right = generate_right
return node
end
def generate_left
node = Node.new
node.add
node.left.add
node.left.left.add
node.left.left.left.add
node.left.left.left.left.add # empty
node.left.left.left.left.left.render = false
node.left.left.left.left.right.render = false
node.left.left.left.right.add
node.left.left.right.add
node.left.left.right.left.add
node.left.left.right.right.add # empty
node.left.left.right.right.left.render = false
node.left.left.right.right.right.render = false
node.left.right.add
node.left.right.left.add
node.left.right.left.left.add # empty
node.left.right.left.left.left.render = false # empty
node.left.right.left.left.right.render = false # empty
node.left.right.left.right.add
node.left.right.right.add
node.left.right.right.left.add
node.left.right.right.right.add # empty
node.left.right.right.right.left.render = false # empty
node.left.right.right.right.right.render = false # empty
node
end
def generate_right
node = Node.new
node.add
node.right.add
node.right.left.add
node.right.left.left.add
node.right.left.left.right.add
node.right.left.right.add
node.right.left.right.left.add
node.right.right.add
node.right.right.left.add
node.right.right.left.right.add
node.right.right.right.add
node.right.right.right.left.add
return node
end
end
class LoserBullshit < Bullshit
def generate_section
node = Node.new
node.render = false
node.add
node.right.render = false
node.right.add
node.right.left.render = false
node.right.right.render = false
node.right.left = generate_left
node.right.right = generate_right
node
end
def generate_left
node = Node.new
node.add
node.right.add
node.right.left.add
node.right.left.left.add
node.right.left.left.left.add
node.right.left.left.left.left.add
node.right.left.left.left.right.add
node.right.left # Y
node.right.left.right.add
node.right.left.right.right.add # Z
node.right.left.right.right.left.add
node.right.left.right.right.right.add
node
end
def generate_right
node = Node.new
node.add # A
node.left.add
node.left.right.add # B
node.left.right.left.add
node.left.right.left.left.add # C
node.left.right.left.left.left.add
node.left.right.left.left.right.add
node.left.right.right.add
node.left.right.right.right.add # D
node.left.right.right.right.left.add
node.left.right.right.right.right.add
node
end
end
class TotalBullshit < Base
def add_nodes
@root.render = false
@root.left = add_winners
@root.right = add_losers
end
def add_winners
winners = WinnerBullshit.new(nil)
winners.add_nodes
winners.root
end
def add_losers
losers = LoserBullshit.new(nil)
losers.add_nodes
losers.root
end
end
class ChampionshipLosers < Base
def add_nodes
@root.left = add_side
@root.right = add_side
end
def add_side
node = Node.new
node.add
node.right.add
node.right.right.add
node.right.right.right.add
node.right.right.right.left = add_portion
node.right.right.right.right = add_portion
node
end
def add_portion
node = Node.new
node.add
node.right.add
node.right.right.add
node.right.right.right.add
node.right.right.right.left.add
node.right.right.right.left.right.add
node.right.right.right.right.add
node.right.right.right.right.right.add
node
end
end
class ChampionshipBracket < Base
def add_nodes
@root.left = add_winners
@root.right = add_losers
end
def add_winners
single = SingleElimination.new(8)
single.add_nodes
single.root
end
def add_losers
losers = ChampionshipLosers.new(nil)
losers.add_nodes
losers.root
end
end
class GroupPlay < Base
def add_nodes
@root.left = add_group_play
@root.right = add_championship_bracket
end
def add_group_play
group_play = DoubleElimination.new(32)
group_play.add_nodes
group_play.root
end
def add_championship_bracket
champ = ChampionshipBracket.new(nil)
champ.add_nodes
champ.root
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment