Bracket Filling Logic

posted on 03/05/06 at 12:36:25 am by Joel Ross

Now that the Tourney Bracket Control is in the wild,?lets talk about how a bracket should be laid out. This is one of the things we changed in the Tourney Bracket Control (TBC) 2.0 - we've extracted away the complexities of how brackets should be created and allowed developers to focus on what they want to do with the data coming from the bracket. We're confident that this will make developing with the Tourney Bracket Control much simpler, and you'll be able to get a bracket up and running a LOT faster than before because you don't have to think about the details ahead of time. And in case you don't beleive it, we went ahead and did just that. From our Quickstarts, we created a page where you can quickly add and remove teams from a bracket. The code to do this is quite simple, and just so you know it's not smoke and mirrors, here it is:

protected void AddButton_Click(object sender, EventArgs e)
{
?? Bracket1.Competitors.Add(new BracketCompetitor());
}

protected void Page_PreRender(object sender, EventArgs e)
{
?? if (Bracket1.Competitors.Count <= 2)
??????RemoveButton.Enabled = false;
else
????? RemoveButton.Enabled = true;
}

protected void RemoveButton_Click(object sender, EventArgs e)
{
?? Bracket1.Competitors.Remove(Bracket1.Competitors[Bracket1.Competitors.Count - 1]);
}

As you can see, it's dirt simple to do. The PreRender code isn't technically needed - this just ensures you don't ever drop below two competitors (and seriously, what good is a bracket for one team?). But since it's so simple to build, of course that means that we're worrying the details. Now, when you're working with the TBC, you won't really need to know how we figured out the layout and how teams are assigned. You'll just need to know where the competitors are assigned, and go from there. But I'm sure some out there will be curious about how we're doing it under the hood.

And I'm here to help.

The simple case is pretty easy. This is when the number of teams is a power of two - 2, 4, 8, 16, 32, etc. Why is this the easy case? Well, the first round is always full. There aren't any byes. Things get a little tricky when you have byes in the first round. Let's say you have 13 teams. This means that three teams get a bye in the first round. So, where do you assign teams and where do you give byes? The easiest way would be to assign two teams to each of the first round games, and the bottom three would be byes, but that's not right. Why? Well, in the second round, you'd end up with two teams who got byes playing each other. Teams usually earn byes, which means that teams 1-3 would have earned the right to take a round off. Making team 1 and team 2 play in the second round would be unfair to both of them.

So, what's the proper way to create the match ups? Well, it turns out to be an iterative process. Instead of starting in the first round, you actually start with the final round and work backwards. The final game has two "feeding" games. Game 1 feeds Game 2 if the winner of Game 1 becomes one of the competitors in Game 2. Creating the feeding games is pretty straight forward. You don't have much of a choice. The next two match ups are either the upper feeder or the lower feeder. The next set is more complicated. You have two match ups that each have two feeders. Like I mentioned before, you can't just do it in order - if you only had two match ups left, you'd end up with the top match up having two feeders and the other having none - an unfair situation.

So, you number the open slots 1 through 4. Start with one, then go to 4, back to two and finally slot 3. The next round you have 8 feeder slots for 4 match ups. The process is the same, except now a pattern starts to develop. If you number the slots 1 through 8, the slot assignment order works out like this: 1, 8, 4, 5, 2, 7, 3, 6. The sum of each pair is one plus the number of slots. But the pattern is more than just summing up to 9. It also can be continued for the next round. You get 16 slots, and the easiest way to determine what the slot assignment order for the next round is to take the assignment order from the previous round and add your numbers into it. Treat each element as one half of the pair, and remember that each pair adds up to 17 (16 slots + 1). So the order becomes: 1, 16 (17-1), 8, 9 (17-8), 4, 13 (17-4 - you get the idea right?), 5, 12, 2, 15, 7, 10, 3, 14, 6, 11. Yes, these are the same seed pairings as you'll see in the NCAA tourney.

The advantage of doing it?this way is that you can stop at any point and have a valid bracket. If you only have thirteen teams for 16 slots, then slots 14, 6 and 11 are open. This makes the bye situation much?more reasonable.

Now, from a Tourney Bracket Control perspective, we make things a little more friendly. Instead of having match up IDs (which are generated) that jump all over the place, we go through and re-assign them, so they are in order. For a 64 team tourney, round 1 will be MatchUp1 through MatchUp32, Round 2 will be MatchUp33 through MatchUp48, etc. Then we use the assignment order for the first round to determine where the team slots are, but teams are put into the slot in order also - so when you bind up to the TBC, you can order your teams in such a way that you can determine the initial match ups fairly easily.

So, how does all this work in a double elimination bracket? Good try. I've got it worked out, but because we wanted to get it released, we pulled it out. We'll finish that up this summer, and then I'll talk about how double elimination brackets are created and teams are assigned.

Categories: Develomatic