+
+ public function isComplete() {
+ if (count($this->tournament->participants) == 0) return false;
+ if (count($this->results) == 0) return false;
+ foreach ($this->tournament->getRunners() as $participant) {
+ $result = $participant->findResult($this);
+ if (!$result || !$result->has_finished) return false;
+ }
+ return true;
+ }
+
+ public function updatePlacement() {
+ if ($this->tournament->type == 'open-async') {
+ $results = $this->results->sort([Result::class, 'compareResult']);
+ $reversed = $results->reverse();
+
+ $running = 0;
+ $bonus = 1;
+ $lastResult = null;
+ foreach ($reversed as $result) {
+ $betterThanLast = is_null($lastResult) || $result->time < $lastResult;
+ if (!$result->forfeit && $betterThanLast) {
+ $running += $bonus;
+ $lastResult = $result->time;
+ $bonus = 1;
+ } else {
+ ++$bonus;
+ }
+ if (!$result->forfeit) {
+ $result->updatePlacement($running, count($results) - $running + 1);
+ } else {
+ $result->updatePlacement(0, count($results));
+ }
+ }
+ } else {
+ $runners = [];
+ foreach ($this->tournament->participants as $p) {
+ if ($p->isRunner()) {
+ $runners[] = $p;
+ } else {
+ $result = $p->findResult($this);
+ if ($result) {
+ $result->updatePlacement(null, null);
+ }
+ }
+ }
+
+ usort($runners, Participant::compareResult($this));
+ $mapped = array_map(function ($p) {
+ return ['participant' => $p, 'result' => $p->findResult($this)];
+ }, $runners);
+ $filtered = array_filter($mapped, function($r) {
+ return $r['result'] && ($r['result']->time || $r['result']->forfeit);
+ });
+ $reversed = array_reverse($filtered);
+
+ $running = 0;
+ $bonus = 1;
+ $lastResult = null;
+ foreach ($reversed as $r) {
+ $betterThanLast = is_null($lastResult) || $r['result']->time < $lastResult;
+ if (!$r['result']->forfeit && $betterThanLast) {
+ $running += $bonus;
+ $lastResult = $r['result']->time;
+ $bonus = 1;
+ } else {
+ ++$bonus;
+ }
+ if (!$r['result']->forfeit) {
+ $r['result']->updatePlacement($running, count($filtered) - $running + 1);
+ } else {
+ $r['result']->updatePlacement(0, count($filtered));
+ }
+ }
+ }
+ }
+
+
+ public function hideResults() {
+ foreach ($this->results as $result) {
+ $result->makeHidden(['forfeit', 'placement', 'score', 'time']);
+ }
+ }
+
+