Skip to content

Instantly share code, notes, and snippets.

Created March 7, 2018 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/89f1eb7668a056e593b66a6f62390c7c to your computer and use it in GitHub Desktop.
Save anonymous/89f1eb7668a056e593b66a6f62390c7c to your computer and use it in GitHub Desktop.
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