using System.Collections.Generic;
using System.Threading.Tasks.Dataflow;
static void Main(string[] args)
var allTeams = GetInitialisedTeams(10);
var allSessions = new Session[totalSessions];
for (int i = 0; i < totalSessions; i++)
var tableA = GetTable(allTeams);
var tableB = GetTable(allTeams, tableA.TeamNumbers);
allSessions[i] = new Session(tableA, tableB);
foreach (int team in tableA.TeamNumbers)
allTeams[team].IncrementCountsFor(tableA.TeamNumbers, team);
foreach (int team in tableB.TeamNumbers)
allTeams[team].IncrementCountsFor(tableB.TeamNumbers, team);
Console.WriteLine("Generated Sessions:");
Console.WriteLine(PrintSessions(allSessions));
for (int i = 0; i < allTeams.Length; i++)
Console.WriteLine($"Team {i} playcounts: {allTeams[i].GetPlaycountString()}");
var shuffledSessions = ShuffleSessions(allSessions);
Console.WriteLine("---------------------------------------------");
Console.WriteLine("Randomized Sessions");
Console.WriteLine(PrintSessions(shuffledSessions));
public static Session[] ShuffleSessions(Session[] currentSessions)
var newSessions = currentSessions;
Random rand = new Random();
for (int i = 0; i < newSessions.Length - 1; i++)
int j = rand.Next(i, newSessions.Length);
var temp = newSessions[i];
newSessions[i] = newSessions[j];
public static string PrintSessions(Session[] allSessions)
StringBuilder builder = new StringBuilder();
for (int i = 0; i < allSessions.Length; i++)
builder.Append(allSessions[i].ToString(i)).Append("\r\n");
return builder.ToString();
public static Table GetTable(Team[] allTeams, params int[] excludedTeams)
List<int> excluded = new List<int>(excludedTeams);
var a = GetLowestPlayCount(allTeams, excludedTeams);
var b = GetLowestPlayCountWithTeams(allTeams, new[] { a }, excluded.ToArray());
var c = GetLowestPlayCountWithTeams(allTeams, new[] { a, b }, excluded.ToArray());
var d = GetLowestPlayCountWithTeams(allTeams, new[] { a, b, c }, excluded.ToArray());
return new Table(a, b, c, d);
public static int GetLowestPlayCount(Team[] allTeams, int[] excludedTeams)
int teamPlaycount = int.MaxValue;
for (int i = 0; i < allTeams.Length; i++)
if (!excludedTeams.Contains(i))
var nextPlaycount = allTeams[i].GetTotalPlayedCount();
if (nextPlaycount < teamPlaycount)
teamPlaycount = nextPlaycount;
public static int GetLowestPlayCountWithTeams(Team[] allTeams, int[] matchingTeams, params int[] excludedTeams)
int teamPlaycount = int.MaxValue;
for (int i = 0; i < allTeams.Length; i++)
if (!excludedTeams.Contains(i))
var nextPlaycount = allTeams[i].GetPlayedCountForTeams(matchingTeams);
if (nextPlaycount < teamPlaycount)
teamPlaycount = nextPlaycount;
public static Team[] GetInitialisedTeams(int numberOfTeams)
var teams = new Team[numberOfTeams];
for (int i = 0; i < numberOfTeams; i++)
teams[i] = new Team(numberOfTeams);
public int[] PlayedWithCount;
public Team(int totalTeams)
PlayedWithCount = new int[totalTeams];
public int GetTotalPlayedCount()
foreach (int v in PlayedWithCount)
public int GetPlayedCountForTeams(params int[] teams)
res += PlayedWithCount[i];
public void IncrementCountsFor(int[] teams, int thisIndex)
foreach (int team in teams)
PlayedWithCount[team] = 999;
public string GetPlaycountString()
return $"[{string.Join(", ", PlayedWithCount)}]";
public readonly Table TableA;
public readonly Table TableB;
public Session(Table a, Table b)
public string ToString(int index)
return $"[Session {index} - A: {TableA}, B: {TableB}";
public readonly int[] TeamNumbers;
public Table(int a, int b, int c, int d)
TeamNumbers = new[] { a, b, c, d };
return $"[{string.Join(", ", TeamNumbers)}]";