Examples Delphi

Title: How To Create A Round Robin Tournament Schedule
Question: How do I create a balanced round robin tournament schedule which ensures that every team plays every other team once with the minimum amount of idle time (a/k/a byes) and ensures that teams have an equal number of home and away games.
Answer:
The creation of a balanced round robin schedule is more complex than it first appears. There are several delphi round-robin components that are available on the web ... for example the one from engerning objects international at http://www.engineeringobjects.com/RndRobin.htm which costs $495.00. I wrote this algorithm to quickly and cheaply calculate a round robin schedule. Currently, the program has a hard-coded maximum number of 500 teams; however, this can easily be increased. If you have no need for such an algorithm then so be it, but I hope that anyone who needs to create such a schedule will give this algorithm a try. The CreateRoundRobin procedure will easily create a schedule for you.
For example assume that there are 5 teams, a valid schedule would be.
Round 1
Home : 1 Away: 4
Home : 2 Away: 3
Home : 5 Away: -1
Round 2
Home : 5 Away: 3
Home : 1 Away: 2
Home : 4 Away: -1
Round 3
Home : 4 Away: 2
Home : 5 Away: 1
Home : 3 Away: -1
Round 4
Home : 3 Away: 1
Home : 4 Away: 5
Home : 2 Away: -1
Round 5
Home : 2 Away: 5
Home : 3 Away: 4
Home : 1 Away: -1
Most traditional round robin schedules look like the following, but there is no easy way to calculate which team is the home team (or has the home field) and which team is away team (or plays on the away field).
team
\ 1 2 3 4 5 6 7 8 9 10
round \............................................................
1: 10 9 8 7 6 5 4 3 2 1
2: 6 10 9 8 7 1 5 4 3 2
3: 2 1 10 9 8 7 6 5 4 3
4: 7 3 2 10 9 8 1 6 5 4
5: 3 4 1 2 10 9 8 7 6 5
6: 8 5 4 3 2 10 9 1 7 6
7: 4 6 5 1 3 2 10 9 8 7
8: 9 7 6 5 4 3 2 10 1 8
9: 5 8 7 6 1 4 3 2 10 9
Instead of creating a tratitional [N by N] array, I have created an [N by 1/2 N by 2] array to keep track of the home and away aspects of the round robin tournament.
const
MaxTeams = 500;
MaxRounds = MaxTeams;
MaxGames = (MaxTeams+1) Div 2;
Home = 1;
Away = 2;
Bye : Integer = -1;
type
TGameAry = Array[1..MaxTeams] of Integer;
TRoundRobinAry = Array[1..MaxRounds,1..MaxGames,Home..Away] of Integer;
....
procedure TForm1.CreateRoundRobin(var RoundRobinAry: TRoundRobinAry;
const Teams: Integer);
var
GameAry : TGameAry;
Half,
Rounds,
Bottom,
SwitchBottom,
TempGameValue,
i,
ii,
iii : Integer;
begin
For i := 1 to MaxRounds do
For ii := 1 to MaxGames do
For iii := 1 to 2 do
RoundRobinAry[i][ii][iii] := 0;
IF ((Teams MaxTeams)) Then exit;
//Initilize Team Array with Team Numbers
For i := 1 to Teams do
GameAry[i] := i;
if (Teams then For i := (Teams+1) to MaxTeams do
GameAry[i] := 0;
Half := (Teams-1) Div 2;
IF ((Teams Mod 2)=0)
Then Begin
Rounds := Teams - 1;
Bottom := Teams - 2;
SwitchBottom := Bottom + 1;
End
else Begin
Rounds := Teams;
Bottom := Teams - 1;
SwitchBottom := Teams;
end;
for i := 1 to Rounds do
begin
for ii := 1 to Half do
begin
RoundRobinAry[i][ii][Home] := GameAry[ii];
RoundRobinAry[i][ii][Away] := GameAry[Bottom-ii+1];
end;
If ((Teams - Bottom) = 2) // if even number of teams
then begin
if i mod 2 = 0
then begin
RoundRobinAry[i][Half+1][Home] := GameAry[SwitchBottom];
RoundRobinAry[i][Half+1][Away] := GameAry[Bottom+2];
end
else begin
RoundRobinAry[i][Half+1][Away] := GameAry[SwitchBottom];
RoundRobinAry[i][Half+1][Home] := GameAry[Bottom+2];
end
end
else begin // if odd number of teams then idle team gets a bye
RoundRobinAry[i][Half+1][Home] := GameAry[SwitchBottom];
RoundRobinAry[i][Half+1][Away] := Bye;
end;
//rotate value of gameary
TempGameValue := GameAry[SwitchBottom];
for ii := SwitchBottom downto 2 do
GameAry[ii] := GameAry[ii-1];
GameAry[1] := TempGameValue;
end;
end;
You can easily print the result to a richedit with a push of a button.
procedure TForm1.Button1Click(Sender: TObject);
const NoOfTeams : integer = 7;
var roundrobinary : TRoundRobinAry;
begin
RichEdit1.Clear;
CreateRoundRobin(RoundRobinAry,NoOfTeams);
PrintFullChart(RoundRobinAry); //see below
end;
Procedure Tform1.PrintFullChart(const RoundRobinAry: TRoundRobinAry;);
var i,ii : integer;
begin
richedit1.Lines.BeginUpdate;
i := 1;
ii := 1;
repeat;
Richedit1.Lines.Add(Format('Round : %d', [i]));
while (RoundRobinAry[i][ii][Home] 0) do
begin
if RoundRobinAry[i][ii][away] - 1 then
Richedit1.Lines.Add(Format('Home : %3.0d Away: %3.0d', [RoundRobinAry[i][ii][Home],RoundRobinAry[i][ii][Away]]))
else
Richedit1.Lines.Add(Format('BYE FOR TEAM : %3.0d', [RoundRobinAry[i][ii][Home]]));
inc(ii);
end;
inc(i);
ii := 1;
until (RoundRobinAry[i][ii][Home] = 0);
Richedit1.Lines.endupdate;
end;