]> git.localhorst.tv Git - alttp.git/blob - app/Models/Round.php
adlib chat
[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                 if ($this->tournament->type == 'open-async') {
25                         $results = $this->results->sort([Result::class, 'compareResult']);
26                         $reversed = $results->reverse();
27
28                         $running = 0;
29                         $bonus = 1;
30                         $lastResult = null;
31                         foreach ($reversed as $result) {
32                                 $betterThanLast = is_null($lastResult) || $result->time < $lastResult;
33                                 if (!$result->forfeit && $betterThanLast) {
34                                         $running += $bonus;
35                                         $lastResult = $result->time;
36                                         $bonus = 1;
37                                 } else {
38                                         ++$bonus;
39                                 }
40                                 if (!$result->forfeit) {
41                                         $result->updatePlacement($running, count($results) - $running + 1);
42                                 } else {
43                                         $result->updatePlacement(0, count($results));
44                                 }
45                         }
46                 } else {
47                         $runners = [];
48                         foreach ($this->tournament->participants as $p) {
49                                 if ($p->isRunner()) {
50                                         $runners[] = $p;
51                                 } else {
52                                         $result = $p->findResult($this);
53                                         if ($result) {
54                                                 $result->updatePlacement(null, null);
55                                         }
56                                 }
57                         }
58
59                         usort($runners, Participant::compareResult($this));
60                         $mapped = array_map(function ($p) {
61                                 return ['participant' => $p, 'result' => $p->findResult($this)];
62                         }, $runners);
63                         $filtered = array_filter($mapped, function($r) {
64                                 return $r['result'] && ($r['result']->time || $r['result']->forfeit);
65                         });
66                         $reversed = array_reverse($filtered);
67
68                         $running = 0;
69                         $bonus = 1;
70                         $lastResult = null;
71                         foreach ($reversed as $r) {
72                                 $betterThanLast = is_null($lastResult) || $r['result']->time < $lastResult;
73                                 if (!$r['result']->forfeit && $betterThanLast) {
74                                         $running += $bonus;
75                                         $lastResult = $r['result']->time;
76                                         $bonus = 1;
77                                 } else {
78                                         ++$bonus;
79                                 }
80                                 if (!$r['result']->forfeit) {
81                                         $r['result']->updatePlacement($running, count($filtered) - $running + 1);
82                                 } else {
83                                         $r['result']->updatePlacement(0, count($filtered));
84                                 }
85                         }
86                 }
87         }
88
89
90         public function hideResults() {
91                 foreach ($this->results as $result) {
92                         $result->makeHidden(['forfeit', 'placement', 'score', 'time']);
93                 }
94         }
95
96
97         public function results() {
98                 return $this->hasMany(Result::class);
99         }
100
101         public function rolled_by_user() {
102                 return $this->belongsTo(User::class, 'rolled_by');
103         }
104
105         public function tournament() {
106                 return $this->belongsTo(Tournament::class);
107         }
108
109
110         protected $casts = [
111                 'code' => 'array',
112                 'locked' => 'boolean',
113                 'no_record' => 'boolean',
114                 'rolled_by' => 'string',
115         ];
116
117         protected $fillable = [
118                 'game',
119                 'number',
120                 'no_record',
121                 'tournament_id',
122         ];
123
124         protected $with = [
125                 'rolled_by_user',
126         ];
127
128 }