Skip to content

Commit b84190a

Browse files
committed
Add a basic visualization for the scoring scoreboard type.
This currently only works with integers, e.g. setting points per problem. Part of #2525
1 parent b272039 commit b84190a

File tree

7 files changed

+54
-14
lines changed

7 files changed

+54
-14
lines changed

webapp/src/Service/ScoreboardService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ public function updateRankCache(Contest $contest, Team $team): void
554554
}
555555
}
556556

557-
const SCALE = 9;
557+
public const SCALE = 9;
558558

559559
// Converts integer or bcmath floats to a string that can be used as a key in a score cache.
560560
// The resulting key will be a string with 33 characters, 23 before the decimal dot and 9 after.

webapp/src/Utils/Scoreboard/Scoreboard.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use App\Entity\Contest;
66
use App\Entity\ContestProblem;
77
use App\Entity\RankCache;
8+
use App\Entity\ScoreboardType;
89
use App\Entity\ScoreCache;
910
use App\Entity\Team;
1011
use App\Entity\TeamCategory;
@@ -153,22 +154,32 @@ protected function calculateScoreboard(): void
153154
!array_key_exists($probId, $this->problems)) {
154155
continue;
155156
}
157+
$isCorrect = $scoreCell->getIsCorrect($this->restricted);
156158

157159
$penalty = Utils::calcPenaltyTime(
158-
$scoreCell->getIsCorrect($this->restricted),
160+
$isCorrect,
159161
$scoreCell->getSubmissions($this->restricted),
160162
$this->penaltyTime, $this->scoreIsInSeconds
161163
);
162164

165+
$contestProblem = $scoreCell->getContest()->getContestProblem($scoreCell->getProblem());
166+
// TODO: For actual scoring problems, we need to calculate the score here and
167+
// output it with the correct precision. For now, this is always an integer.
168+
$points = strval(
169+
$isCorrect ?
170+
$contestProblem->getPoints() : 0
171+
);
172+
163173
$this->matrix[$teamId][$probId] = new ScoreboardMatrixItem(
164-
isCorrect: $scoreCell->getIsCorrect($this->restricted),
165-
isFirst: $scoreCell->getIsCorrect($this->restricted) && $scoreCell->getIsFirstToSolve(),
174+
isCorrect: $isCorrect,
175+
isFirst: $isCorrect && $scoreCell->getIsFirstToSolve(),
166176
numSubmissions: $scoreCell->getSubmissions($this->restricted),
167177
numSubmissionsPending: $scoreCell->getPending($this->restricted),
168178
time: $scoreCell->getSolveTime($this->restricted),
169179
penaltyTime: $penalty,
170180
runtime: $scoreCell->getRuntime($this->restricted),
171181
numSubmissionsInFreeze: $scoreCell->getPending(false),
182+
points: $points,
172183
);
173184
}
174185

@@ -258,6 +269,11 @@ public function showPoints(): bool
258269
return false;
259270
}
260271

