MatchTimes.perl
MatchTimes.perl
—
Plain Text,
15 kB (16043 bytes)
File contents
#!/usr/bin/perl
# This script takes the user data input and generates two plots. The first plot shows
# the times for each match and the judging. The second plot shows which teams play
# which and is used to make sure that no team plays too often or little.
# The text output has the team pairings, schedule, and a list of which teams are
# played by each team. The script also creates a tab delimited file with the competition
# and judging schedule that can be read directly into the scoring spread sheet. The team
# names are then pulled into the schedule and it is ready for formatting, printing, and then
# handing out to the teams. The file name is MatchAndJudgeTimes.tab.
#
# We started with pairings developed by Tim Burks and then worked with them until
# we had judging times that were not too close to competition matches and so that
# they do not compete in subsequent matches.
#
# Use this script by simply running it on a unix machine or cygwin Windows machine
# and ploting the resulting MatchTimes.gnu file with gnuplot. Gnuplot sends two
# plots to the default x11 screen. It also generates MatchTimes.ps and MatchPairings.ps.
# These can be converted with Acrobat to pdf's. This conversion can also be done
# under cygwin with the "convert" command with
# convert MatchTimes.ps MatchTimes.pdf
# convert MatchPairings.ps MatchPairings.pdf
#
# The times for the Judging and team matches are not connected. They must work
# in concert with eachother at the event. The only way I have figured out how
# to do this is to make a set of plots and then figure out where things should go
# and then update the lists below by hand.
#
# The script works for any number of matchs, teams, and rounds.
#
#
# Michael and Wyn Schuh
# Los Altos, CA
# Michael@Boardsailor.com
#
# Version Date Who Comments
# 1.5 05 Nov 05 Schuhs First working version.
# 1.6 05 Nov 05 Schuhs Reworked the pairings to give teams more time and
# added MatchAndJudgeTimes.tab file.
# 1.7 06 Nov 05 Schuhs (Austin and Michael) Made number of teams dynamic, automaticly find
# the number of matches per round, checks for errors in number of judgings
# and repeated pairings. Fixed pairings so 6 is on table 1 in first match
# of round d.
#
# Start of user data input.
#
$StartTime = 75; # Start time in minutes. 60 is 1:00 PM.
# Round a b c d e
@Cycle = ( 7, 7, 7, 6, 5 ); # Time between matches in each round
@Break = ( 20, 0, 10, 0, 20 ); # Break time before each round
$JudgingTimeSlotLength = 10; # This is the amount of time given to each judging session.
$FirstBreak = $Break[0] + 5; # Used to have the judging start five minutes after the first competition match starts.
# Break J1 J2 P
@Judgings = ( [ $FirstBreak, 3, 2, 10 ], # First Set
[ 0, 1, 3, 8 ],
[ 0, 2, 1, 11 ],
[ 0, 4, 5, 3 ], # Second Set
[ 0, 6, 4, 7 ],
[ 0, 5, 6, 9 ],
[ 10, 7, 8, 12 ], # Third Set
[ 0, 9, 7, 6 ],
[ 0, 8, 9, 5 ],
[ 0, 10, 11, 2 ], # Fourth Set
[ 0, 12, 10, 4 ],
[ 0, 11, 12, 1 ] );
@Matchings = (
[ # Round a
[ 4, 8 ],
[ 11, 7 ],
[ 5, 9 ],
[ 6, 10 ],
], [ # Round b
[ 12, 7 ],
[ 8, 9 ],
[ 10, 11 ],
[ 2, 12 ],
[ 3, 1 ],
], [ # Round c
[ 1, 5 ],
[ 4, 11 ],
[ 10, 2 ],
[ 12, 3 ],
], [ # Round d
[ 6, 4 ],
[ 7, 1 ],
[ 9, 3 ],
[ 8, 5 ],
[ 2, 6 ],
], [ # Round e
[ 1, 2 ],
[ 3, 4 ],
[ 5, 6 ],
[ 7, 8 ],
[ 9, 10 ],
[ 11, 12 ],
]
);
$NumberOfTeams = 0; # Number of the highest team. This is assumed to be the number of teams.
foreach $i ( 0 .. $#Matchings ) {
push @Matches, $#{$Matchings[$i]} + 1; # Number of matches in each round.
foreach $match ( 0 .. $#{$Matchings[$i]} ) {
$NumberOfTeams = $Matchings[$i][$match][0] if $Matchings[$i][$match][0] > $NumberOfTeams;
$NumberOfTeams = $Matchings[$i][$match][1] if $Matchings[$i][$match][1] > $NumberOfTeams;
}
}
if ( $NumberOfTeams != $#Judgings+1 ) { # Check to make sure we have the right number of Judgings.
printf "\nERROR: The number of teams, $NumberOfTeams, does not equal the number of Judgings, %d\n\n",$#Judgings+1;
exit(-5);
}
#
# End of user data input.
#
# t1 t2 # t1 and t2 are filled with the number of times at each table.
for ( 0 .. $NumberOfTeams ) {
push @TableCountForEachTeam , [0, 0]; # Used to count the number of times a team plays at table 1 and table 2.
}
foreach $i ( 0 .. $NumberOfTeams ) {
foreach $j ( 0 .. $NumberOfTeams ) {
$PairingsTable[$i][$j] = 0; # 2D Used to keep track of the number of times a team plays each other team.
}
}
$time = $StartTime;
GP_CommandFile_HeaderFill(); # Write the first part of the plot command file.
push @JudgeTimesAndTeamsTabs, "Competition Round Schedule\n"; # Build the contents for the MatchAndJudgeTimes.tab file.
push @JudgeTimesAndTeamsTabs, "Round\tMatch\tTime\tTable 1\tTable 2\n";
@RoundNames = (qw(A B C D E)); # Used to label matches with letters.
# Make the plot command lines and data files for showing when each team competes and for the pairings chart.
foreach $RoundNumber ( 0 .. $#Matches ) {
open(GP,">MatchTimes$RoundNumber.data");
open(GPP,">MatchPairings$RoundNumber.data");
$RoundMatches = $Matches[$RoundNumber];
$time += $Break[$RoundNumber];
foreach $Match ( 1 .. $RoundMatches ) {
$timeEnd = $time + $Cycle[$RoundNumber];
$GPtimeStart = sprintf "%d:%2.2d",int($time/60), $time%60; # Set the match start and end times.
$GPtimeEnd = int($timeEnd/60) . ":" . $timeEnd%60;
$GPtimeCent = int(($time+$timeEnd)/120) . ":" . (($time+$timeEnd)/2)%60;
$Table1team = $Matchings[$RoundNumber][$Match-1][0]; # Get the team names.
$Table2team = $Matchings[$RoundNumber][$Match-1][1];
$TableCountForEachTeam[$Table1team][0] += 1; # Keep track of how many times the
$TableCountForEachTeam[$Table2team][1] += 1; # teams play at each table.
push @MatchTimesAndTeams, sprintf " $RoundNames[$RoundNumber] %6d $GPtimeStart %6d %6d\n",$Match,$Table1team,$Table2team;
push @JudgeTimesAndTeamsTabs, sprintf "$RoundNames[$RoundNumber]\t%d\t$GPtimeStart\t=Team%d\t=Team%d\n",$Match,$Table1team,$Table2team;
push @{ $TableCountForEachTeam[$Table1team] }, $Table2team; # Add the competing team to the list.
push @{ $TableCountForEachTeam[$Table2team] }, $Table1team; # Add the competing team to the list.
printf GP "$GPtimeStart %5.1f\n", $Table1team - .4; # Box for competition schedule.
printf GP "$GPtimeEnd %5.1f\n", $Table1team - .4;
printf GP "$GPtimeEnd %5.1f\n", $Table1team + .4;
printf GP "$GPtimeStart %5.1f\n", $Table1team + .4;
printf GP "$GPtimeStart %5.1f\n\n",$Table1team - .4;
printf GP "$GPtimeStart %5.1f\n", $Table2team - .4;
printf GP "$GPtimeEnd %5.1f\n", $Table2team - .4;
printf GP "$GPtimeEnd %5.1f\n", $Table2team + .4;
printf GP "$GPtimeStart %5.1f\n", $Table2team + .4;
printf GP "$GPtimeStart %5.1f\n\n",$Table2team - .4;
printf GPC "set label \"t1\" at \"$GPtimeCent\", $Table1team center tc lt %d\n",$RoundNumber+1;
printf GPC "set label \"t2\" at \"$GPtimeCent\", $Table2team center tc lt %d\n",$RoundNumber+1;
printf GPP "%5.1f %5.1f\n", $Table1team-.5, $Table2team-.5; # Box for pairings chart
printf GPP "%5.1f %5.1f\n", $Table1team-.5, $Table2team+.5;
printf GPP "%5.1f %5.1f\n", $Table1team+.5, $Table2team+.5;
printf GPP "%5.1f %5.1f\n", $Table1team+.5, $Table2team-.5;
printf GPP "%5.1f %5.1f\n\n", $Table1team-.5, $Table2team-.5;
printf GPP "%5.1f %5.1f\n", $Table2team-.5, $Table1team-.5; # Box for pairings chart
printf GPP "%5.1f %5.1f\n", $Table2team-.5, $Table1team+.5;
printf GPP "%5.1f %5.1f\n", $Table2team+.5, $Table1team+.5;
printf GPP "%5.1f %5.1f\n", $Table2team+.5, $Table1team-.5;
printf GPP "%5.1f %5.1f\n\n", $Table2team-.5, $Table1team-.5;
$PairingsTable[$Table1team][$Table2team] += 1; # Increment the number of times each team is paired with the other.
$PairingsTable[$Table2team][$Table1team] += 1;
$ErrorString = ($PairingsTable[$Table1team][$Table2team] > 1) ? " Error" : ""; # Check to see if they have more than 1 pairing.
$TextColor = ($PairingsTable[$Table1team][$Table2team] > 1) ? 0 : $RoundNumber+1; # Use black text if they have more than 1 pairing.
push @GPC, sprintf "set label \"$RoundNames[$RoundNumber]%d$ErrorString\" at $Table1team, $Table2team center tc lt %d\n",$Match,$TextColor;
push @GPC, sprintf "set label \"$RoundNames[$RoundNumber]%d$ErrorString\" at $Table2team, $Table1team center tc lt %d\n",$Match,$TextColor;
$time = $timeEnd
}
close(GP);
close(GPP);
}
push @JudgeTimesAndTeamsTabs, " \n", " \n", "\tJudging Schedule\n";
push @JudgeTimesAndTeamsTabs, "\tSession\tTime\tRobot Design Go to Judging Room\tTeam Categories Go to Judging Room\tProgramming Go to your Pit Table\n";
$time = $StartTime;
open(GP,">MatchJudgeTimes.data");
foreach $JudgingRoundNumber ( 0 .. $#Judgings ) {
$time += $Judgings[$JudgingRoundNumber][0]; # Add in the time for the break
$timeEnd = $time + $JudgingTimeSlotLength;
$GPtimeStart = sprintf "%d:%2.2d",int($time/60), $time%60; # Set the Judging start and end times.
$GPtimeEnd = int($timeEnd/60) . ":" . $timeEnd%60;
$GPtimeCent = int(($time+$timeEnd)/120) . ":" . (($time+$timeEnd)/2)%60;
$Judge1team = $Judgings[$JudgingRoundNumber][1];
$Judge2team = $Judgings[$JudgingRoundNumber][2];
$Judge3team = $Judgings[$JudgingRoundNumber][3];
push @JudgeTimesAndTeams, sprintf "%4d $GPtimeStart %8d %10d %10d\n",$JudgingRoundNumber+1,$Judge1team,$Judge2team,$Judge3team;
push @JudgeTimesAndTeamsTabs, sprintf "\t%d\t$GPtimeStart\t=Team%d\t=Team%d\t=Team%d\n",$JudgingRoundNumber+1,$Judge1team,$Judge2team,$Judge3team;
printf GP "$GPtimeStart %5.1f\n", $Judge1team - .4;
printf GP "$GPtimeEnd %5.1f\n", $Judge1team - .4;
printf GP "$GPtimeEnd %5.1f\n", $Judge1team + .4;
printf GP "$GPtimeStart %5.1f\n", $Judge1team + .4;
printf GP "$GPtimeStart %5.1f\n\n", $Judge1team - .4;
printf GP "$GPtimeStart %5.1f\n", $Judge2team - .4;
printf GP "$GPtimeEnd %5.1f\n", $Judge2team - .4;
printf GP "$GPtimeEnd %5.1f\n", $Judge2team + .4;
printf GP "$GPtimeStart %5.1f\n", $Judge2team + .4;
printf GP "$GPtimeStart %5.1f\n\n", $Judge2team - .4;
printf GP "$GPtimeStart %5.1f\n", $Judge3team - .4;
printf GP "$GPtimeEnd %5.1f\n", $Judge3team - .4;
printf GP "$GPtimeEnd %5.1f\n", $Judge3team + .4;
printf GP "$GPtimeStart %5.1f\n", $Judge3team + .4;
printf GP "$GPtimeStart %5.1f\n\n", $Judge3team - .4;
printf GPC "set label \"j1\" at \"$GPtimeCent\", $Judge1team center tc lt 6\n";
printf GPC "set label \"j2\" at \"$GPtimeCent\", $Judge2team center tc lt 6\n";
printf GPC "set label \"P\" at \"$GPtimeCent\", $Judge3team center tc lt 6\n";
$time = $timeEnd
}
close (GP);
GP_CommandFile_TrailerFill();
print "Check the list below to make sure that each team competes on each table half the time.\n";
print "The Table_1 and Table_2 columns contain the number of time they compete on the two tables.\n\n";
print " Team# Table_1 Table_2 | Teams Competing against this team.\n";
for $i ( 1 .. $NumberOfTeams ) {
#printf "%5d %8d %7d %5d\n",$i,$TableCountForEachTeam[$i][0],$TableCountForEachTeam[$i][1],$#{$TableCountForEachTeam[$i]};
#printf "%5d %8d %7d %5d\n",$i,$TableCountForEachTeam[$i][0],$TableCountForEachTeam[$i][1],$TableCountForEachTeam[$i][2];
printf "%5d %8d %7d |",$i,$TableCountForEachTeam[$i][0],$TableCountForEachTeam[$i][1];
for $j ( 2 .. $#{$TableCountForEachTeam[$i]} ) { printf "%6d",$TableCountForEachTeam[$i][$j]; } print "\n";
}
print "\n\nMatch Start times and team numbers\n";
print "Round Match StartTime Team_1 Team_2\n";
print @MatchTimesAndTeams;
print "\n\nJudging Start times and team numbers\n";
print "Round StartTime Judging_1 Judging_2 Programming\n";
print @JudgeTimesAndTeams;
# Create a tab delimited file for the match and judging schedule.
# Read this file into Microsoft Excel by using the Data/ImportExternalData/ImportData tool.
open(MSE,">MatchAndJudgeTimes.tab");
print MSE @JudgeTimesAndTeamsTabs;
close(MSE);
# Check to see if teams play each other more than once.
foreach $i ( 0 .. $NumberOfTeams ) {
foreach $j ( $i .. $NumberOfTeams ) {
print "\nError: Teams $i and $j play each other more than once.\n" if $PairingsTable[$i][$j] > 1;
}
}
# Print out the current date and time.
print "\n"; system ("date");
# End
#
#================================================================================
#================================================================================
#================================================================================
#
sub GP_CommandFile_HeaderFill {
open(GPC,">MatchTimes.gnu");
print GPC '
# Tell gnuplot that the x data is in time format
set xdata time
# Set the time format which will be used for xrange and maybe other things.
set timefmt "%H"
set style data lines
# %R = %H:%M (hours:minutes)
set format x "%R"
set xrange ["0:0":"3:00"]
set autoscale x
';
printf GPC "
set yrange [0:%d] rever
set yti 1,1,$NumberOfTeams
",$NumberOfTeams+1;
print GPC '
set timefmt "%H:%M"
unset label # Clear any labels that might have been set from a privious loading of this file.
';
}
#
#================================================================================
#================================================================================
#================================================================================
#
sub GP_CommandFile_TrailerFill {
print GPC '
set time
set tit "Match Times"
set xlab "Time"
set ylab "Team Number"
plot "MatchTimes0.data" using 1:2 notit, \
"MatchTimes1.data" using 1:2 notit, \
"MatchTimes2.data" using 1:2 notit, \
"MatchTimes3.data" using 1:2 notit, \
"MatchTimes4.data" using 1:2 notit, \
"MatchJudgeTimes.data" using 1:2 notit
pause -1
set term post color solid
set output "MatchTimes.ps"
replot
set output
unset label # Clear any labels that might have been set from a privious loading of this file.
';
print GPC "@GPC";
print GPC '
set term x11
set xdata
set format x
';
printf GPC "
set xrange [0:%d]
set xti 1,1,$NumberOfTeams
",$NumberOfTeams+1;
print GPC '
set tit "Team Pairings\nErrors are noted by \'Error\' in the pairings label."
set xlab "Team Number"
plot "MatchPairings0.data" using 1:2 notit, \
"MatchPairings1.data" using 1:2 notit, \
"MatchPairings2.data" using 1:2 notit, \
"MatchPairings3.data" using 1:2 notit, \
"MatchPairings4.data" using 1:2 notit
pause -1
set term post color solid
set output "MatchPairings.ps"
replot;
';
close(GPC);
}

