Working on Case2: New League Creation after Qualification

This commit is contained in:
Torsten 2017-11-02 16:41:07 +01:00
parent d8a7f78cbd
commit 66671b1e81
11 changed files with 12726 additions and 40 deletions

12506
d0274241_2017-11-02_1021.sql Normal file

File diff suppressed because it is too large Load diff

View file

@ -68,7 +68,6 @@ class LeaguesController extends Controller
public function createLeagues($start_round_id, $round_count) {
League::createLeagues($start_round_id, $round_count);
Log::info("LeaguesController::createLeagues completed.");
Match::createMatchups();

View file

@ -36,7 +36,7 @@ class UsersController extends Controller
$round_id = Round::getLastCompleteRoundId();
if ($round_id > -1) {
$rounds = Round::where("id", "<=", $round_id)->get();
$rounds = Round::where("id", "<=", $round_id)->where('season_id','=',$currentSeason->id)->get();
foreach($rounds as $round) {
$dpr =array();
$dpr["name"]=$round->name;
@ -189,6 +189,9 @@ class UsersController extends Controller
public function ranking($max_round_id, $seasonId=-1) {
if (!Auth::user()) { return redirect("/"); }
$startTime = microtime(true);
$season = Season::getCurrent();

View file

@ -36,6 +36,7 @@ class Round extends Model
public static function isCompleted($round_id) {
$round = Round::where('id','=',$round_id)->first();
$games = Game::where('round_id','=',$round->id)->get();
$completed = true;
foreach($games as $game) {
@ -46,8 +47,16 @@ class Round extends Model
return $completed;
}
public static function getLastCompleteRoundId() {
$season = Season::getCurrent();
public static function getLastCompleteRoundId($seasonId=-1) {
$season=null;
if ($seasonId==-1) {
$season = Season::getCurrent();
} else {
$season=Season::where('id','=',$seasonId)->first();
}
if (!$season) return -1;
$seasonId=$season->id;
$rounds=Round::where('season_id','=',$season->id)->orderBy('id')->get();
$lastCompleteRound=-1;
foreach ($rounds as $round) {
@ -58,22 +67,35 @@ class Round extends Model
return $lastCompleteRound;
}
public static function getFirstIncompleteRound() {
$season = Season::getCurrent();
if (!$season) return -1;
public static function getFirstIncompleteRound($seasonId=-1) {
$season=null;
if ($seasonId==-1) {
$season = Season::getCurrent();
} else {
$season = Season::where('id','=',$seasonId)->first();
}
$rounds = Round::where('season_id','=',$season->id)->orderBy('id')->get();
if (!$season) return -1;
$seasonId=$season->id;
$rounds = Round::where('season_id','=',$seasonId)->orderBy('id')->get();
foreach($rounds as $round) {
if (!Round::isCompleted($round->id)) return $round->id;
}
return -1;
}
public static function getNextRoundId($roundId) {
$currentSeason = Season::getCurrent();
public static function getNextRoundId($roundId, $seasonId=-1) {
$season=null;
if ($seasonId==-1) {
$currentSeason=Season::getCurrent();
} else {
$currentSeason=Season::where('id','=', $seasonId)->first();
}
if (!$currentSeason) return -1;
$seasonId = $currentSeason->id;
$rounds = Round::where('season_id','=',$currentSeason->id)->where('id','>=',$roundId)->get();
$rounds = Round::where('season_id','=',$seasonId)->where('id','>=',$roundId)->get();
foreach($rounds as $round) {
if ($round->id == $roundId) { continue; }
return $round->id;
@ -81,9 +103,15 @@ class Round extends Model
return -1;
}
public static function getLastLockedRoundId() {
$season = Season::getCurrent();
public static function getLastLockedRoundId($seasonId=-1) {
$season=null;
if ($seasonId==-1) {
$season=Season::getCurrent();
} else {
$season=Season::where('id','=', $seasonId)->first();
}
if (!$season) return -1;
$rounds=Round::where('season_id','=',$season->id)->orderBy('id')->get();
$lastLockedRoundId=-1;
foreach ($rounds as $round) {
@ -94,15 +122,29 @@ class Round extends Model
return $lastLockedRoundId;
}
public static function getFirstTippableRoundId() {
$round = Round::getFirstTippableRound();
public static function getFirstTippableRoundId($seasonId=-1) {
$season=null;
if ($seasonId==-1) {
$currentSeason=Season::getCurrent();
} else {
$currentSeason=Season::where('id','=', $seasonId)->first();
}
if (!$season) return null;
$round = Round::getFirstTippableRound($season->id);
if (!$round) return -1;
return $round->id;
}
public static function getFirstTippableRound() {
$season = Season::getCurrent();
public static function getFirstTippableRound($seasonId=-1) {
$season=null;
if ($seasonId==-1) {
$currentSeason=Season::getCurrent();
} else {
$currentSeason=Season::where('id','=', $seasonId)->first();
}
if (!$season) return null;
$rounds=Round::where('season_id','=',$season->id)->orderBy('id')->get();
$locked = false;
foreach ($rounds as $round) {
@ -113,6 +155,7 @@ class Round extends Model
return null;
}
// TODO: CHeck : Unused ??
public static function getClosestRoundToNow() {
$sql="select round_id,DATEDIFF(NOW(),kickoff) from games order by 2 desc limit 1;";
$result=DB::select($sql);
@ -154,10 +197,13 @@ class Round extends Model
}
public static function getNames($seasonId=-1) {
Log::info("Round::getNames for seasonId=".$seasonId);
$season= Season::getCurrent();
if ($seasonId!=-1) { $season = Season::where('id','=',$seasonId)->first(); }
$rounds = Round::where('season_id','=',$season->id)->get();
Log::info("Number of rounds:".sizeof($rounds));
Log::info("START");
$roundnames = array();
foreach($rounds as $round) {

View file

@ -2,11 +2,13 @@
namespace App;
use Carbon;
use Illuminate\Database\Eloquent\Model;
class Test extends Model
{
// In order for testing seasons to work, we need a way to set all the users to 'paid'
// this method is used by fillSeason method
public static function paySeason($seasonId)
{
$users = User::all();
@ -18,12 +20,18 @@ class Test extends Model
return $cnt." Users in season_id ".$seasonId." set to paid";
}
public static function fillSeason($seasonId) {
public static function fillSeason($seasonId=-1) {
error_log("creating all tipps started");
Tipp::createAllTips();
error_log("creating all tipps completed");
$users = User::all();
if ($seasonId==-1) {
$season = Season::getCurrent();
$seasonId = $season->id;
}
error_log("setting payment started");
Test::paySeason($seasonId);
error_log("setting payment completed");
@ -41,6 +49,7 @@ class Test extends Model
foreach ($games as $game) {
$game->score1=random_int(0,3);
$game->score2=random_int(0,3);
$game->kickoff= Carbon\Carbon::now();
$game->save();
foreach ($users as $user) {
// Tipps faken

View file

@ -245,10 +245,20 @@ class Tipp extends Model
// TODO: Implement partial caching
public static function getRoundTipps($max_round_id=-1) {
public static function getRoundTipps($max_round_id=-1, $seasonId=-1) {
$currentSeason=null;
if ($seasonId==null) {
$currentSeason = Season::getCurrent();
} else {
$currentSeason = Season::where('id','=', $seasonId)->first();
}
$startTime = microtime(true);
$currentSeason = Season::getCurrent();
if ($seasonId!=-1) { $currentSeason=Season::where('id','=',$seasonId)->first(); };
error_log("SeasonId=".$currentSeason->id);
// Hier werden _alle_ Tipps der aktuellen Saison ausgerechnet, die $round_id Begrenzung wird erst später ausgewertet.
// TODO: Nur die Runden durchrechnen, die aktuell sind, oder round_incomplete, alle anderen Runden (bis zur ersten unvollständigen) sollen in eine Cachetabelle gespeichert werden.
@ -271,10 +281,8 @@ class Tipp extends Model
$user_ids=array();
$round_ids=array();
// Write sql result to roundtipps (score per round & user)
if ($max_round_id==-1) { $max_round_id=Round::getLastCompleteRoundId(); }
if ($max_round_id==-1) { $max_round_id=Round::getLastCompleteRoundId($currentSeason->id); }
foreach ($result as $entry) {
$round_id = $entry->round_id;
if ($max_round_id >-1 && $round_id>$max_round_id) break;
@ -359,6 +367,7 @@ class Tipp extends Model
$userRankings = array();
foreach ($user_ids as $user_id) {
$key = $max_round_id."_".$user_id;
//error_log("Pushing:". $user_id." => ".$key);
array_push($userRankings, [$user_id , $roundtipps[$key]['totalRankScore']]);
}

View file

@ -136,7 +136,10 @@ class User extends Authenticatable
}
public static function hasMissingTipp($user_id) {
$round_id = Round::getFirstTippableRound()->id;
$round = Round::getFirstTippableRound();
if (!$round) return false;
$round_id = $round->id;
$games = Game::where('round_id','=',$round_id)->get();
foreach ($games as $game) {
@ -155,7 +158,10 @@ class User extends Authenticatable
}
public static function hasMissingJoker($user_id) {
$round_id = Round::getFirstTippableRound()->id;
$round=Round::getFirstTippableRound();
if (!$round) return false;
$round_id = $round->id;
$games = Game::where('round_id','=',$round_id." user_id=".$user_id)->get();
$joker=0;
foreach ($games as $game) {

View file

@ -8,6 +8,8 @@ use App\Season;
use App\Round;
use App\User;
use App\Leagues\LeagueMember;
use DB;
use Log;
@ -64,17 +66,26 @@ class League extends Model
public static function cmpScore($score1, $score2) {
// [0] = user-id
$_score1 = $score1[1];
// [4] = rank
$_score1 = $score1[1];
$goals1 = $score1[2];
$cGoals1 = $score1[3];
$rank1 = -1;
if (array_key_exists(4, $score1 )) { $rank1 = $score1[4]; }
$_score2 = $score2[1];
$_score2 = $score2[1];
$goals2 = $score2[2];
$cGoals2 = $score2[3];
$rank2 = -1;
if (array_key_exists(4, $score2 )) {$rank2 = $score2[4]; }
$diff1 = $goals1-$cGoals1;
$diff2 = $goals2-$cGoals2;
if ($rank1 < $rank2) return true;
if ($rank2 < $rank1) return false;
if ($_score1 == $_score2) {
if ($diff1==$diff2) {
if ($goals1 == $goals2) {
@ -131,6 +142,8 @@ class League extends Model
// Für Auf/Abstiegsberechnung - wird auf previous Season angewendet.
// Unified bezieht sich (nur) auf Gruppen-Übergreifende Listung (also alle Untergruppen)
// Rank = -1 bedeutet über alle Rank (benötigt für Auf- und Abstieg über alle Ligen)
public static function getUnifiedRanking($rank, $seasonId=-1) {
$leagueScores = League::getRanking($rank, $seasonId);
$unifiedScores = array();
@ -144,6 +157,29 @@ class League extends Model
return $unifiedScores;
}
// Nur für Auf und Abstieg
public static function getTotalRankingOverall($seasonId=-1) {
$totalRanking=array();
foreach([1,2,3,4] as $rank) {
foreach (League::getUnifiedRanking($rank, $seasonId) as $rankEntry) {
// Tuple: [0] = userId, [1] = league_score [2] = goals, [3] = counter_goals
$tpl = array();
$tpl[0] = $rankEntry[0];
$tpl[1] = $rankEntry[1];
$tpl[2] = $rankEntry[2];
$tpl[3] = $rankEntry[3];
$tpl[4] = $rank;
array_push($totalRanking, $tpl);
}
}
usort($totalRanking, array('App\Leagues\League','cmpScore'));
return $totalRanking;
}
// ausfaktoriert aus LeaguesController::createLeagues()
// TODO: $round_count ist nur im Quali-Modus relevant und steuert, wieviele Quali-Gruppen benötigt werden.
// TODO: Sobald es Liga1 und Liga2 gibt, wird der round_count immer 21 sein, da Liga1 und Liga2 auf
@ -166,7 +202,7 @@ class League extends Model
$active_member_count=sizeof(User::getActives());
Log::info("Aktive Spieler: ".$active_member_count);
$neededLeagues = League::neededLeagues($active_member_count, $round_count);
Log::info("Benötigte Quali-Gruppen: ".$neededLeagues);
Log::info("Benötigte Liga-Gruppen: ".$neededLeagues);
$league_ids=array();
@ -177,6 +213,7 @@ class League extends Model
// Alle Spieler werden gleichmässig auf Qualifikationsgruppen aufgeteilt
// Dieser Modus wird gewählt, wenn es keine Vorsaison gibt, es also
// die erste Saison im System ist.
Log::info("League::createLeagues => No previous season detected.");
for ($league_nr=1; $league_nr<=$neededLeagues; $league_nr+=1) {
$league = League::create([
'is_qualification' => true,
@ -204,7 +241,6 @@ class League extends Model
'league_id' => $league_ids[$league_index]
]);
$leagueMember->save();
$league_index+=1;
if (sizeof($league_ids)==$league_index) { $league_index=0; }
}
@ -217,6 +253,9 @@ class League extends Model
// - 4.) Member den Ligen zuordnen
// Erzeugung der Ligen
$createdLeagues=array();
$neededLeagues=0;
$league_size1= min(22,$active_member_count);
$league1 = League::create([
'is_qualification' => false,
@ -227,7 +266,7 @@ class League extends Model
'season_id' => $currentSeason->id,
'start_round_id' => $start_round_id
]);
array_push($createdLeagues, $league1);
$league_size2=min(22,$active_member_count - $league_size1);
if ($league_size2>0) {
@ -240,7 +279,7 @@ class League extends Model
'season_id' => $currentSeason->id,
'start_round_id' => $start_round_id
]);
array_push($createdLeagues, $league2);
$league_size3 = $active_member_count - $league_size1 - $league_size2;
if ($league_size3>0) {
@ -256,12 +295,58 @@ class League extends Model
'start_round_id' => $start_round_id
]);
$league->save();
array_push($createdLeagues,$league);
}
}
// TODO: LeagueMembers zu den Leagues hinzufügen, abhängig vom zuzuordnenden Platz
$unifiedList = League::getTotalRankingOverall($previousSeason->id);
$currentCount = 1;
//TODO: Auf- und Abstieg
Log::info("-- CREATED LEAGUES --");
foreach($createdLeagues as $createdLeague) {
Log::info("-> ".$createdLeague->id.") ".$createdLeague->name);
//TODO: Member erzeugen / zuordnen
}
$nr=1;
$leagueNr=1;
$neededSize3=0;
$subLeague=1; // for rank 3 leagues only
$leagueCount=1;
$leagueIndex=0;
Log::info("unified list size= ".sizeof($unifiedList));
foreach($unifiedList as $entry) {
if ($nr==23) { $leagueNr=2; $leagueCount=1; $leagueIndex=1; }
if ($nr==45) {
$leagueNr=3; $leagueCount=1; $leagueIndex=2;
$neededSize3=intdiv(($active_member_count-44),$neededLeagues); // $neededLeagues = needed Groups for rank 3 leagues
Log::info("Needed min/switch size for rank 3 leagues: ".$neededSize3);
}
if ($nr>45 && $leagueCount > $neededSize3) {
$subLeague+=1;
$leagueCount=1;
$leagueIndex+=1;
}
Log::info("#".$leagueCount." Liga ".$leagueNr."-".$subLeague.")".$nr." ".$entry[0]);
$league=$createdLeagues[$leagueIndex];
$leagueMember = LeagueMember::create([
'user_id' => $entry[0],
'league_id' => $league->id
]);
$leagueMember->save();
$leagueCount+=1;
$nr++;
}
}
}
}

View file

@ -32,4 +32,5 @@ class LeagueMember extends Model
return sizeof($matches2)>0;
}
}

View file

@ -32,15 +32,20 @@ class Match extends Model
$leagues = League::where('season_id', '=', $currentSeason->id)->get();
foreach ($leagues as $league) {
Log::info("Creating matchups for league_id=".$league->id);
// Wenn es keine previous League gibt, dann ist $league->rank immer RANK_QUALIFICATION,
// ansonsten ist es einer von RANK_LEAGUE1, RANK_LEAGUE2, RANK_LEAGUE3
Log::info("rank_id of league_id ".$league->id." = ".$league->rank);
if ($league->rank <= League::RANK_QUALIFICATION) {
$rounds = Round::where('id','>=',$league->start_round_id)->get();
$roundNr=1;
$neededRoundCount = Match::getNumberOfNeededRounds($league->id);
$allPairings=Match::getAllPairings($league->id, sizeof($rounds));
Log::info("Match::createMatchups( league_id=".$league->id.", numberOfrounds=".sizeof($rounds));
$allPairings=Match::getAllPairings($league->id);
foreach ($rounds as $round) {
$pairings = $allPairings[$roundNr];
@ -54,12 +59,13 @@ class Match extends Model
'user2_id' => $pair[1]
]);
$newMatch->save();
}
//Log::info("Saving match: league_id=".$league->id.", round_id=".$round->id.", ".$pair[0]." vs ".$pair[2]);
}
$roundNr += 1;
if ($roundNr > $neededRoundCount) break;
}
}
} else {Log::info("Skipped match creation because of unfitting rank=".$league->rank);}
}
}
@ -114,16 +120,22 @@ class Match extends Model
// Hier findet RoundRobin statt.
public static function getAllPairings($leagueId, $roundCount) {
public static function getAllPairings($leagueId) {
$members = LeagueMember::getMembers($leagueId);
$roundCount=sizeof($members)-1;
if (sizeof($members) % 2 == 1) { // ungerade memberzahl => freilos einfügen
error_log("Adding -1 free entry");
array_push($members,-1);
}
shuffle($members);
//error_log("Number of members:".sizeof($members));
error_log("Number of members:".sizeof($members));
$pairingCount = Match::getNumberOfPairingsPerRound($leagueId);
error_log("pairingCount=".$pairingCount);
$all = array();
for ($currentRoundNr=1; $currentRoundNr<= $roundCount; $currentRoundNr++) {
@ -133,8 +145,8 @@ class Match extends Model
array_push($roundRobin, $userId);
}
//error_log("RoundNr ".$currentRoundNr." Array start:");
//error_log(implode(",",$roundRobin));
error_log("RoundNr ".$currentRoundNr." Array start:");
error_log(implode(",",$roundRobin));
$_roundNr = $currentRoundNr;
while ($_roundNr >= 1) {
@ -165,8 +177,11 @@ class Match extends Model
// Matches die nur einen Teilnehmer haben entfernen. Passiert bei ungerader Teilnehmerzahl.
// Der nicht im Pairing befindliche Spieler hat einen spielfreien Tag.
//error_log(" Cleaning up Round pairings");
$pairings_clean=array();
//error_log(":".$pairings[0]);
foreach($pairings as $idx => $pairing) {
if ($pairing[0] == -1 || $pairing[1] == -1) {
//error_log("DONT ADD");
} else {
@ -209,10 +224,13 @@ class Match extends Model
}
public static function getMatchResults($leagueId, $maxRoundId=-1) {
$roundtipps = Tipp::getRoundTipps($maxRoundId);
$league=League::where('id','=',$leagueId)->first();
$season=Season::where('id','=',$league->season_id)->first();
$roundtipps = Tipp::getRoundTipps($maxRoundId, $season->id);
$roundtipps = $roundtipps["roundtipps"];
$matches = Match::getLeagueMatches($leagueId, $maxRoundId);
$season = Season::getCurrent();
if ($maxRoundId==-1) { $maxRoundId = Round::getLastRoundId($season->id); }

View file

@ -26,6 +26,10 @@
<div id="dropdown_league" class="dropdown-content">
<a style="font-weight:normal; font-color: blue; font-size: 22px;" href="/league_show_rounds/league_rank=4/round_id=30">Spielplan</a> &nbsp;
<a style="font-weight:normal; font-color: blue; font-size: 22px;" href="/league/show/rank=4/max_round_id=-1#playerid_{{Auth::user()->id}}">Tabellen</a> &nbsp;
<a style="font-weight:normal; font-color: blue; font-size: 22px;" href="/league/show/rank=1/max_round_id=-1#playerid_{{Auth::user()->id}}">Tabelle Liga 1</a> &nbsp;
<a style="font-weight:normal; font-color: blue; font-size: 22px;" href="/league/show/rank=2/max_round_id=-1#playerid_{{Auth::user()->id}}">Tabelle Liga 2</a> &nbsp;
<a style="font-weight:normal; font-color: blue; font-size: 22px;" href="/league/show/rank=3/max_round_id=-1#playerid_{{Auth::user()->id}}">Tabelle Liga 3</a> &nbsp;
</div>
</label>
&nbsp;