X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=app%2FModels%2FRound.php;h=7daa77957da58769f332421c6b7840407badb74e;hb=07a88747f8a252b41b739185fcb68bdee3a60f9a;hp=927307c2a7d5dc151b0485a36343134b457f151a;hpb=8b95f300549d865815d1a5b981844d1296898111;p=alttp.git diff --git a/app/Models/Round.php b/app/Models/Round.php index 927307c..7daa779 100644 --- a/app/Models/Round.php +++ b/app/Models/Round.php @@ -9,21 +9,120 @@ class Round extends Model { use HasFactory; + + 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']); + } + } + + public function results() { return $this->hasMany(Result::class); } + public function rolled_by_user() { + return $this->belongsTo(User::class, 'rolled_by'); + } + public function tournament() { return $this->belongsTo(Tournament::class); } + protected $casts = [ 'code' => 'array', + 'locked' => 'boolean', + 'no_record' => 'boolean', + 'rolled_by' => 'string', ]; protected $fillable = [ + 'game', 'number', + 'no_record', 'tournament_id', ]; + protected $with = [ + 'rolled_by_user', + ]; + }