Skip to content

Repository files navigation

MatchMakerTool

.NET Build and Test

MatchMakerTool is a set of .NET libraries and a command-line tool for running quiz tournaments that use ACME Quiz Match Maker result files. It can:

  • Generate a schedule for six different tournament types, from a plain list of teams.
  • Produce a results/standings report from a folder of Match Maker score files.
  • Roll up several tournaments into a single multi-event summary.

Reports and schedules can be exported as HTML, Markdown, PDF, RTF, XML, and (for summaries) Excel.

Solution layout

Project Description
Models Core domain types shared by every other project: Team, Church, Quizzer, Schedule, Round, Result, and the TournamentType enum.
Scheduling Builds tournament schedules and generates rounds as results come in. Contains one *Tournament class per TournamentType, plus ITournamentRoundGenerator/TournamentRoundGeneratorFactory for round-by-round advancement.
Reporting Loads Match Maker score files, computes team/quizzer standings and rankings, and exports schedule/summary reports.
Tool The command-line application. Wraps Scheduling and Reporting behind the schedule, report, and summary verbs.
Tool.Unity An in-progress Unity front end (not yet functional).
*.Test Unit tests for the corresponding library project.

Building and testing

dotnet build
dotnet test

Run dotnet test (or dotnet build) from the repository root so it picks up MatchMakerTool.slnx and discovers both test projects.

Command-line usage

Build the tool, then invoke it directly or via dotnet run:

dotnet run --project Tool -- <verb> [options]

Three verbs are available: schedule, report, and summary. Pass --help after any verb (for example dotnet run --project Tool -- schedule --help) to see the full, generated option list.

schedule — generate the initial state of a tournament

dotnet run --project Tool -- schedule -i participants.xml -o .\out -t RoundRobin -n 4
Option Required Description
-i Yes Path to an input schedule/participants XML file (teams, churches, quizzers).
-o Yes Output folder for the generated schedule files.
-t No (default RoundRobin) The TournamentType to generate: RoundRobin, SingleElimination, DoubleElimination, TripleElimination, Swiss, or SwissWithTopCut.
-n No Number of rooms available. Only used for RoundRobin.
-f No (default all) Output formats to produce: any combination of Html, Markdown, Pdf, Rtf, Xml (XML is always produced in addition to whatever is requested).

Important: the CLI only generates the initial state of the tournament:

  • For RoundRobin, the entire round-robin schedule is generated up front, since the full schedule is known in advance.
  • For every other tournament type, only the first round is generated. Teams are seeded in ascending team-id order. Subsequent rounds depend on match results and are not generated by the CLI — see Advancing a tournament below for how a separate controller application generates them using the Scheduling library.

report — generate a results/standings report

dotnet run --project Tool -- report -s .\scores -o .\out -r whse -n "Spring Quiz Meet" -t 8 -m 4 -a 2

Reads every Schedule.*.xml / Results.*.xml pair produced by Match Maker from a source folder, computes standings, and exports a report.

Option Required Description
-s Yes Source folder containing the Match Maker score files.
-o No (default .) Output folder for the report.
-r No (default whse) Ranking procedure: an ordered sequence of tie-break letters, applied left to right — w win percentage, l total losses, h head-to-head, s average score, e average errors.
-n No Tournament name, used in report titles.
-t No (default 0) Number of top-placing round-robin teams that advance, unchanged, into a single-elimination tournament.
-m No (default 0) Number of alternate teams to form from quizzers who didn't advance, for a consolation round robin.
-a No (default 0) Rooms available for the alternate-team round robin (0 runs every match simultaneously).
-f No (default all) Output formats: any combination of Excel, Html, Pdf, Rtf, Xml.

Setting -t/-m also generates the elimination-tournament and alternate-team artifacts alongside the base report.

summary — combine multiple event reports