272+
public function isScoring(): bool
273+
{
274+
return $this->contest->getScoreboardType() === ScoreboardType::SCORING;
275+
}
276+
261277
/**
262278
* Return the used team categories for this scoreboard.
263279
*

webapp/src/Utils/Scoreboard/ScoreboardMatrixItem.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ public function __construct(
1313
public int $penaltyTime,
1414
public int $runtime,
1515
public ?int $numSubmissionsInFreeze = null,
16+
public string $points = "",
1617
) {}
1718
}

webapp/templates/partials/scoreboard_summary.html.twig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
{{ scoreboard.summary.numberOfPoints(sortOrder) }}
2424
</td>
2525
{% endif %}
26-
<td></td>
26+
{% if not scoringScoreboard %}
27+
<td></td>
28+
{% endif %}
2729
{% endif %}
2830
{% for problem in scoreboard.problems %}
2931
{% set summary = scoreboard.summary.problem(problem.probid) %}

webapp/templates/partials/scoreboard_table.html.twig

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
{% set static = false %}
1515
{% endif %}
1616
{% set showPoints = scoreboard.showPoints %}
17+
{% set scoringScoreboard = scoreboard.isScoring %}
1718
{% set usedCategories = scoreboard.usedCategories(limitToTeamIds) %}
1819
{% set hasDifferentCategoryColors = scoreboard.categoryColors(limitToTeamIds) %}
1920
{% set scores = scoreboard.scores | filter(score => limitToTeams is null or score.team.teamid in limitToTeamIds) %}
@@ -62,7 +63,9 @@
6263
{% if enable_ranking %}
6364
<colgroup>
6465
<col id="scoresolv"/>
65-
<col id="scoretotal"/>
66+
{% if not scoringScoreboard %}
67+
<col id="scoretotal"/>
68+
{% endif %}
6669
</colgroup>
6770
{% endif %}
6871
<colgroup>
@@ -79,7 +82,11 @@
7982
{% endif %}
8083
<th title="team name" scope="col" colspan="{{ teamColspan }}">team</th>
8184
{% if enable_ranking %}
82-
<th title="# solved / penalty time" colspan="2" scope="col">score</th>
85+
{% if scoringScoreboard %}
86+
<th title="points" colspan="1" scope="col">score</th>
87+
{% else %}
88+
<th title="# solved / penalty time" colspan="2" scope="col">score</th>
89+
{% endif %}
8390
{% endif %}
8491
{% if showTeamSubmissions or jury %}
8592
{% for problem in problems %}
@@ -107,7 +114,8 @@
107114
>
108115
<a {% if link %}href="{{ link }}"{% endif %} target="{{ target }}">
109116
{{ problem | problemBadge }}
110-
{% if showPoints %}
117+
{% if showPoints and not scoringScoreboard %}
118+
<br/>
111119
<span class='problempoints'>
112120
[{% if problem.points == 1 %}1 point{% else %}{{ problem.points }} points{% endif %}]
113121
</span>
@@ -254,10 +262,12 @@
254262
{% if enable_ranking %}
255263
{% set totalPoints = score.numPoints %}
256264
<td class="scorenc">{{ totalPoints }}</td>
257-
{% if scoreboard.getRuntimeAsScoreTiebreaker() %}
258-
<td class="scorett">{{ "%0.3f s" | format(score.totalRuntime/1000.0) }}</td>
259-
{% else %}
260-
<td class="scorett">{{ totalTime }}</td>
265+
{% if not scoringScoreboard %}
266+
{% if scoreboard.getRuntimeAsScoreTiebreaker() %}
267+
<td class="scorett">{{ "%0.3f s" | format(score.totalRuntime/1000.0) }}</td>
268+
{% else %}
269+
<td class="scorett">{{ totalTime }}</td>
270+
{% endif %}
261271
{% endif %}
262272
{% endif %}
263273
@@ -328,8 +338,17 @@
328338
<td class="score_cell">
329339
{% if numSubmissions != '0' %}
330340
<a {% if link %}href="{{ link }}"{% endif %} {% if extra %}{{ extra | raw }}{% endif %}>
331-
<div class="{{ scoreCssClass }}">
332-
{% if matrixItem.isCorrect %}{{ time }}{% else %}&nbsp;{% endif %}
341+
<div
342+
class="{{ scoreCssClass }}"
343+
{% if scoringScoreboard %}
344+
title="{% if matrixItem.isCorrect %}{{ time }} mins{% endif %}"
345+
{% endif %}
346+
>
347+
{% if scoringScoreboard %}
348+
{% if matrixItem.isCorrect %}{{ matrixItem.points }}{% else %}&nbsp;{% endif %}
349+
{% else %}
350+
{% if matrixItem.isCorrect %}{{ time }}{% else %}&nbsp;{% endif %}
351+
{% endif %}
333352
<span>
334353
{% if numSubmissions is same as(1) %}
335354
1 try

webapp/tests/Unit/Service/AwardServiceTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ protected function setUp(): void
8282
)
8383
->setContest($this->contest)
8484
->setShortname($problemLabel);
85+
$this->contest->addProblem($problem);
8586
$reflectedProblem = new ReflectionClass(Problem::class);
8687
$probIdProperty = $reflectedProblem->getProperty('probid');
8788
$probIdProperty->setAccessible(true);

webapp/tests/Unit/Service/ImportExportServiceTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,6 +1297,7 @@ public function testGetResultsData(bool $full, bool $honors, string $dataSet, st
12971297
->setShortname($problemData['label']);
12981298
$em->persist($problem);
12991299
$em->persist($contestProblem);
1300+
$contest->addProblem($contestProblem);
13001301
$em->flush();
13011302
$contestProblemsById[$contestProblem->getExternalid()] = $contestProblem;
13021303
}

0 commit comments

Comments
 (0)