]> git.localhorst.tv Git - alttp.git/blobdiff - app/Models/Channel.php
simple guessing game
[alttp.git] / app / Models / Channel.php
index d1f0fdc784d4f4e0f4078be186322b4a54901bd8..32ac875bb707c0760f9e75d2362a64416db7da61 100644 (file)
@@ -16,6 +16,97 @@ class Channel extends Model
                        ->first();
        }
 
+       public function hasActiveGuessing() {
+               return !is_null($this->guessing_start);
+       }
+
+       public function isAcceptingGuesses() {
+               return !is_null($this->guessing_start) && is_null($this->guessing_end);
+       }
+
+       public function startGuessing($type) {
+               $this->guessing_type = $type;
+               $this->guessing_start = now();
+               $this->save();
+       }
+
+       public function stopGuessing() {
+               $this->guessing_end = now();
+               $this->save();
+       }
+
+       public function solveGuessing($solution) {
+               $start = $this->guessing_start;
+               $end = is_null($this->guessing_end) ? now() : $this->guessing_end;
+               $guesses = $this->guesses()->whereBetween('created_at', [$start, $end])->orderBy('created_at', 'ASC')->get();
+               $unique_guesses = [];
+               foreach ($guesses as $guess) {
+                       $unique_guesses[$guess->uid] = $guess;
+               }
+               $candidates = [];
+               foreach ($unique_guesses as $guess) {
+                       if ($guess->guess == $solution) {
+                               $candidates[] = $guess;
+                       }
+               }
+               if (empty($candidates) && is_numeric($solution)) {
+                       $min_distance = null;
+                       foreach ($unique_guesses as $guess) {
+                               $distance = abs(intval($guess->guess) - intval($solution));
+                               if (is_null($min_distance) || $distance == $min_distance) {
+                                       $candidates[] = $guess;
+                               } else if ($distance < $min_distance) {
+                                       $candidates = [$guess];
+                                       $min_distance = $distance;
+                               }
+                       }
+               }
+               $winners = [];
+               $first = true;
+               foreach ($candidates as $candidate) {
+                       $score = $this->scoreGuessing($solution, $candidate->guess, $first);
+                       $winner = new GuessingWinner();
+                       $winner->channel()->associate($this);
+                       $winner->pod = $start;
+                       $winner->uid = $candidate->uid;
+                       $winner->uname = $candidate->uname;
+                       $winner->guess = $candidate->guess;
+                       $winner->solution = $solution;
+                       $winner->score = $score;
+                       $winner->save();
+                       $winners[] = $winner;
+                       $first = false;
+               }
+               return $winners;
+       }
+
+       public function clearGuessing() {
+               $this->guessing_start = null;
+               $this->guessing_end = null;
+               $this->save();
+       }
+
+       public function registerGuess($uid, $uname, $guess) {
+               $model = new GuessingGuess();
+               $model->channel()->associate($this);
+               $model->uid = $uid;
+               $model->uname = $uname;
+               $model->guess = $guess;
+               $model->save();
+       }
+
+       public function scoreGuessing($solution, $guess, $first) {
+               return 1;
+       }
+
+       public function isValidGuess($solution) {
+               if ($this->guessing_type == 'gtbk') {
+                       $int_solution = intval($solution);
+                       return $int_solution > 0 && $int_solution < 23;
+               }
+               return false;
+       }
+
        public function crews() {
                return $this->hasMany(ChannelCrew::class);
        }
@@ -26,6 +117,10 @@ class Channel extends Model
                        ->withPivot('accept_comms', 'accept_tracker');
        }
 
+       public function guesses() {
+               return $this->hasMany(GuessingGuess::class);
+       }
+
        public function organization() {
                return $this->belongsTo(Organization::class);
        }
@@ -34,6 +129,8 @@ class Channel extends Model
                'chat' => 'boolean',
                'chat_commands' => 'array',
                'chat_settings' => 'array',
+               'guessing_start' => 'datetime',
+               'guessing_end' => 'datetime',
                'languages' => 'array',
                'join' => 'boolean',
        ];