The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Games::Tournament::Swiss - FIDE Swiss Same-Rank Contestant Pairing

VERSION

Version 0.09

SYNOPSIS

    @Games::Tournament::Swiss::roles = qw/Black White/;
    $tourney = Games::Tournament::Swiss->new($rounds, \@entrants);
    @rankedPlayers = $tourney->assignPairingNumbers;
    $tourney->initializePreferences;


    ...

    $tourney->collectCards(@games);
    @groups = $tourney->formBrackets($round);
    $round5 = $tourney->pairing( \@groups );
    $matches = $round5->matchPlayers;
    $round5->allocateColors;

DESCRIPTION

In a Swiss tournament, there is a pre-declared number of rounds, each contestant meets every other contestant zero or one times, and in each round contestants are paired with other players with the same, or similar, scores.

METHODS

assignPairingNumbers

 @rankings = $tourney->assignPairingNumbers;

Sets the participants pairing numbers, sorting on rating, title and name, and substitutes this for the id they had before (The old id is saved as oldId.) If a pairingNumber attribute already exists for all @players, however, this is used instead, and the old id isn't saved. This function uses Games::Tournament::rank. Before the first round, all scores are usually 0. But if they *do* have scores, they are not used to rank. A2

initializePreferences

 @rankings = $tourney->initializePreferences;

Before the first round, the color (role) preference of the highest ranked player and the other odd-numbered players in the top half of the rankings is determined by lot. The preference of the even-numbered players in the top half is given to the other color. E5

collectCards

 $play = $tourney->collectCards( @games );
  next if $htable->{$player1->id}->{$player2->id};

Records @games after they have been played. Stored as $tourney's play field, keyed on round and ids of players. Returns the new play field. Updates player scores, preferences. TODO This has non-Swiss subclass elements I could factor out into a method in Games::Tournament. TODO What if player is matched more than one time in the round, filling in for someone? XXX It looks like all the games have to be the same round, or you have to collect all cards in one round before collecting cards in following rounds. XXX I'm having problems with recording roles. I want to be lazy about it, and trust the card I get back before the next round. The problem with this is, I may be getting the role from the wrong place. It should come from the card, and is a role which was assigned in the previous round, and is only now being recorded, at this point between the previous round and the next round. Or is the problem copying by value rather than reference of the entrants? Now I also need to record floats. It would be good to do this at the same time as I record roles. The card is the appropriate place to get this info according to A4.

publishCards

 $schedule = $tourney->publishCards( @games );

Announces @games before they have been played, and stores them as $tourney's play field, keyed on round and ids of players. Returns the new play field. TODO This has non-Swiss subclass elements I could factor out into a method in Games::Tournament.

myCard

 $game = $tourney->myCard(round => 4, player => $alekhine);

Finds match from $tourney's play accessor, which is keyed on round and ids of players.

formBrackets

 @groups = $tourney->formBrackets

Returns for the next round an array of Games::Tournament::Swiss::Bracket objects grouping contestants with the same score, ordered by score. Late entrants without a score cause the program to die. Some groups may have odd numbers of players, etc, and players will have to be floated to other score groups. TODO Should this have a round parameter, requiring score info up to that round?

pairing

 $pairing = $tourney->pairing( \@groups );

Returns a Games::Tournament::Swiss::Procedure object. Groups are Games::Tournament::Swiss::Brackets objects of contestants with the same score and they are ordered by score, the group with the highest score first, and the group with the lowest score last. This is the point where round i becomes round i+1.

compatible

        $games = $tourney->compatible
        next if $games->{$alekhine->pairingNumber}->{$capablanca->pairingNumber}

Returns an anonymous hash, keyed on the pairing numbers (ids) of @grandmasters, indicating whether or not the individual @grandmasters could play each other in the next round. But what is the next round? This method uses the whoPlayedWho and colorClashes methods to remove incompatible players.

whoPlayedWho

        $games = $tourney->whoPlayedWho
        next if $games->{$alekhine->pairingNumber}->
            {$capablanca->pairingNumber}

Returns an anonymous hash, keyed on the pairing numbers (ids) of the tourney's entrants, of the round in which individual entrants met. Don't forget to collect scorecards in the appropriate games first! (No tracking of how many times players have met if they have met more than once!) Do you know what round it is? B1

colorClashes

        $nomatch = $tourney->colorClashes
        next if $nomatch->{$alekhine->id}->{$capablanca->id}

Returns an anonymous hash, keyed on the ids/pairing numbers of the tourney's entrants, of a color (role) if 2 of the individual @grandmasters both have an absolute preference for it in the next round and so can't play each other (themselves). Don't forget to collect scorecards in the appropriate games first! B2

byesGone

        next if $tourney->byesGone($grandmasters)

Returns an anonymous hash of either the round in which the tourney's entrants had a 'Bye' or the empty string, keyed on @$grandmasters' ids. If a grandmaster had more than one bye, the last one is returned. Don't forget to collect scorecards in the appropriate games first! B1

incompatibles

        $nomatch = $tourney->incompatibles(@grandmasters)
        next if $nomatch->{$alekhine->id}->{$capablanca->id}

Collates information from the whoPlayedWho and colorClashes methods to show who cannot be matched or given a bye in the next round, returning an anonymous hash keyed on the ids/pairing numbers of @grandmasters. B1,2 C1,6

medianScore

 $group = $tourney->medianScore($round)

Returns the score equal to half the number of rounds that have been played. Half the contestants will have scores above or equal to this score and half will have ones equal to or below it, assuming everyone has played every round. What IS the number of rounds played, again?

rounds

        $tourney->rounds

Gets/sets the total number of rounds to be played in the competition

size

$size = 'Maxi' if $tourney->size > 2**$tourney->rounds

Gets the number of entrants

AUTHOR

Dr Bean, <drbean, followed by the at mark (@), cpan, then a dot, and finally, org>

BUGS

Please report any bugs or feature requests to bug-games-tournament-swiss at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Games-Tournament-Swiss. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Games::Tournament::Swiss

You can also look for information at:

ACKNOWLEDGEMENTS

See http://www.fide.com/official/handbook.asp?level=C04 for the FIDE's Swiss rules.

COPYRIGHT & LICENSE

Copyright 2006 Dr Bean, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.