Tournament construction and maintenance including competition based structures and helpers.

This library is intended to be imported qualified as it exports functions that clash with
Prelude.

import Game.Tournament as T

The Tournament structure contain a Map of GameId -> Game for its internal
representation and the GameId keys are the location in the Tournament.

Duel tournaments are based on the theory from http://clux.org/entries/view/2407.
By using the seeding definitions listed there, there is almost only one way to
generate a tournament, and the ambivalence appears only in Double elimination.

We have additionally chosen that brackets should converge by having the losers bracket move upwards.
This is not necessary, but improves the visual layout when presented in a standard way.

FFA tournaments use a collection of sensible assumptions on how to
optimally split n people into s groups while minimizing the sum of seeds difference
between groups for fairness. At the end of each round, groups are recalculated from the scores
of the winners, and new groups are created for the next round.

Building Block B: Group helpers

Splits a numer of players into groups of as close to equal seeding sum
as possible. When groupsize is even and s | n, the seed sum is constant.
Fixes the number of groups as ceil $ n / s, but will reduce s when all groups not full.

Tournament Interface

Create match shells for an FFA elimination tournament.
Result comes pre-filled in with either top advancers or advancers intersect seedList.
This means what the player numbers represent is only fixed per round.
TODO: Either String Tournament as return for intelligent error handling

Score a match in a tournament and propagate winners/losers.
If match is not scorable, the Tournament will pass through unchanged.

For a Duel tournament, winners (and losers if Double) are propagated immediately,
wheras FFA tournaments calculate winners at the end of the round (when all games played).

There is no limitation on re-scoring old games, so care must be taken to not update too far
back ones and leaving the tournament in an inconsistent state. When scoring games more than one
round behind the corresponding active round, the locations to which these propagate must
be updated manually.

To prevent yourself from never scoring older matches, only score games for which
safeScorable returns True. Though this has not been implemented yet.

Get the list of all GameIds in a Tournament.
This list is also ordered by GameId's Ord, and in fact,
if the corresponding games were scored in this order, the tournament would finish,
and scorable would only return False for a few special walkover games.
TODO: if introducing crossovers, this would not be true for LB crossovers
=> need to place them in WB in an 'interim round'