public async Task <IActionResult> PairRoundMatchupEdit(int id, [Bind("Id,RoundNo,PlayerOneId,PlayerTwoId,PlayerThreeId,PlayerFourId,PlayerOneBattleScore,PlayerTwoBattleScore,PlayerThreeBattleScore,PlayerFourBattleScore,PlayerOneSportsmanshipScore,PlayerTwoSportsmanshipScore,PlayerThreeSportsmanshipScore,PlayerFourSportsmanshipScore,Table")] PairRoundMatchupEditViewModel pairRoundMatchupvm) { if (id != pairRoundMatchupvm.Id) { return(NotFound()); } var playerOne = await _context.Players.SingleOrDefaultAsync(p => p.Id == pairRoundMatchupvm.PlayerOneId); var playerTwo = await _context.Players.SingleOrDefaultAsync(p => p.Id == pairRoundMatchupvm.PlayerTwoId); var playerThree = await _context.Players.SingleOrDefaultAsync(p => p.Id == pairRoundMatchupvm.PlayerThreeId); var playerFour = await _context.Players.SingleOrDefaultAsync(p => p.Id == pairRoundMatchupvm.PlayerFourId); var roundMatchup = new PairRoundMatchup() { Id = pairRoundMatchupvm.Id, RoundNo = pairRoundMatchupvm.RoundNo, PlayerOne = playerOne, PlayerOneBattleScore = pairRoundMatchupvm.PlayerOneBattleScore, PlayerOneSportsmanshipScore = pairRoundMatchupvm.PlayerOneSportsmanshipScore, PlayerTwo = playerTwo, PlayerTwoBattleScore = pairRoundMatchupvm.PlayerTwoBattleScore, PlayerTwoSportsmanshipScore = pairRoundMatchupvm.PlayerTwoSportsmanshipScore, PlayerThree = playerThree, PlayerThreeBattleScore = pairRoundMatchupvm.PlayerThreeBattleScore, PlayerThreeSportsmanshipScore = pairRoundMatchupvm.PlayerThreeSportsmanshipScore, PlayerFour = playerFour, PlayerFourBattleScore = pairRoundMatchupvm.PlayerFourBattleScore, PlayerFourSportsmanshipScore = pairRoundMatchupvm.PlayerFourSportsmanshipScore, Table = pairRoundMatchupvm.Table }; if (ModelState.IsValid) { try { _context.Update(roundMatchup); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!RoundMatchupActions.RoundMatchupsExists(roundMatchup.Id, _context)) { return(NotFound()); } else { throw; } } return(RedirectToAction(nameof(AllRounds))); } return(View(pairRoundMatchupvm)); }
public async Task <IActionResult> Edit(int id, [Bind("Id,PlayerOneId,PlayerTwoId,PlayerThreeId,PlayerFourId,CurrentRound")] AdminEditRoundMatchupsViewModel roundMatchup) { if (id != roundMatchup.Id) { return(NotFound()); } PairRoundMatchup updatedPairRoundMatchup = null; RoundMatchup updatedRoundMatchup = null; if (_context.RoundMatchups.Find(id) is PairRoundMatchup) { updatedPairRoundMatchup = _context.RoundMatchups.Find(id) as PairRoundMatchup; updatedPairRoundMatchup.PlayerOne = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerOneId); updatedPairRoundMatchup.PlayerTwo = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerTwoId); updatedPairRoundMatchup.PlayerThree = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerThreeId); updatedPairRoundMatchup.PlayerFour = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerFourId); } else { updatedRoundMatchup = _context.RoundMatchups.Find(id); updatedRoundMatchup.PlayerOne = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerOneId); updatedRoundMatchup.PlayerTwo = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerTwoId); } if (ModelState.IsValid) { try { if (updatedPairRoundMatchup != null) { _context.Update(updatedPairRoundMatchup); } else { _context.Update(updatedRoundMatchup); } await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!RoundMatchupActions.RoundMatchupsExists(roundMatchup.Id, _context)) { return(NotFound()); } else { throw; } } return(RedirectToAction(nameof(Index))); } return(View(roundMatchup)); }
/** * * Validation * **/ //Get the errors for all roundMatchups, including any players on a team with themself or versing themself, any players //who have played the same opponent more than once, any players who have not played in every round and any players who have //played twice in one round public static List <List <string> > GetRoundMatchupErrors(TournamentDbContext _context) { var roundMatchups = _context.RoundMatchups.Include(r => r.PlayerOne).Include(r => r.PlayerTwo).OrderByDescending(r => r.PlayerOne.BattleScore).ToList(); List <string> duplicatePlayers = new List <string>(); List <string> duplicateOpponents = new List <string>(); List <string> unallocatedPlayers = new List <string>(); List <string> overallocatedPlayers = new List <string>(); Dictionary <string, int> playerRoundCount = new Dictionary <string, int>(); List <Player> players = _context.Players.ToList(); foreach (Player player in players) { playerRoundCount.Add(player.Name, 0); } List <String> tempDuplicatePlayers = new List <string>(); foreach (RoundMatchup roundMatchup in roundMatchups) { if (roundMatchup is PairRoundMatchup) { var pairRoundMatchup = roundMatchup as PairRoundMatchup; // Check if PlayerOne is on a team with themself if (pairRoundMatchup.PlayerOne == pairRoundMatchup.PlayerTwo) { duplicatePlayers.Add(pairRoundMatchup.PlayerOne.Name + " is on a team with themself in round " + pairRoundMatchup.RoundNo); } // Check if PlayerOne is playing themself if (pairRoundMatchup.PlayerOne == pairRoundMatchup.PlayerThree || pairRoundMatchup.PlayerOne == pairRoundMatchup.PlayerFour) { duplicatePlayers.Add(pairRoundMatchup.PlayerOne.Name + " is playing themself in round " + pairRoundMatchup.RoundNo); } //Check if PlayerTwo is playing themself if (pairRoundMatchup.PlayerTwo == pairRoundMatchup.PlayerThree || pairRoundMatchup.PlayerTwo == pairRoundMatchup.PlayerFour) { duplicatePlayers.Add(pairRoundMatchup.PlayerTwo.Name + " is playing themself in round " + pairRoundMatchup.RoundNo); } //Check if PlayerThree is on a team with themself if (pairRoundMatchup.PlayerThree == pairRoundMatchup.PlayerFour) { duplicatePlayers.Add(pairRoundMatchup.PlayerThree.Name + " is on a team with themself in round " + pairRoundMatchup.RoundNo); } } //Check if there are any players versing themselves else if (!(roundMatchup is PairRoundMatchup)) { if (roundMatchup.PlayerOne == roundMatchup.PlayerTwo) { duplicatePlayers.Add(roundMatchup.PlayerOne.Name + " is playing themself in round " + roundMatchup.RoundNo); } } //Check if there are players who either do not play at all or play more than once foreach (Player player in _context.Players) { if (player.Id == roundMatchup.PlayerOne.Id) { playerRoundCount[player.Name] += 1; } if (player.Id == roundMatchup.PlayerTwo.Id) { playerRoundCount[player.Name] += 1; } if (roundMatchup is PairRoundMatchup) { PairRoundMatchup pairRoundMatchup = roundMatchup as PairRoundMatchup; if (player.Id == pairRoundMatchup.PlayerThree.Id) { playerRoundCount[player.Name] += 1; } if (player.Id == pairRoundMatchup.PlayerFour.Id) { playerRoundCount[player.Name] += 1; } } } } int roundCount = GetLastRoundNo(_context); foreach (KeyValuePair <string, int> entry in playerRoundCount) { if (entry.Value > roundCount) { overallocatedPlayers.Add(entry.Key + " has been allocated to " + entry.Value + " matchups with only " + roundCount + " rounds played"); } if (entry.Value < roundCount) { unallocatedPlayers.Add(entry.Key + " has only been allocated to " + entry.Value + " matchup/s when " + roundCount + " have been played"); } } Dictionary <Player, List <string> > duplicateOpponentsDictionary = new Dictionary <Player, List <string> >(); foreach (Player player in players) { List <Player> opponents = PlayerActions.GetAllOpponents(player, _context); List <string> duplicateNames = opponents .GroupBy(i => i) .Where(g => g.Count() > 1) .Select(g => g.Key.Name) .ToList(); duplicateOpponentsDictionary[player] = duplicateNames; } foreach (var duplicateOpponentSet in duplicateOpponentsDictionary) { string duplicateOpponentFormattedNameList = string.Join(", ", duplicateOpponentSet.Value); if (duplicateOpponentSet.Value.Count != 0) { duplicateOpponents.Add(duplicateOpponentSet.Key.Name + " has played " + duplicateOpponentFormattedNameList + " at least twice"); } } var errors = new List <List <string> >() { duplicatePlayers, duplicateOpponents, overallocatedPlayers, unallocatedPlayers }; return(errors); }
public static void GenerateNextPairRound(TournamentDbContext _context) { int lastRound = GetLastRoundNo(_context); List <RoundMatchup> roundMatchups = _context.RoundMatchups.Include(r => r.PlayerOne).Include(r => r.PlayerTwo).Where(r => r.RoundNo == lastRound).ToList(); List <PlayerPair> playerPairs = new List <PlayerPair>(); foreach (RoundMatchup roundMatchup in roundMatchups) { PlayerPair pair = new PlayerPair() { First = roundMatchup.PlayerOne, Second = roundMatchup.PlayerTwo }; playerPairs.Add(pair); } //List<int> AllocatedTables = new List<int>(GetnoOfTables()); int secondaryIndex = 0; int i = 0; while (i < playerPairs.Count) { //Skip this player if they are already allocated an opponent if (playerPairs[i].CurrentOpponent == null) { if (secondaryIndex == 0) { secondaryIndex = i + 1; } int s = 0; for (s = secondaryIndex; s < playerPairs.Count; s++) { if (playerPairs[s].CurrentOpponent == null) { //Check if higher player has ever played lower player var playerOneOpponents = PlayerActions.GetAllOpponents(playerPairs[i].First, _context); var playerTwoOpponents = PlayerActions.GetAllOpponents(playerPairs[i].Second, _context); var opponents = playerOneOpponents.Union(playerTwoOpponents); var hasPlayed = false; foreach (Player opponent in opponents) { if (playerPairs[s].First == opponent || playerPairs[s].Second == opponent) { hasPlayed = true; } } //If they have not played allocate them as opponents if (hasPlayed == false) { playerPairs[i].CurrentOpponent = playerPairs[s]; playerPairs[s].CurrentOpponent = playerPairs[i]; secondaryIndex = 0; break; } /** * Following block is to deallocate the next lowest ranked allocated pair **/ if (playerPairs.Where(p => p.CurrentOpponent == null).LastOrDefault() == playerPairs[s] && (playerPairs[i].CurrentOpponent == null)) //if (s == (players.Count - 1) && (players[i].CurrentOpponent == null)) { if (i - 1 >= 0) { //Set the lowestAllocatedPair to the highest ranked pair PlayerPair lowestAllocatedPair = playerPairs[0]; //Iterate from the second highest ranked pair all the way to the pair ranked one higher than the player currently being matched for (int playerIndex = 1; playerIndex < i; playerIndex++) { //Assign the current player to the player being examined in the current iteration of the loop PlayerPair currentPair = playerPairs[playerIndex]; //Check that the current player has an opponent (if not, skip to the next iteration of the loop) if (currentPair.CurrentOpponent != null) { //Proceed if the current player's opponent has a higher rank than the current player if (playerPairs.IndexOf(currentPair.CurrentOpponent) < playerPairs.IndexOf(currentPair)) { if (playerPairs.IndexOf(currentPair.CurrentOpponent) > playerPairs.IndexOf(lowestAllocatedPair)) { //Set lowestAllocatedPair to the current player's opponent //(The highest ranked member of the new lowest ranked allocated pair) lowestAllocatedPair = currentPair.CurrentOpponent; } } //Proceed if the current player has a higher rank than their opponent else if (playerPairs.IndexOf(currentPair) < playerPairs.IndexOf(currentPair.CurrentOpponent)) { //Proceed if the current player has a lower rank than the previous value of lowestAllocatedPair if (playerPairs.IndexOf(currentPair) > playerPairs.IndexOf(lowestAllocatedPair)) { //Set lowestAllocatedPair to the current player //(The highest ranked member of the new lowest ranked allocated pair) lowestAllocatedPair = currentPair; } } } } //Set the new player to be allocated to the highest member of the lowestAllocatedPair i = playerPairs.IndexOf(lowestAllocatedPair) - 1; //Set the starting player that will be tested for allocation suitability to one rank lower than //the opponent of the highest member of the allocated pair secondaryIndex = playerPairs.IndexOf(lowestAllocatedPair.CurrentOpponent) + 1; //Deallocate the lowest allocated pair as each other's opponent lowestAllocatedPair.CurrentOpponent.CurrentOpponent = null; lowestAllocatedPair.CurrentOpponent = null; } } } } } i++; } int newRound = lastRound + 1; foreach (PlayerPair playerPair in playerPairs) { if (playerPairs.IndexOf(playerPair) < playerPairs.IndexOf(playerPair.CurrentOpponent)) { PairRoundMatchup roundMatchup = new PairRoundMatchup { RoundNo = newRound, PlayerOne = playerPair.First, PlayerTwo = playerPair.Second, PlayerThree = playerPair.CurrentOpponent.First, PlayerFour = playerPair.CurrentOpponent.Second }; //allocates table for matchup //roundMatchup.Table = AllocateTable(GetTables(player), AllocatedTables); _context.Add(roundMatchup); } } _context.SaveChanges(); }
public async Task <IActionResult> PairRoundMatchupEdit(int id, [Bind("Id,RoundNo,PlayerOneId,PlayerTwoId,PlayerThreeId,PlayerFourId,PlayerOneBattleScore,PlayerTwoBattleScore,PlayerThreeBattleScore,PlayerFourBattleScore,PlayerOneSportsmanshipScore,PlayerTwoSportsmanshipScore,PlayerThreeSportsmanshipScore,PlayerFourSportsmanshipScore,Table")] PairRoundMatchupEditViewModel pairRoundMatchupvm) { if (id != pairRoundMatchupvm.Id) { return(NotFound()); } //Check if a player is versing themself or on a team with themself if (pairRoundMatchupvm.PlayerOneId == pairRoundMatchupvm.PlayerTwoId || pairRoundMatchupvm.PlayerOneId == pairRoundMatchupvm.PlayerThreeId || pairRoundMatchupvm.PlayerOneId == pairRoundMatchupvm.PlayerFourId || pairRoundMatchupvm.PlayerTwoId == pairRoundMatchupvm.PlayerThreeId || pairRoundMatchupvm.PlayerTwoId == pairRoundMatchupvm.PlayerFourId || pairRoundMatchupvm.PlayerThreeId == pairRoundMatchupvm.PlayerFourId) { TempData["Errors"] = "A player cannot verse themself or be on a team with themself"; pairRoundMatchupvm.Players = _context.Players.ToList(); return(View(pairRoundMatchupvm)); } var playerOne = await _context.Players.SingleOrDefaultAsync(p => p.Id == pairRoundMatchupvm.PlayerOneId); var playerTwo = await _context.Players.SingleOrDefaultAsync(p => p.Id == pairRoundMatchupvm.PlayerTwoId); var playerThree = await _context.Players.SingleOrDefaultAsync(p => p.Id == pairRoundMatchupvm.PlayerThreeId); var playerFour = await _context.Players.SingleOrDefaultAsync(p => p.Id == pairRoundMatchupvm.PlayerFourId); var roundMatchup = new PairRoundMatchup() { Id = pairRoundMatchupvm.Id, RoundNo = pairRoundMatchupvm.RoundNo, PlayerOne = playerOne, PlayerOneBattleScore = pairRoundMatchupvm.PlayerOneBattleScore, PlayerOneSportsmanshipScore = pairRoundMatchupvm.PlayerOneSportsmanshipScore, PlayerTwo = playerTwo, PlayerTwoBattleScore = pairRoundMatchupvm.PlayerTwoBattleScore, PlayerTwoSportsmanshipScore = pairRoundMatchupvm.PlayerTwoSportsmanshipScore, PlayerThree = playerThree, PlayerThreeBattleScore = pairRoundMatchupvm.PlayerThreeBattleScore, PlayerThreeSportsmanshipScore = pairRoundMatchupvm.PlayerThreeSportsmanshipScore, PlayerFour = playerFour, PlayerFourBattleScore = pairRoundMatchupvm.PlayerFourBattleScore, PlayerFourSportsmanshipScore = pairRoundMatchupvm.PlayerFourSportsmanshipScore, Table = pairRoundMatchupvm.Table }; if (ModelState.IsValid) { try { _context.Update(roundMatchup); await _context.SaveChangesAsync(); if (playerOne != null) { PlayerActions.SetPlayerScores((int)pairRoundMatchupvm.PlayerOneId, _context); } if (playerTwo != null) { PlayerActions.SetPlayerScores((int)pairRoundMatchupvm.PlayerTwoId, _context); } if (playerThree != null) { PlayerActions.SetPlayerScores((int)pairRoundMatchupvm.PlayerThreeId, _context); } if (playerFour != null) { PlayerActions.SetPlayerScores((int)pairRoundMatchupvm.PlayerFourId, _context); } } catch (DbUpdateConcurrencyException) { if (!RoundMatchupActions.RoundMatchupsExists(roundMatchup.Id, _context)) { return(NotFound()); } else { throw; } } return(RedirectToAction(nameof(AllRounds))); } pairRoundMatchupvm.Players = _context.Players.ToList(); return(View(pairRoundMatchupvm)); }
public async Task <IActionResult> Edit(int id, [Bind("Id,PlayerOneId,PlayerTwoId,PlayerThreeId,PlayerFourId,CurrentRound")] AdminEditRoundMatchupsViewModel roundMatchup) { if (id != roundMatchup.Id) { return(NotFound()); } //Check if a player is versing themself or on a team with themself in a standard round if (roundMatchup.PlayerThreeId == 0.5 && roundMatchup.PlayerFourId == 0.5) { if (roundMatchup.PlayerOneId == roundMatchup.PlayerTwoId) { TempData["Errors"] = "A player cannot verse themself or be on a team with themself"; roundMatchup.Players = _context.Players.ToList(); return(View(roundMatchup)); } } //Check if a player is versing themself or on a team with themself in a pair round else if (roundMatchup.PlayerOneId == roundMatchup.PlayerTwoId || roundMatchup.PlayerOneId == roundMatchup.PlayerThreeId || roundMatchup.PlayerOneId == roundMatchup.PlayerFourId || roundMatchup.PlayerTwoId == roundMatchup.PlayerThreeId || roundMatchup.PlayerTwoId == roundMatchup.PlayerFourId || roundMatchup.PlayerThreeId == roundMatchup.PlayerFourId) { TempData["Errors"] = "A player cannot verse themself or be on a team with themself"; roundMatchup.Players = _context.Players.ToList(); return(View(roundMatchup)); } PairRoundMatchup updatedPairRoundMatchup = null; RoundMatchup updatedRoundMatchup = null; if (_context.RoundMatchups.Find(id) is PairRoundMatchup) { updatedPairRoundMatchup = _context.RoundMatchups.Include(p => p.PlayerOne).Include(p => p.PlayerTwo).SingleOrDefault(r => r.Id == id) as PairRoundMatchup; updatedPairRoundMatchup.PlayerOne = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerOneId); updatedPairRoundMatchup.PlayerTwo = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerTwoId); updatedPairRoundMatchup.PlayerThree = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerThreeId); updatedPairRoundMatchup.PlayerFour = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerFourId); updatedPairRoundMatchup.Table = roundMatchup.TableNo; } else { updatedRoundMatchup = _context.RoundMatchups.Include(p => p.PlayerOne).Include(p => p.PlayerTwo).SingleOrDefault(r => r.Id == id); updatedRoundMatchup.PlayerOne = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerOneId); updatedRoundMatchup.PlayerTwo = _context.Players.FirstOrDefault(p => p.Id == roundMatchup.PlayerTwoId); updatedRoundMatchup.Table = roundMatchup.TableNo; } if (ModelState.IsValid) { try { if (updatedPairRoundMatchup != null) { _context.Update(updatedPairRoundMatchup); } else { _context.Update(updatedRoundMatchup); } await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!RoundMatchupActions.RoundMatchupsExists(roundMatchup.Id, _context)) { return(NotFound()); } else { throw; } } return(RedirectToAction(nameof(Index))); } roundMatchup.Players = _context.Players.ToList(); return(View(roundMatchup)); }
/** * * Validation * **/ //Get the errors for all roundMatchups, including any players on a team with themself or versing themself, any players //who have played the same opponent more than once, any players who have not played in every round and any players who have //played twice in one round public static List <List <string> > GetRoundMatchupErrors(TournamentDbContext _context) { var preSortedRoundMatchups = _context.RoundMatchups.Include(r => r.PlayerOne).Include(r => r.PlayerTwo).Where(r => !(r is PairRoundMatchup) && r.PlayerTwo.Name != "Bye").ToList(); var preSortedPairRoundMatchups = _context.RoundMatchups.OfType <PairRoundMatchup>().Include(r => r.PlayerOne).Include(r => r.PlayerThree).Where(r => r.PlayerThree.Name != "Bye").ToList(); List <RoundMatchup> roundMatchups = preSortedRoundMatchups.Union(preSortedPairRoundMatchups).OrderBy(r => r.RoundNo).ToList(); List <string> duplicatePlayers = new List <string>(); List <string> duplicateOpponents = new List <string>(); List <string> unallocatedPlayers = new List <string>(); List <string> overallocatedPlayers = new List <string>(); Dictionary <Player, int> playerRoundCount = new Dictionary <Player, int>(); List <Player> players = _context.Players.ToList(); foreach (Player player in players) { playerRoundCount.Add(player, 0); } foreach (RoundMatchup roundMatchup in roundMatchups) { //Check if there are players who either do not play at all or play more than once foreach (Player player in players) { if (player.Id == roundMatchup.PlayerOne.Id) { playerRoundCount[player] += 1; } //Only check playerTwo if they are not null (Will be null in a bye round) if (roundMatchup.PlayerTwo != null) { //Increment the amount of matchups player two has been a part of if they are not the same player as player one if (player.Id == roundMatchup.PlayerTwo.Id && roundMatchup.PlayerOne != roundMatchup.PlayerTwo) { playerRoundCount[player] += 1; } } if (roundMatchup is PairRoundMatchup) { PairRoundMatchup pairRoundMatchup = roundMatchup as PairRoundMatchup; //Only check playerThree and playerFour if they are not null (Will be null in a bye round) if (pairRoundMatchup.PlayerThree != null && pairRoundMatchup.PlayerFour != null) { //Increment the amount of matchups player three has played of if they are not the same player as player one or two if (player.Id == pairRoundMatchup.PlayerThree.Id && pairRoundMatchup.PlayerThree != pairRoundMatchup.PlayerTwo && pairRoundMatchup.PlayerThree != pairRoundMatchup.PlayerOne) { playerRoundCount[player] += 1; } //Increment the amount of matchups player four has played if they are not the same player as player one, two or three if (player.Id == pairRoundMatchup.PlayerFour.Id && pairRoundMatchup.PlayerFour != pairRoundMatchup.PlayerThree && pairRoundMatchup.PlayerFour != pairRoundMatchup.PlayerTwo && pairRoundMatchup.PlayerFour != pairRoundMatchup.PlayerOne) { playerRoundCount[player] += 1; } } } } } //Is set up so that if a player is allocated to themselves playerRoundCount is only incremented once. //It will warn that a player has not played enough rounds, even if they are versing themself in a round. //It will not warn that a player has played too many rounds if they have been allocated one too many times but //are versing themself in a round. int roundCount = GetLastRoundNo(_context); foreach (KeyValuePair <Player, int> entry in playerRoundCount) { if (entry.Value > roundCount) { overallocatedPlayers.Add(entry.Key.Name + " has been allocated " + entry.Value + " times with only " + roundCount + " rounds played"); } if (entry.Value < roundCount) { unallocatedPlayers.Add(entry.Key.Name + " has only been allocated to " + entry.Value + " matchup/s when " + roundCount + " have been played"); } } Dictionary <Player, List <Player> > duplicateOpponentsDictionary = PlayerActions.GetPreviouslyPlayedOpponentClashes(_context); foreach (var duplicateOpponentSet in duplicateOpponentsDictionary) { List <string> duplicateOpponentNameList = new List <string>(); foreach (Player duplicateOpponent in duplicateOpponentSet.Value) { duplicateOpponentNameList.Add(duplicateOpponent.Name); } string duplicateOpponentFormattedNameList = string.Join(", ", duplicateOpponentNameList); if (duplicateOpponentSet.Value.Count != 0) { duplicateOpponents.Add(duplicateOpponentSet.Key.Name + " has played " + duplicateOpponentFormattedNameList + " at least twice"); } } var errors = new List <List <string> >() { duplicatePlayers, duplicateOpponents, overallocatedPlayers, unallocatedPlayers }; return(errors); }
public static Boolean GenerateNextPairRound(TournamentDbContext _context) { Boolean error = false; int lastRound = GetLastRoundNo(_context); var roundMatchups = _context.RoundMatchups.Where(r => !(r is PairRoundMatchup)).Include(r => r.PlayerOne).Include(r => r.PlayerTwo).Where(r => r.RoundNo == lastRound).ToList(); var pairRoundMatchups = _context.PairRoundMatchups.Include(r => r.PlayerOne).Include(r => r.PlayerTwo).Include(r => r.PlayerThree).Include(r => r.PlayerFour).Where(r => r.RoundNo == lastRound).ToList(); List <Player> activePlayers = _context.Players.Where(p => p.Active && p.Bye == false).ToList(); List <Player> activeByePlayers = new List <Player>(); List <PlayerPair> playerPairs = new List <PlayerPair>(); roundMatchups = roundMatchups.Union(pairRoundMatchups).ToList(); if (roundMatchups != null) { Tuple <List <PlayerPair>, List <Player> > playerPairsAndByes = (RoundMatchupActions.GetPlayerPairs(roundMatchups, activePlayers)); playerPairs = playerPairsAndByes.Item1; activeByePlayers = playerPairsAndByes.Item2; } else { error = true; } //List<int> AllocatedTables = new List<int>(GetnoOfTables()); int secondaryIndex = 0; int i = 0; while (i < playerPairs.Count && i >= 0) { //Skip this player if they are already allocated an opponent if (playerPairs[i].CurrentOpponent == null) { if (secondaryIndex == 0) { secondaryIndex = i + 1; } int s = 0; for (s = secondaryIndex; s < playerPairs.Count; s++) { //If there are no more unique matchups, exit if (i == -1) { i = -2; error = true; break; } if (playerPairs[s].CurrentOpponent == null) { //Check if higher player has ever played lower player var playerOneOpponents = PlayerActions.GetAllOpponents(playerPairs[i].First, _context); var playerTwoOpponents = PlayerActions.GetAllOpponents(playerPairs[i].Second, _context); var opponents = playerOneOpponents.Union(playerTwoOpponents); var hasPlayed = false; foreach (Player opponent in opponents) { if (playerPairs[s].First == opponent || playerPairs[s].Second == opponent) { hasPlayed = true; } } //If they have not played allocate them as opponents if (hasPlayed == false) { playerPairs[i].CurrentOpponent = playerPairs[s]; playerPairs[s].CurrentOpponent = playerPairs[i]; secondaryIndex = 0; break; } /** * Following block is to deallocate the next lowest ranked allocated pair **/ if (playerPairs.Where(p => p.CurrentOpponent == null).LastOrDefault() == playerPairs[s] && (playerPairs[i].CurrentOpponent == null)) //if (s == (players.Count - 1) && (players[i].CurrentOpponent == null)) { if (i - 1 >= 0) { //Set the lowestAllocatedPair to the highest ranked pair PlayerPair lowestAllocatedPair = playerPairs[0]; //Iterate from the second highest ranked pair all the way to the pair ranked one higher than the player currently being matched for (int playerIndex = 1; playerIndex < i; playerIndex++) { //Assign the current player to the player being examined in the current iteration of the loop PlayerPair currentPair = playerPairs[playerIndex]; //Check that the current player has an opponent (if not, skip to the next iteration of the loop) if (currentPair.CurrentOpponent != null) { //Proceed if the current player's opponent has a higher rank than the current player if (playerPairs.IndexOf(currentPair.CurrentOpponent) < playerPairs.IndexOf(currentPair)) { if (playerPairs.IndexOf(currentPair.CurrentOpponent) > playerPairs.IndexOf(lowestAllocatedPair)) { //Set lowestAllocatedPair to the current player's opponent //(The highest ranked member of the new lowest ranked allocated pair) lowestAllocatedPair = currentPair.CurrentOpponent; } } //Proceed if the current player has a higher rank than their opponent else if (playerPairs.IndexOf(currentPair) < playerPairs.IndexOf(currentPair.CurrentOpponent)) { //Proceed if the current player has a lower rank than the previous value of lowestAllocatedPair if (playerPairs.IndexOf(currentPair) > playerPairs.IndexOf(lowestAllocatedPair)) { //Set lowestAllocatedPair to the current player //(The highest ranked member of the new lowest ranked allocated pair) lowestAllocatedPair = currentPair; } } } } //Set the new player to be allocated to the highest member of the lowestAllocatedPair i = playerPairs.IndexOf(lowestAllocatedPair) - 1; //If there are no more unique matchups, exit if (i == -1) { i = -2; error = true; break; } //Set the starting player that will be tested for allocation suitability to one rank lower than //the opponent of the highest member of the allocated pair secondaryIndex = playerPairs.IndexOf(lowestAllocatedPair.CurrentOpponent) + 1; //Deallocate the lowest allocated pair as each other's opponent lowestAllocatedPair.CurrentOpponent.CurrentOpponent = null; lowestAllocatedPair.CurrentOpponent = null; } else { i = -2; error = true; break; } } } } } i++; } int newRoundNo = lastRound + 1; foreach (PlayerPair playerPair in playerPairs) { if (playerPairs.IndexOf(playerPair) < playerPairs.IndexOf(playerPair.CurrentOpponent)) { var roundMatchup = new PairRoundMatchup { RoundNo = newRoundNo, PlayerOne = playerPair.First, PlayerTwo = playerPair.Second, PlayerThree = playerPair.CurrentOpponent.First, PlayerFour = playerPair.CurrentOpponent.Second }; //allocates table for matchup //roundMatchup.Table = AllocateTable(GetTables(player), AllocatedTables); _context.Add(roundMatchup); } //If there are no more unique matchups if (error) { //RoundMatchup will hold random pair matchups where teammates were opponents last round unless their opponent is no longer active or has a bye if (playerPair.CurrentOpponent == null && playerPairs[playerPairs.IndexOf(playerPair) + 1] != null) { playerPair.CurrentOpponent = playerPairs[playerPairs.IndexOf(playerPair) + 1]; playerPair.CurrentOpponent.CurrentOpponent = playerPair; var roundMatchup = new PairRoundMatchup { RoundNo = newRoundNo, PlayerOne = playerPair.First, PlayerTwo = playerPair.Second, PlayerThree = playerPair.CurrentOpponent.First, PlayerFour = playerPair.CurrentOpponent.Second }; _context.Add(roundMatchup); } } } CreateByeRounds(activeByePlayers, newRoundNo, _context); _context.SaveChanges(); if (error) { return(false); } return(true); }