Esempio n. 1
0
/**
 * Scoreboard
 */
function scoreboard($args)
{
    global $DB, $api, $cdatas, $cids;
    if (isset($args['cid'])) {
        $cid = safe_int($args['cid']);
    } else {
        if (count($cids) == 1) {
            $cid = reset($cids);
        } else {
            $api->createError("No contest ID specified but active contest is ambiguous.");
        }
    }
    $filter = array();
    if (array_key_exists('category', $args)) {
        $filter['categoryid'] = array($args['category']);
    }
    if (array_key_exists('country', $args)) {
        $filter['country'] = array($args['country']);
    }
    if (array_key_exists('affiliation', $args)) {
        $filter['affilid'] = array($args['affiliation']);
    }
    $scoreboard = genScoreBoard($cdatas[$cid], !$args['public'], $filter);
    $prob2label = $DB->q('KEYVALUETABLE SELECT probid, shortname
	                      FROM contestproblem WHERE cid = %i', $cid);
    $res = array();
    foreach ($scoreboard['scores'] as $teamid => $data) {
        $row = array('rank' => $data['rank'], 'team' => $teamid);
        $row['score'] = array('num_solved' => safe_int($data['num_points']), 'total_time' => safe_int($data['total_time']));
        $row['problems'] = array();
        foreach ($scoreboard['matrix'][$teamid] as $probid => $pdata) {
            $prob = array('label' => $prob2label[$probid], 'num_judged' => safe_int($pdata['num_submissions']), 'num_pending' => safe_int($pdata['num_pending']), 'solved' => safe_bool($pdata['is_correct']));
            if ($prob['solved']) {
                $prob['time'] = scoretime($pdata['time']);
                $first = first_solved($pdata['time'], $scoreboard['summary']['problems'][$probid]['best_time_sort'][$data['sortorder']]);
                $prob['first_to_solve'] = safe_bool($first);
            }
            $row['problems'][] = $prob;
        }
        usort($row['problems'], 'cmp_prob_label');
        $res[] = $row;
    }
    return $res;
}
Esempio n. 2
0
/**
 * Output the general scoreboard based on the cached data in table
 * 'scorecache'. $myteamid can be passed to highlight a
 * specific row.
 * If this function is called while IS_JURY is defined, the scoreboard
 * will always be current, regardless of the freezetime setting in the
 * contesttable.
 * $static generates output suitable for standalone static html pages,
 * that is without references/links to other parts of the DOMjudge
 * interface.
 * $limitteams is an array of teamid's whose rows will be the only
 * ones displayed. The function still needs the complete scoreboard
 * data or it will not know the rank.
 * if $displayrank is false the first column will not display the
 * team's current rank but a question mark.
 */
function renderScoreBoardTable($sdata, $myteamid = null, $static = FALSE, $limitteams = null, $displayrank = TRUE, $center = FALSE, $showlegends = TRUE)
{
    // 'unpack' the scoreboard data:
    $scores = $sdata['scores'];
    $matrix = $sdata['matrix'];
    $summary = $sdata['summary'];
    $teams = $sdata['teams'];
    $probs = $sdata['problems'];
    $categs = $sdata['categories'];
    unset($sdata);
    // configuration
    $SHOW_AFFILIATIONS = dbconfig_get('show_affiliations', 1);
    $SHOW_PENDING = dbconfig_get('show_pending', 0);
    // Do not show points if they are all 1
    $showpoints = FALSE;
    foreach ($probs as $pr) {
        if ($pr['points'] != 1) {
            $showpoints = TRUE;
            break;
        }
    }
    echo '<table class="scoreboard' . (IS_JURY ? ' scoreboard_jury' : '') . ($center ? ' center' : '') . "\">\n";
    // output table column groups (for the styles)
    echo '<colgroup><col id="scorerank" />' . ($SHOW_AFFILIATIONS ? '<col id="scoreaffil" />' : '') . '<col id="scoreteamname" /></colgroup><colgroup><col id="scoresolv" />' . "<col id=\"scoretotal\" /></colgroup>\n<colgroup>" . str_repeat('<col class="scoreprob" />', count($probs)) . "</colgroup>\n";
    // column headers
    echo "<thead>\n";
    echo '<tr class="scoreheader">' . '<th title="rank" scope="col">' . jurylink(null, 'rank') . '</th>' . '<th title="team name" scope="col"' . ($SHOW_AFFILIATIONS ? ' colspan="2"' : '') . '>' . jurylink(null, 'team') . '</th>' . '<th title="# solved / penalty time" colspan="2" scope="col">' . jurylink(null, 'score') . '</th>' . "\n";
    foreach ($probs as $pr) {
        echo '<th title="problem \'' . specialchars($pr['name']) . '\'" scope="col">';
        $str = specialchars($pr['shortname']) . (!empty($pr['color']) ? ' <div class="circle" style="background: ' . specialchars($pr['color']) . ';"></div>' : '');
        if (!$static && (IS_JURY || $pr['hastext'] > 0)) {
            echo '<a href="problem.php?id=' . urlencode($pr['probid']) . '">' . $str . '</a>';
        } else {
            echo '<a>' . $str . '</a>';
        }
        if ($showpoints) {
            $points = $pr['points'];
            $pts = $points == 1 ? '1 point' : "{$points} points";
            echo "<span class='problempoints'>[{$pts}]</span>";
        }
        echo '</th>';
    }
    echo "</tr>\n</thead>\n\n<tbody>\n";
    // print the main scoreboard rows
    $prevsortorder = -1;
    foreach ($scores as $team => $totals) {
        // skip if we have limitteams and the team is not listed
        if (!empty($limitteams) && !in_array($team, $limitteams)) {
            continue;
        }
        // rank, team name, total points, total time
        echo '<tr';
        $classes = array();
        if ($totals['sortorder'] != $prevsortorder) {
            $classes[] = "sortorderswitch";
            $prevsortorder = $totals['sortorder'];
            $prevteam = null;
        }
        // check whether this is us, otherwise use category colour
        if (@$myteamid == $team) {
            $classes[] = "scorethisisme";
            unset($color);
        } else {
            $color = $teams[$team]['color'];
        }
        if (count($classes) > 0) {
            echo ' class="' . implode(' ', $classes) . '"';
        }
        echo ' id="team:' . $teams[$team]['teamid'] . '"';
        echo '><td class="scorepl">';
        // Only print rank when score is different from the previous team
        if (!$displayrank) {
            echo jurylink(null, '?');
        } elseif (!isset($prevteam) || $scores[$prevteam]['rank'] != $totals['rank']) {
            echo jurylink(null, $totals['rank']);
        } else {
            echo jurylink(null, '');
        }
        $prevteam = $team;
        echo '</td>';
        if ($SHOW_AFFILIATIONS) {
            echo '<td class="scoreaf">';
            if (isset($teams[$team]['affilid'])) {
                if (IS_JURY) {
                    echo '<a href="team_affiliation.php?id=' . urlencode($teams[$team]['affilid']) . '">';
                }
                if (isset($teams[$team]['country'])) {
                    $countryflag = '../images/countries/' . urlencode($teams[$team]['country']) . '.png';
                    echo ' ';
                    if (is_readable($countryflag)) {
                        echo '<img src="' . $countryflag . '"' . ' alt="' . specialchars($teams[$team]['country']) . '"' . ' title="' . specialchars($teams[$team]['country']) . '" />';
                    } else {
                        echo specialchars($teams[$team]['country']);
                    }
                }
                if (IS_JURY) {
                    echo '</a>';
                }
            }
            echo '</td>';
        }
        $affilname = '';
        if ($SHOW_AFFILIATIONS && isset($teams[$team]['affilid'])) {
            $affilname = specialchars($teams[$team]['affilname']);
        }
        echo '<td class="scoretn"' . (!empty($color) ? ' style="background: ' . $color . ';"' : '') . (IS_JURY ? ' title="' . specialchars($team) . '"' : '') . '>' . ($static ? '' : '<a href="team.php?id=' . urlencode($team) . '">') . specialchars($teams[$team]['name']) . ($SHOW_AFFILIATIONS ? '<br /><span class="univ">' . $affilname . '</span>' : '') . ($static ? '' : '</a>') . '</td>';
        echo '<td class="scorenc">' . jurylink(null, $totals['num_points']) . '</td>' . '<td class="scorett">' . jurylink(null, $totals['total_time']) . '</td>';
        // for each problem
        foreach (array_keys($probs) as $prob) {
            echo '<td class=';
            // CSS class for correct/incorrect/neutral results
            if ($matrix[$team][$prob]['is_correct']) {
                echo '"score_correct' . (first_solved($matrix[$team][$prob]['time'], @$summary['problems'][$prob]['best_time_sort'][$totals['sortorder']]) ? ' score_first' : '') . '"';
            } elseif ($matrix[$team][$prob]['num_pending'] > 0 && $SHOW_PENDING) {
                echo '"score_pending"';
            } elseif ($matrix[$team][$prob]['num_submissions'] > 0) {
                echo '"score_incorrect"';
            } else {
                echo '"score_neutral"';
            }
            // number of submissions for this problem
            $str = $matrix[$team][$prob]['num_submissions'];
            // add pending submissions
            if ($matrix[$team][$prob]['num_pending'] > 0 && $SHOW_PENDING) {
                $str .= ' + ' . $matrix[$team][$prob]['num_pending'];
            }
            // if correct, print time scored
            if ($matrix[$team][$prob]['is_correct']) {
                $str .= '/' . scoretime($matrix[$team][$prob]['time']);
            }
            echo '>' . jurylink('team.php?id=' . urlencode($team) . '&amp;restrict=probid:' . urlencode($prob), $str) . '</td>';
        }
        echo "</tr>\n";
    }
    echo "</tbody>\n\n";
    if (empty($limitteams)) {
        // print a summaryline. Exclude the "total solved" cell if using
        // perproblem points as it's actually total points and not useful
        if (!$showpoints) {
            $totalCell = '<td title="total solved" class="scorenc">' . jurylink(null, $summary['num_points']) . '</td>';
        } else {
            $totalCell = '<td class="scorenc" title=" "></td>';
            // Empty
        }
        echo '<tbody><tr id="scoresummary" title="#submitted / #correct">' . '<td title="total teams">' . jurylink(null, count($matrix)) . '</td>' . ($SHOW_AFFILIATIONS ? '<td class="scoreaffil" title="#affiliations / #countries">' . jurylink('team_affiliations.php', count($summary['affils']) . ' / ' . count($summary['countries'])) . '</td>' : '') . '<td title=" ">' . jurylink(null, 'Summary') . '</td>' . $totalCell . '<td title=" "></td>';
        foreach (array_keys($probs) as $prob) {
            $str = $summary['problems'][$prob]['num_submissions'] . '/' . $summary['problems'][$prob]['num_correct'];
            echo '<td>' . jurylink('problem.php?id=' . urlencode($prob), $str) . '</td>';
        }
        echo "</tr>\n</tbody>\n";
    }
    echo "</table>\n\n";
    if ($showlegends) {
        echo "<p><br /><br /></p>\n";
        // only print legend when there's more than one category
        if (empty($limitteams) && count($categs) > 1) {
            echo "<table id=\"categ_legend\" class=\"scoreboard scorelegend" . (IS_JURY ? ' scoreboard_jury' : '') . "\">\n" . "<thead><tr><th scope=\"col\">" . jurylink('team_categories.php', 'Categories') . "</th></tr></thead>\n<tbody>\n";
            foreach ($categs as $cat) {
                echo '<tr' . (!empty($cat['color']) ? ' style="background: ' . $cat['color'] . ';"' : '') . '>' . '<td>' . jurylink('team_category.php?id=' . urlencode($cat['categoryid']), specialchars($cat['name'])) . "</td></tr>\n";
            }
            echo "</tbody>\n</table>\n&nbsp;\n";
        }
        // print legend of scorecell colors
        $cellcolors = array('first' => 'Solved first', 'correct' => 'Solved', 'incorrect' => 'Tried, incorrect', 'pending' => 'Tried, pending', 'neutral' => 'Untried');
        echo "<table id=\"cell_legend\" class=\"scoreboard scorelegend" . (IS_JURY ? ' scoreboard_jury' : '') . "\">\n" . "<thead><tr><th scope=\"col\">" . jurylink(null, 'Cell colours') . "</th></tr></thead>\n<tbody>\n";
        foreach ($cellcolors as $color => $desc) {
            if ($color == 'pending' && !dbconfig_get('show_pending', 0)) {
                continue;
            }
            echo '<tr class="score_' . $color . '">' . '<td>' . jurylink(null, $desc) . "</td></tr>\n";
        }
        echo "</tbody>\n</table>\n\n";
    }
    return;
}