bluebones.net

Icon

Adventures in Computer Programming

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

Category: Uncategorized

Tagged:

29 Responses

  1. steve says:

    You have interleaved declared as a 2 dimensional array but it is not clear whether the line “interleaved[i] = rounds” is the zero or first indice in this array. Also, should “rounds.length” be the first indice also? Many thanks.

    // 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++];
    }
    }

  2. Thomas David Baker says:

    At this stage we already have a complete set of rounds for the tournament. But they are not in an ideal order because some teams would play at home or away several times in a row. To get around this we mix up the rounds. It so happens that taking one from the first half then one from the second then one from the first and so on ends up with a much better arrangement so that’s how we do it.

    So, rounds is an array of arrays just like interleaved (it’s probably easier to think of it that way rather than as a multidimensional array although they are much the same thing). Which means we assign an array from rounds to the zeroth index of interleaved at each step until interleaved has one copy of each array in the array of arrays that is rounds.

    You could stop before this step but then some teams would have several home or away matches in a row.

    Does that make sense?

    I’m afraid I don’t understand the second question. rounds.length is the total size of the zeroth index of rounds.

  3. Charles says:

    Can somebody help me write a code that can fix soccer matches randomly.

  4. Ragz says:

    Is there a way to generate it with team names instead of having to change the team numbers to team names afterwards?

    For instance, English Prem League football team names.

  5. Hi Ragz,

    Not at the moment. You can use Find and Replace in your text editor or word processor to replace all 1s with Arsenal and all 2s with Aston Villa, etc. which should be nearly as easy as entering the team names first. Hope that helps.

  6. Ragz says:

    Yep, that’s pretty much how i did it.
    Thanks for responding though. Appreciated mate.
    If i can get the php written right, then i’ll send you some more source code if you like, as i’m working on an entire league system to generate a league table that will keep things updated with goals for, against, w/d/l, points, etc. All using php and mysql.

    Only part i’ve been having issues with is fixture generation, but the source you have here is helpful and if it’s ok with you, i’d like to try and work it into my whole thing and hopefully get it to use team names from the database.
    As if it uses those numbers it generates and references say a ‘TEAMID’ field in a database table, it could then echo the team names instead of numbers for each fixture.

    But i wanted to ask if it’s ok to use it before i did so.

  7. By all means Ragz. Please feel free to use the Java or the PHP for any purpose.

  8. Ragz says:

    Do you have the php source available anywhere? As i could only find the above Java source.

  9. Ragz says:

    nm, disregard that, i found it on the other page ;)

  10. Just in case anyone else wants to know, it’s linked to from this page:

    http://bluebones.net/2005/05/league-fixtures-generator/

  11. Ragz says:

    Tom,

    i’ve been working on the php source to try and get it to do a str_replace() on the numbers and change them to teams. However, my knowledge of php isn’t as good as it could be and i’ve been trying to figure out where exactly i’d need to place the str_replace() to get it to function (if it will even work).
    Any thoughts on this one?

    Or the other option i was thinking of using would be to output the fixtures to a file and then have a second php function called to open that file and run a str_replace() on that file which would then either rewrite the file or preferable write the new results to a table in mysql.
    Again though, i’m hitting the proverbial brick wall. I can’t figure out exactly what i’d need to write into the file with fwrite() ;)

    Hopefully i’ve not overstayed my welcome by asking such questions, and if you don’t have time to assist, it’s all good, as i’m sure you’re probably busy.

    Thanks

  12. Ragz says:

    Well, so far so good.
    It’s now generating names via an array.
    Only it’s causing a little problem on every other round. Round 2 is missing the first two teams.
    Here’s what i’ve got so far:

    http://footy.darknessrising.net/fixtures_test.php

    and the source:
    http://footy.darknessrising.net/fixtures_test.txt

  13. Ragz says:

    This is what the output shows for 4 teams…

    Round 1
    Arsenal v Bolton Wanderers
    Aston Villa v Blackburn Rovers

    Round 2
    v
    Arsenal v Aston Villa

    Round 3
    Aston Villa v Bolton Wanderers
    Blackburn Rovers v Arsenal

    See in round 2 it’s got the invisible teams? hehe.
    If you can spot what’s up, i’d be most appreciative.
    As i’m stumped. It’s something to do with the array, but i can’t seem to stop it.

  14. Ragz says:

    Tom, just to let you know, i figured it all out. Got it to write to a mysql db aswell.

    Once i’ve got my league sorted out, i’ll add in some extra code to the php fixtures generator to allow a user to input their team names aswell, in a second step of the input process.
    So it will then record those names into an array and output the entire set of rounds using team names instead of numbers.
    Once i’ve done it, i’ll put the source up for you so you can grab a copy of it and host it here.

  15. Hi Ragz,

    I’m glad you got where you wanted with it.

  16. I’ve updated the fixtures generator to optionally allow you to enter team names instead of the number of teams.

  17. Tim says:

    Hey Thomas, i’m doing my dissertion on a squash league fixture generator, and i was looking how you made your code. When i copy your code into JCreator and save it as the class name ‘Fixtures2′, it doesn’t work, it just comes up with the following, and i’m not sure why, any chance you could tell me why. Thanks Tim

    javac: invalid flag: D:\\Tim\\Squash League\\Website\\Fixtures2
    Usage: javac
    where possible options include:
      -g                        Generate all debugging info
      -g:none                   Generate no debugging info
      -g:{lines,vars,source}    Generate only some debugging info
      -nowarn                   Generate no warnings
      -verbose                  Output messages about what the compiler is doing
      -deprecation              Output source locations where deprecated APIs are used
      -classpath          Specify where to find user class files
      -sourcepath         Specify where to find input source files
      -bootclasspath      Override location of bootstrap class files
      -extdirs            Override location of installed extensions
      -d             Specify where to place generated class files
      -encoding       Specify character encoding used by source files
      -source          Provide source compatibility with specified release
      -target          Generate class files for specific VM version
      -help                     Print a synopsis of standard options
    
  18. Hi Tim,

    I think you’re having a problem with configuration rather than with the code. If I copy this code into a text file and call it Fixtures2.java I can issue the following at a command prompt:

    $ javac Fixtures2.java
    $ java Fixtures2 4
    

    The first command compiles it and the second gives me a fixture list for four teams.

    I would try getting that working before you worry about using it in an IDE or as part of a package, etc.

    Hope that helps. Let me know if not.

  19. Tim says:

    Hey Thomas, i figured out what was going wrong, thanks for your help.

  20. Davy says:

    I must say I’m flattered. This whole thing works like majic. I was given a task to come up with a system to generate fixtures given the participating teams. I spent an entire night pondering over ths issue and ideas were all over and gat me pretty confused. I then decided to check if someone has done this and published for all to see and probably use. Just one search criteria gave me this solution. I must say that the net is as good as a life saver. I think I have all I need to get on with my life. Thanks to you!

  21. m lang says:

    hiya,

    could you please help me ,i am the new fixture sec for our snooker league and this year we have five clubs each with 2 team total 10 teams who need to play each other 3 times,i have tried to put a fixture list together but i find it impossible. the teams have to play each other home and away but if team 1 is at home then team 2 must be away.
    Could you please e-mail me if you can help or need any further inf
    Thanks Martin

  22. joe says:

    if have a 12 team league teams must play each other 3 times can any one help cheers joe

  23. brumalia says:

    Thanks!

  24. Mike says:

    I love this application but I am a non-programmer and I was wondering if there is a simple way to adapt the code to allow each team to play each other only once rather than Home and Away?

  25. Mike, you can get a play-only-once fixture list by just using the first half of the season generated by my fixtures generator. Hope that helps!

  26. Geoff Willetts says:

    I have 14 teams in my Domino league, 4 teams 2A & 2B from 2 different clubs.
    Have you a fixture matrix for 14 teams which will ensure that Teams 1 A & B
    and Teams 2 A & B will always be opposite to each other. At the same time ensuring that all the other 10 teams only have a maximum of 2 or 3 consecutive Home or Away fixtures.

  27. I know a little basic programmming in VB3/VB5. Has anybody converted it to basic as I don’t have the skills to convert Java.

    Cheers

  28. bakert says:

    @Geoff – You might get more joy posting your question here – http://bluebones.net/2005/05/league-fixtures-generator/ – where the FIXTUREMAN lurks …

    @Peter – There is no basic version but there is a version in PHP – http://bluebones.net/fixtures.txt – any good?

Leave a Reply