]> git.localhorst.tv Git - alttp.git/blob - app/Models/Round.php
18be60fe015d346a085a416e4990aee3458c7447
[alttp.git] / app / Models / Round.php
1 <?php
2
3 namespace App\Models;
4
5 use Illuminate\Database\Eloquent\Factories\HasFactory;
6 use Illuminate\Database\Eloquent\Model;
7
8 class Round extends Model
9 {
10         use HasFactory;
11
12
13         public function isComplete() {
14                 if (count($this->tournament->participants) == 0) return false;
15                 if (count($this->results) == 0) return false;
16                 foreach ($this->tournament->getRunners() as $participant) {
17                         $result = $participant->findResult($this);
18                         if (!$result || !$result->has_finished) return false;
19                 }
20                 return true;
21         }
22
23         public function updatePlacement() {
24                 $runners = [];
25                 foreach ($this->tournament->participants as $p) {
26                         if ($p->isRunner()) {
27                                 $runners[] = $p;
28                         } else {
29                                 $result = $p->findResult($this);
30                                 if ($result) {
31                                         $result->updatePlacement(null, null);
32                                 }
33                         }
34                 }
35
36                 usort($runners, Participant::compareResult($this));
37                 $mapped = array_map(function ($p) {
38                         return ['participant' => $p, 'result' => $p->findResult($this)];
39                 }, $runners);
40                 $filtered = array_filter($mapped, function($r) {
41                         return $r['result'] && ($r['result']->time || $r['result']->forfeit);
42                 });
43                 $reversed = array_reverse($filtered);
44
45                 $running = 0;
46                 $bonus = 1;
47                 $lastResult = null;
48                 foreach ($reversed as $r) {
49                         $betterThanLast = is_null($lastResult) || $r['result']->time < $lastResult;
50                         if (!$r['result']->forfeit && $betterThanLast) {
51                                 $running += $bonus;
52                                 $lastResult = $r['result']->time;
53                                 $bonus = 1;
54                         } else {
55                                 ++$bonus;
56                         }
57                         if (!$r['result']->forfeit) {
58                                 $r['result']->updatePlacement($running, count($filtered) - $running + 1);
59                         } else {
60                                 $r['result']->updatePlacement(0, count($filtered));
61                         }
62                 }
63         }
64
65
66         public function hideResults() {
67                 foreach ($this->results as $result) {
68                         $result->makeHidden(['forfeit', 'placement', 'score', 'time']);
69                 }
70         }
71
72
73         public function results() {
74                 return $this->hasMany(Result::class);
75         }
76
77         public function rolled_by_user() {
78                 return $this->belongsTo(User::class, 'rolled_by');
79         }
80
81         public function tournament() {
82                 return $this->belongsTo(Tournament::class);
83         }
84
85
86         protected $casts = [
87                 'code' => 'array',
88                 'locked' => 'boolean',
89                 'no_record' => 'boolean',
90         ];
91
92         protected $fillable = [
93                 'number',
94                 'no_record',
95                 'tournament_id',
96         ];
97
98         protected $with = [
99                 'rolled_by_user',
100         ];
101
102 }