Generating Fixture Lists

Update 2007-03-21: If all you want to do is generate a fixtures list you can use my Fixtures Generator

I’ve been trying to find out how to generate fixture lists for some time (it is harder than it sounds!) and I finally worked it out thanks to this page about a fixture generating algorithm. My Java implementation of the algorithm is below.

/* 
 * This code owes an enormous debt to 
 * http://www.barrychessclub.org.uk/berger2001.htm 
 */

import java.util.Arrays;

public class Fixtures2 {

    public static void main(String[] args) {
        
        // Find out how many teams we want fixtures for.
        int teams = 0;
        try {
            teams = Integer.parseInt(args[0]);
        } catch (NumberFormatException e) {
            System.err.println("Please state number of teams as first arg.");
            System.exit(0);
        }
        
        // If odd number of teams add a "ghost".
        boolean ghost = false;
        if (teams % 2 == 1) {
            teams++;
            ghost = true;
        }
        
        // Generate the fixtures using the cyclic algorithm.
        int totalRounds = teams - 1;
        int matchesPerRound = teams / 2;
        String[][] rounds = new String[totalRounds][matchesPerRound];
        
        for (int round = 0; round < totalRounds; round++) {
            for (int match = 0; match < matchesPerRound; match++) {
                int home = (round + match) % (teams - 1);
                int away = (teams - 1 - match + round) % (teams - 1);
                // Last team stays in the same place while the others
                // rotate around it.
                if (match == 0) {
                    away = teams - 1;
                }
                // Add one so teams are number 1 to teams not 0 to teams - 1
                // upon display.
                rounds[round][match] = (home + 1) + " v " + (away + 1);
            }
        }
        
        // Interleave so that home and away games are fairly evenly dispersed.
        String[][] interleaved = new String[totalRounds][matchesPerRound];
        
        int evn = 0;
        int odd = (teams / 2);
        for (int i = 0; i < rounds.length; i++) {
            if (i % 2 == 0) {
                interleaved[i] = rounds[evn++];
            } else {
                interleaved[i] = rounds[odd++];
            }
        }
        
        rounds = interleaved;

        // Last team can't be away for every game so flip them
        // to home on odd rounds.
        for (int round = 0; round < rounds.length; round++) {
            if (round % 2 == 1) {
                rounds[round][0] = flip(rounds[round][0]);
            }
        }
        
        // Display the fixtures        
        for (int i = 0; i < rounds.length; i++) {
            System.out.println("Round " + (i + 1));
            System.out.println(Arrays.asList(rounds[i]));
            System.out.println();
        }
        
        System.out.println();
        
        if (ghost) {
            System.out.println("Matches against team " + teams + " are byes.");
        }
        
        System.out.println("Use mirror image of these rounds for "
            + "return fixtures.");
    }

    private static String flip(String match) {
        String[] components = match.split(" v ");
        return components[1] + " v " + components[0];
    }
}

Update 2005-06-05: Now allows “complementary teams”, that is – teams that never play at home at the same time as each other. For example, try 10 teams — for each pair from 1 & 6, 2 & 7, 3 & 8, 4 & 9, and 5 & 10, both are never both at home. It was meant to be in the original program but a bug in my code was fouling things up.

Update 2007-03-21: You might also want to see the source code to my PHP fixtures generator

61 Replies to “Generating Fixture Lists”

  1. You could randomize which team is Team 1, Team 2, etc. I’d be surprised if anyone noticed.

  2. Hi, thanks for your code!!
    I dont understand because the mirrors of First Round in the First Half is the Last Round of Second Half… i think that would be in First Round of Second Half…

    .. in Round 1 in the First Half i have
    Round 1
    1 v 6
    2 v 5
    3 v 4
    And in Round 6 (first round of the Second Half) i haven’t the mirror of the Round 1!!
    Round 6
    6 v 3
    2 v 4
    1 v 5

    But the real mirror round of Round 1 is in the last round of second half (Round 10)
    Round 10
    6 v 1
    5 v 2
    4 v 3

    Thank for your help…

  3. I have tried the above java program but i’ve always been getting an error, Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 0
    can anyone help me, i’ve tried teams = 0 and teams = 10; and still nothing seems to be fine

  4. @Steven – You have to pass the number of teams on the commandline …

    $ java Fixtures2 10

    for 10 teams for example.

    My try … catch around teams = Integer.parseInt(args[0]); is meant to catch this case but does not!

  5. Is there any way to code display the second half of the league in the Java code?

    Also I want to look into how I could permutate the whole schedule to make the second half of the league not so similar as the first while still maintaining a good Home and Away spread. Is there any help I could have with this?

  6. I figured out how to code the second half of the league. Now I just need to find a way to make the second half different from the first, but have a good solid home and away spread.

  7. ive 62 teams in total to go into into 5 divisions but 19 ot the teams have two teams..how do I keep them teams from there two teams at home at the same time

  8. how can i make the fixtures to be played across 2 days..like half of the fixtures in round 1 to be played on saturday and the remaining half played on sunday every round.

  9. Hello, I had one interview. This summer saved my life. Thank you so much for sharing everything as open source

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.