Created
March 7, 2018 10:45
-
-
Save anonymous/89f1eb7668a056e593b66a6f62390c7c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using ProPoolAPI.Data; | |
using ProPoolAPI.Enums; | |
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel.DataAnnotations.Schema; | |
using System.Linq; | |
using System.Web; | |
namespace ProPoolAPI.Entities | |
{ | |
[Table("SingleKnockoutTournaments")] | |
public class SingleKnockoutTournament : KnockoutTournament | |
{ | |
public override void Initialize(ApplicationDbContext dbContext, User loggedInOwner) | |
{ | |
if(this.Rounds.Count > 0) | |
{ | |
//throw new Exception("This tournament is already started"); | |
} | |
this.Status = TournamentStatus.Started; | |
// Prepare | |
int nrOfPlayers = this.Users.Count; | |
int maxSchemaPlayers = (MaxPlayers == 0) ? GetNextPowerOfTwo(nrOfPlayers) : MaxPlayers; // Todo: For scaling up if no max is provided | |
var width = GetWidth(maxSchemaPlayers); | |
// Calculate total amount of matches | |
var amountToAdd = 1; | |
int nrOfTotalMatches = 0; | |
for (var i = 1; i <= width; i++) | |
{ | |
nrOfTotalMatches += amountToAdd; | |
amountToAdd *= 2; | |
} | |
// Generate rounds/matches | |
var nrOfMatches = nrOfTotalMatches; | |
var matchNumber = 1; | |
for (var round = 1; round <= width; round++) | |
{ | |
// Round | |
var tournamentRound = new SingleKnockoutRound(); | |
tournamentRound.Round = round; | |
tournamentRound.BreakType = this.BreakType; | |
tournamentRound.Race = this.Race; | |
tournamentRound.Tournament = this; | |
tournamentRound.Matches = new List<TournamentMatch>(); | |
this.Rounds.Add(tournamentRound); | |
dbContext.SaveChanges(); | |
for (var m = 0; m < nrOfMatches; m++) | |
{ | |
// TournamentMatch | |
var tournamentMatch = new TournamentMatch(); | |
tournamentMatch.Number = matchNumber; | |
dbContext.TournamentMatches.Add(tournamentMatch); | |
tournamentRound.Matches.Add(tournamentMatch); | |
// Roel: This line is giving the error | |
// I'm calling SaveChanges multiple times now to detect where the problem is | |
dbContext.SaveChanges(); | |
// Match | |
var match = new Match(); | |
match.StartDate = DateTime.Now; | |
match.Discipline = this.Discipline; | |
match.Race = tournamentRound.Race; | |
dbContext.Matches.Add(match); | |
tournamentMatch.Match = match; | |
dbContext.SaveChanges(); | |
matchNumber++; | |
} | |
nrOfMatches /= 2; | |
} | |
//dbContext.SaveChanges(); | |
// Assign winner/previous matches | |
for (var roundIndex = width -1; roundIndex >= 1; roundIndex--) | |
{ | |
var round = this.Rounds[roundIndex]; | |
for (var m = 0; m < round.Matches.Count; m++) | |
{ | |
var tournamentMatch = round.Matches[m]; | |
// Winner match | |
if(roundIndex != 0) | |
{ | |
tournamentMatch.WinnerMatch = this.Rounds[roundIndex - 1].Matches[m / 2]; | |
} | |
else | |
{ | |
tournamentMatch.PreviousMatch1 = this.Rounds[1].Matches[0]; | |
tournamentMatch.PreviousMatch2 = this.Rounds[1].Matches[1]; | |
} | |
// Previous match | |
if (tournamentMatch.WinnerMatch != null) | |
{ | |
if (tournamentMatch.WinnerMatch.PreviousMatch1 != null) | |
{ | |
tournamentMatch.WinnerMatch.PreviousMatch1 = tournamentMatch; | |
} | |
else | |
{ | |
tournamentMatch.WinnerMatch.PreviousMatch2 = tournamentMatch; | |
} | |
} | |
} | |
} | |
//dbContext.SaveChanges(); | |
// Bug: Het probleem is dat hij met State == Added alsnog de volgorde niet goed doet. | |
// Maar het is nodig omdat je anders errors krijgt. | |
// Reverse rounds | |
//tempRounds.Reverse(); | |
// Shuffle users - Otherwise signing in later could result in a "bye" | |
Random r = new Random(); | |
Users.Sort((a, b) => | |
{ | |
return r.Next(0, 1); | |
}); | |
// Link players | |
var matchCounter = 0; | |
var userCounter = 0; | |
// First half (players) | |
for (; userCounter < Users.Count / 2; userCounter++) | |
{ | |
var user = Users[userCounter]; | |
Rounds[0].Matches[matchCounter].Match.Challenger = user; | |
matchCounter++; | |
} | |
// Second half (players) | |
matchCounter = 0; | |
for (; userCounter < Users.Count; userCounter++) | |
{ | |
var user = Users[userCounter]; | |
Rounds[0].Matches[matchCounter].Match.Challenged = user; | |
matchCounter++; | |
} | |
dbContext.SaveChanges(); | |
// Assign bye's | |
//var firstRound = Rounds[0]; | |
//for (var ma = 0; ma < firstRound.Matches.Count; ma++) | |
//{ | |
// var tournamentMatch = firstRound.Matches[ma]; | |
// var match = tournamentMatch.Match; | |
// if (match.Challenger == null || match.Challenged == null) | |
// { | |
// tournamentMatch.IsBye = true; | |
// tournamentMatch.Complete(dbContext, loggedInOwner); | |
// } | |
//} | |
} | |
private int GetWidth(int amountOfPlayers) | |
{ | |
var width = 0; | |
while (amountOfPlayers > 1) | |
{ | |
amountOfPlayers /= 2; | |
width++; | |
} | |
return width; | |
} | |
private int GetNextPowerOfTwo(int nr) | |
{ | |
nr--; | |
nr |= nr >> 1; | |
nr |= nr >> 2; | |
nr |= nr >> 4; | |
nr |= nr >> 8; | |
nr |= nr >> 16; | |
nr++; | |
return nr; | |
} | |
// Todo: Move to TournamentRound | |
public override void InitializeRound(ApplicationDbContext dbContext, int roundId, BreakType breakType, int race) | |
{ | |
var round = this.Rounds.SingleOrDefault(r => r.Id.Equals(roundId)); | |
if(round == null) | |
{ | |
throw new ArgumentNullException(); | |
} | |
foreach(TournamentMatch tournamentMatch in round.Matches) | |
{ | |
var match = tournamentMatch.Match; | |
match.Race = race; | |
dbContext.Entry(match).State = System.Data.Entity.EntityState.Modified; | |
} | |
round.Race = race; | |
round.BreakType = breakType; | |
dbContext.Entry(round).State = System.Data.Entity.EntityState.Modified; | |
dbContext.SaveChanges(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment