forked from science-ation/science-ation
654 lines
18 KiB
PHP
654 lines
18 KiB
PHP
<?
|
|
/*
|
|
This file is part of the 'Science Fair In A Box' project
|
|
SFIAB Website: http://www.sfiab.ca
|
|
|
|
Copyright (C) 2005 Sci-Tech Ontario Inc <info@scitechontario.org>
|
|
Copyright (C) 2005 James Grant <james@lightbox.org>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public
|
|
License as published by the Free Software Foundation, version 2.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; see the file COPYING. If not, write to
|
|
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA.
|
|
*/
|
|
?>
|
|
<?
|
|
require("../common.inc.php");
|
|
auth_required('admin');
|
|
require("judges_schedulerconfig_check.inc.php");
|
|
|
|
send_header("Judging teams automatic scheduler");
|
|
$ok=checkPrerequisites();
|
|
if(!$ok)
|
|
{
|
|
echo error(i18n("Schduler cannot run until the above problems are resolved. Use the links below each error to resolve the problem"));
|
|
send_footer();
|
|
exit;
|
|
}
|
|
|
|
function TRACE() { }
|
|
//function TRACE($str) { print($str); }
|
|
function TRACE_R()
|
|
{
|
|
}
|
|
|
|
|
|
/* Given the team data, pick a judge, then pick a new team
|
|
* for them */
|
|
function pick_random_move(&$team)
|
|
{
|
|
//TRACE_R($team);
|
|
/* Pick 2 random teams*/
|
|
$tms = count($team);
|
|
while(1) {
|
|
$t1 = rand(0, $tms - 1);
|
|
if(count($team[$t1]['judges']) > 0) break;
|
|
}
|
|
$t2 = rand(0, $tms - 2);
|
|
if($t2 >= $t1) $t2++;
|
|
|
|
/* Pick a judge on team1 */
|
|
$j1 = rand(0, count($team[$t1]['judges']) - 1);
|
|
/* Pick a judge or the empty slot on team2 */
|
|
$j2 = rand(0, count($team[$t2]['judges']));
|
|
|
|
if($j2 == count($team[$t2]['judges'])) {
|
|
$j2 = -1;
|
|
}
|
|
|
|
|
|
TRACE("Random move: ($t1,$j1) ($t2,$j2)\n");
|
|
TRACE_R($team[$t1]['judges']);
|
|
TRACE("T2:\n");
|
|
TRACE_R($team[$t2]['judges']);
|
|
TRACE("\n");
|
|
/* The move is team1,judge1 <==> team2,judge2 */
|
|
return array($t1, $j1, $t2, $j2);
|
|
}
|
|
|
|
/* The cost function is:
|
|
+ 50 * each judge below the min for each team
|
|
+ 10 * each judge above the max for each team
|
|
+ 2 * each level of preference away from the
|
|
max level for each judge
|
|
+ 40 if the team doesn't have a chair.
|
|
+ 25 for each memember on the team that can't speak the language
|
|
of the judging team
|
|
|
|
( ex: if a judge has selected LS->2, PS->0, CS->-1
|
|
then matching that judge with a:
|
|
LS = -4,
|
|
PS = 0,
|
|
CS = -2,
|
|
else = 0
|
|
)
|
|
*/
|
|
|
|
/* Compute the cost of adding a judge to a team */
|
|
|
|
function compute_team_cost(&$teams, &$judges, $team_id)
|
|
{
|
|
$cost = 0;
|
|
$have_chair = 0;
|
|
|
|
$t =& $teams[$team_id];
|
|
|
|
/* Compute the over max / under min costs */
|
|
$c = count($t['judges']);
|
|
$min = ($c < $t['min']) ? $t['min'] - $c : 0;
|
|
$max = ($c > $t['max']) ? $c - $t['max'] : 0;
|
|
$cost += $min * 50;
|
|
$cost += $max * 10;
|
|
|
|
// TRACE("Under min=$min, over max=$max\n");
|
|
|
|
/* For each judge on the team, score their preferences */
|
|
reset($t['judges']);
|
|
while( list($key, $judge_id) = each($t['judges']) ) {
|
|
$j =& $judges[$judge_id];
|
|
|
|
/* Get the division, and see where it fits with this
|
|
* judges preferences */
|
|
$dpref = $j['divprefs'][$t['division']];
|
|
$cpref = $j['catprefs'][$t['category']];
|
|
|
|
// TRACE("Judge $judge_id cp=$cpref, dp=$dpref\n");
|
|
|
|
$cost += 2 * (-$dpref + 2);
|
|
$cost += 2 * (-$cpref + 2);
|
|
|
|
/* See if the judge is willing to chair a team */
|
|
if($j['willing_chair'] == 'yes') {
|
|
$have_chair = 1;
|
|
}
|
|
|
|
/* Check the language preferences */
|
|
if(!in_array($t['language'], $j['languages'])) {
|
|
$cost += 25;
|
|
}
|
|
}
|
|
/* Huge penalty for a team without a willing chair */
|
|
if(!$have_chair) {
|
|
$cost += 40;
|
|
}
|
|
|
|
TRACE("Team $team_id, cost is $cost\n");
|
|
|
|
return $cost;
|
|
}
|
|
|
|
function compute_delta_cost(&$teams, &$judges, $move)
|
|
{
|
|
list($tid1, $jidx1, $tid2, $jidx2) = $move;
|
|
|
|
$t1 =& $teams[$tid1];
|
|
$t2 =& $teams[$tid2];
|
|
|
|
$ja1 = $t1['judges'];
|
|
$ja2 = $t2['judges'];
|
|
|
|
/* Turn the indexes into judge IDs */
|
|
$jid1 = $t1['judges'][$jidx1];
|
|
if($jidx2 == -1)
|
|
$jid2 = -1;
|
|
else
|
|
$jid2 = $t2['judges'][$jidx2];
|
|
|
|
|
|
$cost = 0;
|
|
|
|
/* Make new arrays for each judge list */
|
|
$nj1 = array();
|
|
for($x=0; $x<count($t1['judges']); $x++) {
|
|
$id = $t1['judges'][$x];
|
|
|
|
if($x == $jidx1) {
|
|
/* This is the index of the judge we're
|
|
* supposed to swap (or remove) */
|
|
if($jid2 != -1) $nj1[] = $jid2;
|
|
} else {
|
|
$nj1[] = $id;
|
|
}
|
|
}
|
|
$t1['judges'] = $nj1;
|
|
|
|
$nj2 = array();
|
|
for($x=0; $x<count($t2['judges']); $x++) {
|
|
$id = $t2['judges'][$x];
|
|
if($x == $jidx2) {
|
|
/* if jidx2 is -1 we'll never get here, else
|
|
* we might, meaning that this is where
|
|
* we want to swap in the value from the first
|
|
* array */
|
|
$nj2[] = $jid1;
|
|
} else {
|
|
$nj2[] = $id;
|
|
}
|
|
}
|
|
/* jidx2 may be -1 meaning that something was removed
|
|
* from the first array, but not added back to this one,
|
|
* do that now so we don't lose judges */
|
|
if($jidx2 == -1) $nj2[] = $jid1;
|
|
$t2['judges'] = $nj2;
|
|
|
|
/* Recompute the costs */
|
|
$cost -= $t1['cost'];
|
|
$cost -= $t2['cost'];
|
|
$c1 = compute_team_cost($teams, $judges, $tid1);
|
|
$c2 = compute_team_cost($teams, $judges, $tid2);
|
|
$cost += $c1 + $c2;
|
|
|
|
TRACE("Team $tid1 cost {$t1['cost']} -> $c1\n");
|
|
TRACE("Team $tid2 cost {$t2['cost']} -> $c2\n");
|
|
TRACE("Delta = $cost\n");
|
|
|
|
$t1['judges'] = $ja1;
|
|
$t2['judges'] = $ja2;
|
|
|
|
return array($cost, array($nj1, $c1, $nj2, $c2)) ;
|
|
}
|
|
|
|
function record_move(&$teams, $move, $movedata)
|
|
{
|
|
list($tid1, $jidx1, $tid2, $jidx2) = $move;
|
|
list($judges1, $c1, $judges2, $c2) = $movedata;
|
|
|
|
$t1 =& $teams[$tid1];
|
|
$t2 =& $teams[$tid2];
|
|
|
|
// TRACE_R($t1);
|
|
|
|
$t1['judges'] = $judges1;
|
|
$t1['cost'] = $c1;
|
|
$t2['judges'] = $judges2;
|
|
$t2['cost'] = $c2;
|
|
|
|
TRACE("T1:");
|
|
TRACE_R($t1['judges']);
|
|
TRACE("\nT2:");
|
|
TRACE_R($t2['judges']);
|
|
TRACE("\n");
|
|
|
|
// TRACE_R($t1);
|
|
// TRACE_R($t2);
|
|
|
|
}
|
|
|
|
|
|
/* Inputs to annealer:
|
|
* - data['min_per_team']
|
|
* - 'max_per_team'
|
|
* - 'teams' [division][category] = number of teams
|
|
*
|
|
* - judges
|
|
*/
|
|
function judges_assign_anneal($divisions, $categories, $languages, $judges, &$team, $data)
|
|
{
|
|
$num_teams = count($team);
|
|
$x=0;
|
|
|
|
TRACE("Input: $num_teams juding teams \n");
|
|
|
|
if($num_teams <= 0) return;
|
|
|
|
/* Inital assignment of judges to teams */
|
|
reset($judges);
|
|
while( list($j, $ji) = each($judges)) {
|
|
$team[$x % $num_teams]['judges'][] = $j;
|
|
$x++;
|
|
}
|
|
|
|
/* Compute inital costs */
|
|
$current_cost = 0;
|
|
// reset($team);
|
|
for($x=0; $x<$num_teams; $x++) {
|
|
$t =& $team[$x];
|
|
$t['cost'] = compute_team_cost($team, $judges, $x);
|
|
$current_cost += $t['cost'];
|
|
}
|
|
|
|
|
|
|
|
/* Anneal */
|
|
$temperature = 25.0;
|
|
while(1) {
|
|
$moves = 1000;
|
|
for($m = 0; $m<$moves; $m++) {
|
|
/* Pick 2 moves at random */
|
|
$move = pick_random_move($team);
|
|
/* See what the new cost is compared to the old */
|
|
list($delta_c, $movedata) =
|
|
compute_delta_cost($team, $judges, $move);
|
|
|
|
|
|
$r = floatval(rand()) / floatval(getrandmax());
|
|
/* Decide if we want to keep it */
|
|
$e = exp(-$delta_c / $temperature);
|
|
TRACE("r=$r, exp=$e\n");
|
|
if($r < exp(-$delta_c / $temperature)) {
|
|
/* Yes, we do, record the move */
|
|
record_move($team, $move, $movedata);
|
|
$current_cost += $delta_c;
|
|
$n_accepted++;
|
|
if($current_cost < $best_cost)
|
|
$best_cost = $current_cost;
|
|
TRACE("Move accepted, cost=$current_cost\n");
|
|
} else {
|
|
TRACE("Move rejected\n");
|
|
}
|
|
|
|
}
|
|
TRACE("Cost is $current_cost\n");
|
|
$temperature *= 0.9;
|
|
|
|
if($temperature <= 0.05) break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
$q=mysql_query("SELECT * FROM projectdivisions WHERE year='".$config['FAIRYEAR']."' ORDER BY id");
|
|
while($r=mysql_fetch_object($q))
|
|
{
|
|
$divshort[$r->id]=$r->division_shortform;
|
|
$div[$r->id]=$r->division;
|
|
}
|
|
|
|
$q=mysql_query("SELECT * FROM projectcategories WHERE year='".$config['FAIRYEAR']."' ORDER BY id");
|
|
while($r=mysql_fetch_object($q))
|
|
$cat[$r->id]=$r->category;
|
|
|
|
$langr = array();
|
|
$q=mysql_query("SELECT * FROM languages WHERE active='Y'");
|
|
while($r=mysql_fetch_object($q))
|
|
$langr[] = $r->lang;
|
|
|
|
|
|
$configq=mysql_query("SELECT * FROM judges_schedulerconfig WHERE year='".$config['FAIRYEAR']."'");
|
|
$data=array();
|
|
while($configr=mysql_fetch_object($configq))
|
|
$data[$configr->var]=$configr->val;
|
|
|
|
$data['teams'] = array();
|
|
$data['projects'] = array();
|
|
$jdivisions = array();
|
|
|
|
/* Load a list of all projects, and build an array of projects in each
|
|
* category */
|
|
// print_r($langr);
|
|
$q=mysql_query("SELECT * FROM projects WHERE year='".$config['FAIRYEAR']."'");
|
|
while($r=mysql_fetch_object($q)) {
|
|
$d_id = $r->projectdivisions_id;
|
|
$c_id = $r->projectcategories_id;
|
|
$l_id = $r->language;
|
|
|
|
$data['projects'][$r->id]['timetable'] = array();
|
|
|
|
|
|
if(!in_array($l_id, $langr)) $l_id = 'en';
|
|
|
|
$jdivisions[$d_id][$c_id][$l_id][] = $r->id;
|
|
|
|
TRACE("Found project id {$r->id} in $d_id, $c_id, $l_id\n\n");
|
|
}
|
|
|
|
|
|
$t=0;
|
|
$max_ts = 0;
|
|
foreach($div AS $d_id=>$d_val)
|
|
{
|
|
foreach($cat AS $c_id=>$c_val)
|
|
{
|
|
foreach($langr AS $l_id) {
|
|
$num = count($jdivisions[$d_id][$c_id][$l_id]);
|
|
|
|
if($num <= 0) continue;
|
|
$numteams=ceil($num/$data['max_projects_per_team']*$data['num_times_judged']);
|
|
|
|
if($numteams < $data['num_times_judged'])
|
|
$numteams = $data['num_times_judged'];
|
|
TRACE("Judging teams for $d_id, $c_id, $l_id is $numteams\n\n");
|
|
|
|
$start_t = $t;
|
|
for($x=0; $x<$numteams; $x++) {
|
|
$team[$t]['division'] = $d_id;
|
|
$team[$t]['category'] = $c_id;
|
|
$team[$t]['language'] = $l_id;
|
|
$team[$t]['min'] = $data['min_judges_per_team'];
|
|
$team[$t]['max'] = $data['max_judges_per_team'];
|
|
$team[$t]['judges'] = array();
|
|
$t++;
|
|
}
|
|
|
|
TRACE("Created judging teams $start_t -> ".($t - 1)."\n\n");
|
|
|
|
TRACE("Need to assign these teams to $num projects: ");
|
|
// print_r($jdivisions[$d_id][$c_id][$l_id]);
|
|
TRACE("\n\n");
|
|
/* We just created teams $start_t -> $t-1, now we can assign which projects
|
|
* they judge in different timeslots */
|
|
/* Each project must be judged $data['num_times_judged'], and each team is
|
|
* allowed to judge $data['num_times_judged'] projects */
|
|
$x=0; /* Cycles over 0 -> $num */
|
|
$ts=1; /* Current timeslot , increment when all judging teams are assinged */
|
|
$j=0; /* Cycles over o0 -> $numteams */
|
|
$teams_at_this_ts = array();
|
|
$num_done = 0;
|
|
while(1) {
|
|
|
|
TRACE("x=$x ");
|
|
if($x == $num) $x=0;
|
|
|
|
/* Get the project id we want to look at */
|
|
$p = $jdivisions[$d_id][$c_id][$l_id][$x];
|
|
TRACE(" project=$p \n\n");
|
|
|
|
TRACE("This project has ".(count($data['projects'][$p]['timetable']))." judging teams\n");
|
|
|
|
/* See if this project needs more judges */
|
|
if(count($data['projects'][$p]['timetable']) == $data['num_times_judged']) {
|
|
/* No, this project doesn't need any more judging teams */
|
|
TRACE(" This project doesn't need more teams, skipping\n\n");
|
|
// print_r($data['projects'][$p]['timetable']);
|
|
TRACE("\n\n");
|
|
if($data['projects'][$p]['timetable_done'] != 1) {
|
|
$data['projects'][$p]['timetable_done'] = 1;
|
|
$num_done++;
|
|
|
|
if($num_done == $num) break;
|
|
}
|
|
$x++;
|
|
continue;
|
|
}
|
|
|
|
/* Find a judging team to assign */
|
|
|
|
TRACE("Starting at team=$j\n\n");
|
|
while(1) {
|
|
TRACE("j=$j");
|
|
if($j == $numteams) $j = 0;
|
|
$jteam = $j + $start_t;
|
|
|
|
TRACE(" team=$jteam\n\n");
|
|
if(in_array($jteam, $teams_at_this_ts)) {
|
|
$j++;
|
|
continue;
|
|
}
|
|
|
|
if(!in_array($jteam, $data['projects'][$p]['timetable'])) {
|
|
/* Add this juding team to the timetable */
|
|
TRACE("Project $p, timeslot $ts = judging team $jteam\n\n");
|
|
$data['projects'][$p]['timetable'][$ts] = $jteam;
|
|
$teams_at_this_ts[] = $jteam;
|
|
$j++;
|
|
break;
|
|
}
|
|
$j++;
|
|
if($j==$numteams) $j=0;
|
|
}
|
|
$x++;
|
|
/* If we've used all the judging teams, of we've assigned judges equal
|
|
* to the number of projects, it's time for the next timeslot */
|
|
if(count($teams_at_this_ts) == $numteams || count($teams_at_this_ts) == $num) {
|
|
$ts++;
|
|
$teams_at_this_ts = array();
|
|
if($ts > $max_ts) $max_ts = $ts;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//print_r($data['projects']);
|
|
TRACE("Teams: ".count($team)."\n");
|
|
//print_r($team);
|
|
|
|
TRACE("\n");
|
|
|
|
$q=mysql_query("SELECT judges.* FROM judges,judges_years WHERE complete='yes' AND judges_years.year='{$config['FAIRYEAR']}' AND judges_years.judges_id=judges.id");
|
|
|
|
$judges=array();
|
|
|
|
while($r=mysql_fetch_object($q))
|
|
{
|
|
unset($divprefs);
|
|
unset($catprefs);
|
|
unset($langprefs);
|
|
|
|
//get category preferences
|
|
$q2=mysql_query("SELECT * FROM judges_catpref WHERE judges_id='$r->id' AND year='".$config['FAIRYEAR']."' ORDER BY projectcategories_id");
|
|
$catprefs=array();
|
|
while($r2=mysql_fetch_object($q2))
|
|
$catprefs[$r2->projectcategories_id]=$r2->rank;
|
|
|
|
//get division preferences
|
|
$q2=mysql_query("SELECT * FROM judges_expertise WHERE judges_id='$r->id' AND year='".$config['FAIRYEAR']."' AND projectsubdivisions_id IS NULL ORDER BY projectdivisions_id");
|
|
//the areas of expertise are ranked from 1 to 5, and we need them as -2,-1,0,1,2 so we simply subtract 3
|
|
$divprefs=array();
|
|
while($r2=mysql_fetch_object($q2))
|
|
$divprefs[$r2->projectdivisions_id]=$r2->val-3;
|
|
|
|
$langperfs = array();
|
|
$q3=mysql_query("SELECT * from judges_languages WHERE judges_id='$r->id'");
|
|
while($r3=mysql_fetch_object($q3))
|
|
$langprefs[]=$r3->languages_lang;
|
|
|
|
|
|
$judges[]=array(
|
|
"judges_id"=>"$r->id",
|
|
"name"=>"$r->firstname $r->lastname",
|
|
"years_school"=>$r->years_school,
|
|
"years_regional"=>$r->years_regional,
|
|
"years_national"=>$r->years_national,
|
|
"willing_chair"=>$r->willing_chair,
|
|
"divprefs"=>$divprefs,
|
|
"catprefs"=>$catprefs,
|
|
"languages"=>$langprefs
|
|
);
|
|
}
|
|
|
|
//print_r($judges);
|
|
//echo nl2br(TRACE_R($judges, true));
|
|
|
|
judges_assign_anneal($div,$cat, $langr, $judges, $team, $data);
|
|
|
|
//print_r( $team);
|
|
$teamnums=array();
|
|
|
|
echo i18n("Judging teams successfully created. You can review the teams and modify as desired using the following links");
|
|
echo "<br />";
|
|
echo "<br />";
|
|
echo "<a href=\"judges_teams.php\">".i18n("Manage Judge Teams")."</a>";
|
|
echo "<br />";
|
|
echo "<a href=\"judges_teams_members.php\">".i18n("Manage Judge Members")."</a>";
|
|
echo "<br />";
|
|
echo "<br />";
|
|
|
|
$totalcost=0;
|
|
while(list($tn, $t) = each($team)) {
|
|
//team numbers start with 0 in the annealer, but we want them to start at 1, so just tn++ here.
|
|
$tn++;
|
|
|
|
print("Team $tn: ({$div[$t['division']]}({$t['division']}),{$cat[$t['category']]}({$t['category']})) ".
|
|
"(lang:{$t['language']} ".
|
|
"(cost:{$t['cost']} )<br>\n");
|
|
$totalcost+=$t['cost'];
|
|
|
|
if(!$teamnums[$t['division']][$t['category']]) $teamnums[$t['division']][$t['category']]=1;
|
|
else $teamnums[$t['division']][$t['category']]++;
|
|
|
|
mysql_query("INSERT INTO judges_teams (num,name,autocreate_type_id,year) VALUES ('$tn','(Div) {$divshort[$t['division']]} - {$cat[$t['category']]} #{$teamnums[$t['division']][$t['category']]} ({$t['language']})','1','{$config['FAIRYEAR']}')");
|
|
$team_id=mysql_insert_id();
|
|
//use tn-1 since we incremented it at the top :p
|
|
$team[$tn-1]['team_id']=$team_id;
|
|
|
|
while(list($key, $j) = each($t['judges']) ) {
|
|
$judge = $judges[$j];
|
|
print(" {$judge['name']}");
|
|
if($judge['willing_chair']=='yes') print("(chair)");
|
|
while(list($k, $l) = each($judge['languages']) ) {
|
|
print(" $l ");
|
|
}
|
|
print("<br>\n");
|
|
|
|
mysql_query("INSERT INTO judges_teams_link (judges_id,judges_teams_id,captain,year) VALUES ('{$judge['judges_id']}','$team_id','{$judge['willing_chair']}','{$config['FAIRYEAR']}')");
|
|
}
|
|
|
|
//and finally, link the team to the award
|
|
|
|
$q=mysql_query("SELECT award_awards.id FROM
|
|
award_awards,
|
|
award_awards_projectcategories,
|
|
award_awards_projectdivisions
|
|
WHERE
|
|
award_awards.year='{$config['FAIRYEAR']}'
|
|
AND award_awards.id=award_awards_projectcategories.award_awards_id
|
|
AND award_awards.id=award_awards_projectdivisions.award_awards_id
|
|
AND award_awards_projectcategories.projectcategories_id='{$t['category']}'
|
|
AND award_awards_projectdivisions.projectdivisions_id='{$t['division']}'
|
|
AND award_awards.award_types_id='1'
|
|
");
|
|
if(mysql_num_rows($q)!=1)
|
|
{
|
|
echo error(i18n("Cannot find award for %1 - %2",array($cat[$t['category']],$div[$t['division']])));
|
|
}
|
|
else
|
|
{
|
|
$r=mysql_fetch_object($q);
|
|
mysql_query("INSERT INTO judges_teams_awards_link (award_awards_id,judges_teams_id,year) VALUES ('$r->id','$team_id','{$config['FAIRYEAR']}')");
|
|
}
|
|
}
|
|
|
|
|
|
$available_timeslots=array();
|
|
$q=mysql_query("SELECT * FROM judges_timeslots WHERE year='".$config['FAIRYEAR']."' AND allowdivisional='yes' ORDER BY date,starttime");
|
|
while($r=mysql_Fetch_object($q))
|
|
{
|
|
$available_timeslots[]=array("id"=>$r->id,"date"=>$r->date,"starttime"=>substr($r->starttime,0,-3),"endtime"=>substr($r->endtime,0,-3));
|
|
}
|
|
|
|
print("Project Timeslots:<br>\n");
|
|
print("<table border=1><tr><td>Project ID</td>");
|
|
//FIXME:! max_ts is sometimes bigger than it should be (by 1 or 2)! whats going on??
|
|
for($x=0;$x<=$max_ts;$x++) {
|
|
print("<td>".$available_timeslots[$x]['starttime']."-".$available_timeslots[$x]['endtime']."</td>");
|
|
}
|
|
print("</tr>");
|
|
while(list($proj_id, $projinfo) = each( $data['projects'] )) {
|
|
print("<tr><td>$proj_id</td>");
|
|
$last_slot = 1;
|
|
while(list($slot,$jteam) = each ($projinfo['timetable']) ) {
|
|
while($last_slot != $slot) {
|
|
print("<td> </td>");
|
|
$last_slot++;
|
|
}
|
|
print("<td>#".($jteam+1));
|
|
echo "<br />";
|
|
echo "team_id=".$team[$jteam]['team_id'];
|
|
echo "<br />";
|
|
echo "proj_id=".$proj_id;
|
|
echo "<br />";
|
|
echo "ts_id=".$available_timeslots[$slot-1]['id'];
|
|
echo "<br />";
|
|
echo "</td>";
|
|
$last_slot++;
|
|
|
|
//add the link of the judge team to the timeslot
|
|
mysql_query("INSERT INTO judges_teams_timeslots_link (judges_teams_id,judges_timeslots_id,year) VALUES (
|
|
'".$team[$jteam]['team_id']."',
|
|
'".$available_timeslots[$slot-1]['id']."',
|
|
'".$config['FAIRYEAR']."')");
|
|
|
|
//now add the link of hte project to this judge team & timeslot
|
|
mysql_query("INSERT INTO judges_teams_timeslots_projects_link (judges_teams_id,judges_timeslots_id,projects_id,year) VALUES (
|
|
'".$team[$jteam]['team_id']."',
|
|
'".$available_timeslots[$slot-1]['id']."',
|
|
'".$proj_id."',
|
|
'".$config['FAIRYEAR']."')");
|
|
}
|
|
print("</tr>");
|
|
}
|
|
print("</table>");
|
|
|
|
|
|
|
|
|
|
|
|
echo "<br />";
|
|
echo "<br />";
|
|
echo "<b>Total 'cost' for all teams: $totalcost</b>";
|
|
|
|
send_footer();
|
|
?>
|