In order to interpret a sporting tournament under the
engine, one has to write a tournament definition in the predefined
format in the Scheme programming language.
The following three pieces of definition must be provided:
To make a tournament definition suitable for the
engine, one has to write a file called `<tour-name>.scm' and put
it in a directory where
libtour will find it (for the
`tourcli' CLI client, see section Quick start). The file has to
define a Guile module,
tour-defs <tour-name> and export the
TITLEkey is required
The definitions are usually split into several files. For instance, here is a partial content of `fifawc2002.scm':
(define-module (fifawc2002)) (use-modules ((fifawc2002_rules)) ((fifawc2002_teams) :renamer (symbol-prefix-proc 'fifawc2002:)) ((fifawc2002_schedule) :renamer (symbol-prefix-proc 'fifawc2002:))) ;; definitions of INFO, STAGES, WINNERS omitted (export fifawc2002:INFO fifawc2002:STAGES fifawc2002:WINNERS) (re-export fifawc2002:TEAMS fifawc2002:TEAM-FORMAT fifawc2002:SCHEDULE fifawc2002:SCHEDULE-FORMAT fifawc2002:SCHEDULE-DATE fifawc2002:SCHEDULE-HOME)
The following sections describe contents of the exported variables.
An associative list pointed to by the
variable binds global team IDs to the team descriptions.
<tour-name>:TEAMS : '(("<TEAM-GLOBAL-ID-1" <team-description-list>) ...)
<team-description-list> is a list of strings as defined by the
<tour-name>:TEAM-FORMAT variable. Only
NAME of teams
is required to be specified in
name will be returned as the team identifier in
For instance, team definitions for the 2003 Ice Hockey WC included in
libtour distribution, contains the following (trimmed for
(define ihwc2003:TEAMS '(("SVK" "Slovakia") ; "SVK" is a global team ID ("RUS" "Russia") ; "Russia" is a team name ; according to the TEAM-FORMAT ; definition below ("SWE" "Sweden") ...)) (define ihwc2003:TEAM-FORMAT '(NAME))
<tour-name>:STAGES variable exported by the tournament module
contains a Scheme list where each list member describes one stage.
<tour-name>:STAGES : (<stage-definition> ...) <stage-definition>: ((ID . <string for the stage ID>) (NAME . <string for the stage name>) (STANDINGS-FIELDS . <standings-fields list>) (GAMERES-FIELDS . <gameres-fields list>) (RES-F . <game-result-interpretation-procedure>) (TEAMS . <teams-definition>) (GROUPS . <groups-definition>) (SUMMARY . <summary-definition>) (FILTERS . <filters-definition>)) (MAX-POINTS . <max-points-definition>))
ID string can be anything, by convention it is "S1" for
the first stage, "S2" for the second etc. The
usually denotes what the stage is called, "Preliminary", or
MAX-POINTS defines maximum number of points a team can get in a
game. If such information can be provided for this stage, the value
must be an integer greater than zero. If, on the other hand, maximum
points can't be defined, a false value
#f shoud be used.
The rest of the keys are described in the following subsections.
STANDINGS-FIELDS defines a list of column (or field) names for a
team in a table of standings, like this:
'(GAMES WINS DRAWS LOSSES GOALS-FOR GOALS-AGAINST POINTS)
All the fields will contain integers. The following fields are
required to be present:
GAMERES-FIELDS denotes the fields for a game result. It consists
of a pair of lists, the names of the fields in the first and types of
the fields in the second. For instance, if a game results can be
described by three items, goals scored by the first team, goals scored
by the second team, and whether the game ended in overtime, the game
fields may be defined like following:
'((GF GA OT) int int bool)
bool are the only two supported types.
A Scheme procedure placed under the
RES-F key will be used by
libtour for interpreting a game result. It expects an
associative list as the sole argument, whose keys are the same as
GAMERES-FIELDS. For instance, for the
above and the game in which the first team lost 2 to 3 in regulation
time (OT is false), the argument will be
'((GF . 2) (GA . 3) (OT . 0))
RES-F procedure should return a pair of associative lists
that describe change of
STANDINGS-FIELDS for each of the
teams. Continuing our example, if a team is awarded two points for a
win, and zero for a loss, the procedure can return the following:
'( ;;; first team list ((GAMES . 1) ; increment game count by 1 (LOSSES . 1) ; increment loss count by 1 (GOALS-FOR . 2) ; first team scored 2 goals (GOALS-AGAINST . 3)) ; first team allowed 3 goals (GAMES . 1) ;;; second team list (WINS . 1) ; increment win count by 1 (GOALS-FOR . 3) (GOALS-AGAINST . 2) (POINTS . 2)) ; second team earned 2 points
The return lists may contain an association pair for any of the fields
found in the
STANDINGS-FIELDS list even if their values haven't
changed (such as
(POINTS . 0) for the first team).
Note that values of the
POINTS entry cannot exceed the value
MAX-POINTS for current stage (see section Stages definition).
mk-res-lists helper procedure defined in the
common) module (see section common module) is useful when creating a
TEAMS definition is an associative list with team IDs
local to stage (see section Structure of a tournament) as keys and
procedures of no argument (thunks) that return global team IDs when
'(("TEAM-LOCAL-ID-1" . <thunk>) ...)
Team local IDs can be any strings, but it is convenient to give them
somewhat meaningful names. For the first stage of a tournament teams
are known in advance, therefore the
TEAMS list might look like
`(("TEAM-LOCAL-ID-1" . ,(lambda () "TEAM-GLOBAL-ID-1")) ...)
For the following stages the thunk will be called after the previous stage is compete. Here is an example of specifying the team that took the first place in group "A" in the previous stage:
`("PREV-STAGE-A-1" . ,(lambda () <code to determine the real team ID>))
The thunk has to throw a Guile error if it cannot determine the global team ID.
GROUPS key in the stage definition list corresponds to an
associative list of group definitions.
<group-definitions>: (<group-definition> ...) <group-definition>: ((ID . <string for the group ID>) (NAME . <string for the group name>) (DESCRIPTION . <string for the group description>) ;; optional (G-TEAMS . <stage-local team-IDs list>) (FORMULA . <playing formula specification>) (G-CMP-F . <teams-comparison-procedure>) (G-GAME-HERE-F . <game-belongs-to-this-group-procedure-or-spec>))
Like for a stage, the
ID string can be anything unique, and
NAME string usually describes what a group is, like "Group
A", or "Semifinal Pair 1". The
DESCRIPTION string is
optional and can contain some additional information about the group;
it is filled in by
libtour for filtered groups (see section Filtered groups).
G-TEAMS is a list of team IDs (local to the stage). Team
IDs for a group should be subset of the the keys in stage's
TEAMS definition (see section Stage teams definition). A team may
belong to more than one group within a stage.
Group playing formula helps determine how many games should be played between the teams within a group and when the group becomes complete (see section Game results and formula). The following values are allowed for a formula definition:
The procedure defined under the
G-CMP-F key in the group
definition will be used by
libtour for sorting teams within
The procedure must accept five arguments: (1) tournament name, (2) stage ID, (3) group ID, and (4,5) team result lists of the two teams to be compared. The first three arguments are obvious. Each of the last two contains an associative list of team results (see section Standings and Game result fields definitions) plus a team ID (local to stage) association pair, for example:
'((GAMES . 10) ;; these are STANDINGS-FIELDS (WINS . 7) (DRAWS . 1) (LOSSES . 2) (GOALS-FOR . 22) (GOALS-AGAINST . 7) (POINTS . 15) (ID . "<TEAM-LOCAL-ID>")) ;; additional ID entry
The procedure must return
1 if the first team results are
higher than the second's,
-1 if opposite, and
0 if the
teams appear to be equal.
An example of the sorting procedure below uses helper procedures from
(libtour common) (see section common module).
(define cmp-f (lambda (tour-name stage-id group-id t1 t2) (or ;; compare points (cmp-assoc-field-p 'POINTS t1 t2) ;; if points are equal, compare goal difference (cmp-assoc-field-diff-p 'GOALS-FOR 'GOALS-AGAINST t1 t2) ;; if goal differences are equal, see which team scored more (cmp-assoc-field-p 'GOALS-FOR t1 t2) ;; if equal, compare personal games for these two teams (cmp-two-teams-p c-tour-name stage-id (assoc-ref t1 'ID) (assoc-ref t2 'ID) ;; another cmp procedure cmp-prelim-stage-personal-f ;; consider only games between these two teams 'BOTH) 0))) ;; give up, the teams are equal
To determine if a game belongs to a given group, another Scheme
procedure should be supplied. For the two most common cases, however,
libtour provides shortcuts so that a predefined Scheme symbol
can be given instead of a procedure.
(lambda (game-alist) ...)
(#f . #f)if none of the two teams' result should be recorded in this group (and therefore the game does not belong to this group), or one of
(#t . #f),
(#f . #t),
(#t . #t)if only the first, or only the second, or both teams' results correspondingly should be recorded in this group.
If a procedure is supplied, it should expect a game associative list
and be in the format defined by the
(see section Game schedule definition), for instance:
'((ID . 123) (DATE . "23.06.2003 15:00") (TEAM1 . "<TEAM-LOCAL-ID-1>") (TEAM2 . "<TEAM-LOCAL-ID-2>"))
As mentioned, the procedure should return a pair of boolean values.
SUMMARY entry controls creation of a summary group for a
stage (see section Summary group). If its value is
#f, no summary
group will be created. If it contains a procedure, a summary group
will be created for the stage, and this procedure will be used for
team comparison (like see section Teams comparison procedure) within this
FILTERS entry in a stage definition defines what team and/or
game filters are aplicable to this stage (see section Filtered groups). It
contains an associative list with the following optional keys:
GAME-FILTERS; the values are lists of
((TEAM-FILTERS <team-filter-making-procedure> ...) (GAME-FILTERS <game-filter-making-procedure> ...))
If no filters can be applied, the list is empty.
Winners (or losers) are the teams that finished the tournament with some distinguishable result: won gold, or lost everything. Winners definition is very similar to the one for teams within a stage (see section Stage teams definition). The differences are:
#frather than throw error.
Here is an example of a Winners list:
(define <tour-name>:WINNERS '(("Gold" . <thunk>) ("Silver" . <thunk>) ("Bronze" . <thunk>)))
<tour-name>:SCHEDULE variable contains a list in the form:
'(<stage-list> ...) stage-list: ("stage-id" <entry> ...) entry: <game-definition> or <thunk>
<game-definition> is a list of string members defined in
<thunk> is a procedure of
no arguments that returns a list of
<thunk> list elements (if any) are run at the time the stage
changes its state from "uninitialized" to "ready".
<game-definition> may look like this:
'(("1" "31.05.02 20:30" "<place>" "<stage-local team ID 1>" "<stage-local team ID 2>"))
To allow loading stages with unknown schedule
are optional. Note, however, that a stage with no schedule can never
tour-name:SCHEDULE-FORMAT variable defines the meaning of the
list members. For the preceding example it would be:
'(ID DATE TIME PLACE TEAM1 TEAM2)
TEAM2 fields are mandatory, any other -- optional. Games are
not required to be sorted as the sorting is done internally by
Interestingly, you can also supply a game result along with the game's
schedule entry. If the game list contains more items than there is in
SCHEDULE-FORMAT list, the rest is assumed to contain the game
result in the format according to
GAMERES-FIELDS. If the game
result specified in the schedule, the game will be read-only. This
obscure feature allows to implement carry-forward games but can also
be used for pre-setting game results in the schedule.
tour-name:SCHEDULE-DATE variable should be provided. It is a
string that describes the format of the
DATE field in game
definitions. The format description style used is identical to the one
strptime(3) C function. For instance, a date
"2001-11-12 18:30" would be have format
Please see the corresponding man page for details.
tour-name:SCHEDULE-HOME variable notifies the position of the
home team in the game definitions. The following values
integer type) are permitted:
TEAM1field is the home team
TEAM2field is the home team
Go to the first, previous, next, last section, table of contents.