dotnet run --project Tool -- summary -i .\event1,.\event2,.\event3 -o .\season-summary.xlsx
Option Required Description
-i Yes Comma-separated list of input report paths.
-o Yes Output path for the combined summary.

All verbs accept -v/--verbose for detailed trace output.

Tournament types

MatchMaker.Models.TournamentType defines six formats. All of them are implemented end to end in Scheduling, but the CLI's schedule verb only ever produces the tournament's initial state (see above); a separate, longer-running controller application is expected to drive a tournament to completion round by round using the Scheduling library directly.

Type Elimination rule CLI generates Library supports full progression
RoundRobin Never — every team plays every other team. The complete schedule. N/A — the schedule is complete from creation.
SingleElimination Eliminated after 1 loss. Round 1 only. Yes
DoubleElimination Eliminated after 2 losses. Round 1 only. Yes
TripleElimination Eliminated after 3 losses. Round 1 only. Yes
Swiss Never eliminated; ranked by standings after a fixed number of rounds. Round 1 only. Yes
SwissWithTopCut Swiss stage, then single elimination among the top finishers. Round 1 only. Yes

RoundRobin

Every team plays every other team once. RoundRobinTournament.Create schedules all matches across the requested number of rooms and returns the complete Schedule; there is nothing further to generate.

SingleElimination

A team is eliminated after a single loss. Round 1 pairs the seed list strongest-vs-weakest (1 vs. n, 2 vs. n-1, ...). After each round, EliminationTournament/SingleEliminationRoundGenerator re-pairs the surviving teams the same way until one team remains.

DoubleElimination / TripleElimination

A team is eliminated after 2 (double) or 3 (triple) losses. These share a single internal engine, MultiLifeEliminationTournament, parameterized by the number of lives. Rather than modeling separate winners/losers brackets (the Schedule/Round model has no concept of a bracket), each round re-pairs all teams that have not yet reached the loss limit, ordered by fewest losses first and then by the same strongest-vs-weakest fold used in single elimination. In practice this reproduces the usual double-elimination shape (surviving teams converge into a "grand final," with a "bracket reset" if the team from the loss column wins it) without requiring bracket bookkeeping in the data model.

Swiss

Teams are never eliminated. Round 1 pairs the top half of the seed list against the bottom half (1 vs. n/2+1, 2 vs. n/2+2, ...). Later rounds are paired from current standings (wins descending, then team id ascending) using a greedy nearest-unplayed- opponent search that avoids rematches when possible, falling back to a rematch only if no unplayed opponent remains. The recommended number of rounds is ceil(log2(teamCount)), computed on demand rather than stored, and SwissTournament reports the tournament complete once that many rounds have been played.

Limitation: byes are not scored as wins in the simplified Swiss model (consistent with how byes are handled elsewhere in Schedule).

SwissWithTopCut

Runs the Swiss system for its recommended number of rounds, then appends a single-elimination "top cut" bracket to the same schedule for the top-placing teams. The cut size is always the largest power of two that is at most half the field (with a minimum of 2), which guarantees the elimination bracket never needs a bye.

Advancing a tournament round-by-round

Once a tournament other than RoundRobin has been created (whether by the CLI or otherwise), a controller application can advance it as results come in without branching on the tournament type:

var generator = TournamentRoundGeneratorFactory.For(schedule.EffectiveType);

if (!generator.IsComplete(schedule, result))
{
    var round = generator.CreateNextRound(schedule, result);
    // round is null if the current round hasn't been fully resolved yet.
}

ITournamentRoundGenerator is implemented for every TournamentType, so this is the single entry point a live tournament controller needs for round generation; initial schedule creation (room counts, seeding, and so on) remains type-specific and is exposed directly on each *Tournament class (RoundRobinTournament.Create, EliminationTournament.Create, DoubleEliminationTournament.Create, TripleEliminationTournament.Create, SwissTournament.Create, SwissWithTopCutTournament.Create).

About

A tool for processing ACME Quiz Match Maker results files.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages