<?php
|
|
namespace App;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Log, DB;
|
|
|
|
class Mission extends Model
|
|
{
|
|
protected $fillable = [
|
|
'hashtag',
|
|
];
|
|
|
|
public function getRouteKeyName() {
|
|
return 'slug';
|
|
}
|
|
|
|
public function tweets() {
|
|
return $this->hasMany('App\Tweet');
|
|
}
|
|
|
|
private function unique_trimet_transit_lines(Team $team) {
|
|
static $cache = [];
|
|
if(array_key_exists($team->id, $cache))
|
|
return $cache[$team->id];
|
|
|
|
$tweets = Tweet::where('team_id', $team->id)
|
|
->where('m1_complete', 1)->whereNotNull('m1_transit_line_id')->get();
|
|
|
|
$lines = [];
|
|
foreach($tweets as $tweet) {
|
|
if($tweet->m1_transit_line_id && !in_array($tweet->m1_transit_line_id, $lines)) {
|
|
$lines[] = $tweet->m1_transit_line_id;
|
|
}
|
|
}
|
|
|
|
$cache[$team->id] = count($lines);
|
|
return count($lines);
|
|
}
|
|
|
|
private function unique_transit_centers(Team $team, $with_another_team=false) {
|
|
static $cache = ['with'=>[], 'without'=>[]];
|
|
if(array_key_exists($team->id, $cache[$with_another_team?'with':'without']))
|
|
return $cache[$with_another_team?'with':'without'][$team->id];
|
|
|
|
$query = Tweet::where('team_id', $team->id)->where('m2_complete', 1);
|
|
if($with_another_team)
|
|
$query = $query->where('m2_with_other_team', 1);
|
|
$tweets = $query->get();
|
|
|
|
$centers = [];
|
|
foreach($tweets as $tweet) {
|
|
if($tweet->m2_transit_center_id && !in_array($tweet->m2_transit_center_id, $centers)) {
|
|
$centers[] = $tweet->m2_transit_center_id;
|
|
}
|
|
}
|
|
|
|
$cache[$with_another_team?'with':'without'][$team->id] = count($centers);
|
|
return count($centers);
|
|
}
|
|
|
|
private function unique_documents(Team $team) {
|
|
static $cache = [];
|
|
if(array_key_exists($team->id, $cache))
|
|
return $cache[$team->id];
|
|
|
|
$tweets = Tweet::where('team_id', $team->id)->whereNotNull('m7_document_id')->get();
|
|
$documents = [];
|
|
foreach($tweets as $tweet) {
|
|
if($tweet->m7_document_id && !in_array($tweet->m7_document_id, $documents)) {
|
|
$documents[] = $tweet->m7_document_id;
|
|
}
|
|
}
|
|
|
|
$cache[$team->id] = count($documents);
|
|
return count($documents);
|
|
}
|
|
|
|
private function num_tweets_for_mission(Team $team, $m) {
|
|
static $cache = [3=>[], 4=>[], 5=>[], 6=>[]];
|
|
if(array_key_exists($team->id, $cache[$m]))
|
|
return $cache[$m][$team->id];
|
|
|
|
$num = Tweet::where('team_id', $team->id)->where('m'.$m.'_complete', 1)->count();
|
|
$cache[$m][$team->id] = $num;
|
|
return $num;
|
|
}
|
|
|
|
public function complete(Team $team) {
|
|
switch($this->id) {
|
|
case 1:
|
|
// 5 unique trimet transit lines
|
|
return $this->unique_trimet_transit_lines($team) >= 5;
|
|
case 2:
|
|
// 3 unique transit centers
|
|
return $this->unique_transit_centers($team) >= 3;
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
return $this->num_tweets_for_mission($team, $this->id) >= 1;
|
|
case 7:
|
|
return $this->unique_documents($team) >= 3;
|
|
}
|
|
}
|
|
|
|
public function progress(Team $team) {
|
|
switch($this->id) {
|
|
case 1:
|
|
return [$this->unique_trimet_transit_lines($team), 5];
|
|
case 2:
|
|
return [$this->unique_transit_centers($team), 3];
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
return [$this->num_tweets_for_mission($team, $this->id), 1];
|
|
case 7:
|
|
return [$this->unique_documents($team), 3];
|
|
}
|
|
return [false,false];
|
|
}
|
|
|
|
public function score(Team $team) {
|
|
switch($this->id) {
|
|
case 1:
|
|
// No points unless they hit 5 trimet transit lines
|
|
if($this->complete($team)) {
|
|
$score = 50;
|
|
// 20 bonus for each line that is not trimet
|
|
$tweets = Tweet::where('team_id', $team->id)->where('m1_complete', 1)->whereNotNull('m1_non_trimet')->get();
|
|
$lines = [];
|
|
foreach($tweets as $tweet) {
|
|
if(!in_array($tweet->m1_non_trimet, $lines)) {
|
|
$lines[] = $tweet->m1_non_trimet;
|
|
}
|
|
}
|
|
$score += count($lines) * 20;
|
|
return $score;
|
|
} else {
|
|
return 0;
|
|
}
|
|
break;
|
|
case 2:
|
|
// No points unless they hit 3 transit centers
|
|
if($this->complete($team)) {
|
|
$score = 50;
|
|
// If they have more than 3 unique transit centers,
|
|
// then award bonus points for any beyond the third with another team
|
|
$unique_transit_centers = $this->unique_transit_centers($team);
|
|
if($unique_transit_centers > 3) {
|
|
// Take the total number of transit centers and subtract 3
|
|
$total_possible_bonus = $unique_transit_centers - 3;
|
|
// Find the number of unique transit centers with another team
|
|
$unique_with_another_team = $this->unique_transit_centers($team, true);
|
|
// Use the smaller of the two numbers as the bonus
|
|
$score += 20 * min($total_possible_bonus, $unique_with_another_team);
|
|
}
|
|
|
|
// Increasing bonus points for additional transit centers
|
|
if($unique_transit_centers >= 4) {
|
|
$score += 10;
|
|
}
|
|
if($unique_transit_centers >= 5) {
|
|
$score += 20;
|
|
}
|
|
if($unique_transit_centers >= 6) {
|
|
$score += 30;
|
|
}
|
|
if($unique_transit_centers >= 7) {
|
|
$score += (50 * ($unique_transit_centers - 6));
|
|
}
|
|
|
|
// Double points for each transit center that no other team goes to
|
|
$this_team_tcs = Tweet::where('team_id', $team->id)->where('m2_complete', 1)
|
|
->distinct()->pluck('m2_transit_center_id')->toArray();
|
|
$other_visited_tcs = Tweet::where('team_id', '!=', $team->id)->where('m2_complete', 1)
|
|
->distinct()->pluck('m2_transit_center_id')->toArray();
|
|
$distinct_tcs = array_diff($this_team_tcs, $other_visited_tcs);
|
|
|
|
if(count($distinct_tcs) > 0) {
|
|
$score *= 2;
|
|
}
|
|
|
|
return $score;
|
|
} else {
|
|
return 0;
|
|
}
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
case 6:
|
|
if($this->complete($team)) {
|
|
return 50;
|
|
} else {
|
|
return 0;
|
|
}
|
|
case 5:
|
|
if($this->complete($team)) {
|
|
$score = 50;
|
|
|
|
// +10 if any of their photos are tipping the bus driver
|
|
$num = Tweet::where('team_id', $team->id)->where('m5_complete', 1)->where('m5_tip', 1)->count();
|
|
if($num > 0)
|
|
$score += 10;
|
|
|
|
return $score;
|
|
} else {
|
|
return 0;
|
|
}
|
|
case 7:
|
|
if($this->complete($team)) {
|
|
$score = 50;
|
|
// +5 for each additional photo
|
|
$extra_docs = $this->unique_documents($team) - 3;
|
|
if($extra_docs > 0) {
|
|
$score += $extra_docs * 5;
|
|
}
|
|
// add bonus points for certain documents
|
|
$tweets = DB::table('tweets')->select('m7_document_id', 'm7_documents.points')
|
|
->where('team_id', $team->id)
|
|
->join('m7_documents', 'm7_documents.id', '=', 'tweets.m7_document_id')
|
|
->whereNotNull('m7_document_id')
|
|
->distinct()->get();
|
|
foreach($tweets as $tweet) {
|
|
$score += $tweet->points;
|
|
}
|
|
return $score;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|