// Tournament Organizer functions. These are used to run a tournament bracket. public static void StartTournament(PlayerDatabase playerData, ChallongeClient challonge) { // Name bracket Print("Input bracket name: "); string name = Read(); // Create bracket and list to hold players being added List <Player> participants = new List <Player>(); // Add players to bracket/start bracket bool startedBracket = false; PrintLine(); PrintLine("Type 'help' to see pre-tournament commands."); Print("> "); string input = Read().ToLowerInvariant(); while (!startedBracket) { switch (input) { case "new": Player player = AddPlayer(playerData); participants.Add(player); PrintLine(); break; case "add": player = AddExistingPlayerToCurrentBracket(playerData); if (player != null) { participants.Add(player); } PrintLine(); break; case "cancel": return; case "start": case "start tournament": PrintLine("Once you start the bracket, you cannot add additional players. Begin bracket? "); input = Read().ToLowerInvariant(); if (input == "y" || input == "yes") { startedBracket = true; } break; case "participants": PrintLine("Current Participants:"); foreach (var p in participants) { PrintLine($"* {p.Tag}"); } break; case "view database": PrintLine("Saved Players:"); foreach (var p in playerData.GetAllPlayers()) { PrintLine($"* {p.Tag}"); } break; case "help": PrintTournamentCreationHelp(); break; } if (!startedBracket) { Print("> "); input = Read().ToLowerInvariant(); } } // Actually create the bracket now that we know the user wants to. ChallongeBracket newBracket = challonge.CreateBracket(name); while (!challonge.TryBulkAddPlayers(newBracket.Id.ToString(), participants.Select(p => p.Tag))) { Print("Error adding players to begin tournament. Try again? "); input = Read().ToLowerInvariant(); if (input == "no" || input == "n") { PrintLine("Ok. Cancelling bracket."); Console.Clear(); return; } } challonge.StartTournament(newBracket.Id.ToString()); newBracket = challonge.GetBracket(newBracket.Id.ToString()); newBracket.Started = true; // This is needed to be able to update player rankings during the tournament. var playersByChallongeId = participants.ToReadOnlyDictionary(p => newBracket.PlayerList.Where(cp => p.Tag == cp.Tag).Select(cp => cp.Id).SingleOrDefault()); RunTournament(playerData, challonge, newBracket, playersByChallongeId); }
public static void RunTournament(PlayerDatabase playerData, ChallongeClient challonge, ChallongeBracket currentBracket, ReadOnlyDictionary <string, Player> playersByChallongeId) { // Initialize variables and start tournament int roundCount = 0; var playerIdRef = currentBracket.PlayerList.ToReadOnlyDictionary(p => p.Id); var playerTagRef = currentBracket.PlayerList.ToReadOnlyDictionary(p => p.Tag.ToLowerInvariant()); PrintLine(); PrintLine($"Beginning tournament {currentBracket.Id}"); // Run each round until the bracket is done while (currentBracket.MatchList.Any(m => m.State != MatchState.Complete)) { // Initialize current round information var currentRound = challonge.GetMatches(currentBracket.Id.ToString(), MatchState.Open); var matchesByPlayerId = new Dictionary <string, ChallongeMatch>(); foreach (var match in currentRound) { matchesByPlayerId.Add(match.Player1Id, match); matchesByPlayerId.Add(match.Player2Id, match); } // Print out current round matches PrintLine($"{(TournamentRound)roundCount++} Round Matches: "); foreach (var match in currentRound) { PrintLine($"{playerIdRef[match.Player1Id].Tag} vs. {playerIdRef[match.Player2Id].Tag}"); } // Read match results until current round is done PrintLine("To report match result, enter the tag of the winning player. To see matches not yet played, enter 'view matches'."); Print("> "); while (currentRound.Any(m => m.State != MatchState.Complete)) { string input = Read(); if (input.ToLowerInvariant() == "view matches") { foreach (var match in currentRound.Where(m => m.State == MatchState.Open)) { PrintLine($"{playerIdRef[match.Player1Id].Tag} vs. {playerIdRef[match.Player2Id].Tag}"); } } else if (input == "") { PrintLine("Enter a valid command."); } else { // Update challonge results string winnerTag = input.ToLowerInvariant(); var challongeWinner = playerTagRef[winnerTag]; var currentMatch = matchesByPlayerId[challongeWinner.Id]; currentMatch.ReportWinner(challongeWinner.Id); PrintLine("Enter score in the format of Winner-Loser"); Print("> "); string score = Read(); score = currentMatch.ConvertScoreCSV(score, challongeWinner.Id); challonge.UpdateMatch(currentBracket.Id.ToString(), currentMatch.Id, score, challongeWinner.Id); // Update rankings and commit them to database. var winner = playersByChallongeId[challongeWinner.Id]; var loser = playersByChallongeId[currentMatch.LosingPlayerId]; loser.Rating.UpdateRating(won: false, opponentRating: winner.Rating); winner.Rating.UpdateRating(won: true, opponentRating: loser.Rating); playerData.UpdatePlayerRating(winner); playerData.UpdatePlayerRating(loser); PrintLine(); } if (currentRound.Any(m => m.State != MatchState.Complete)) { Print("> "); } } currentBracket = challonge.GetBracket(currentBracket.Id.ToString()); PrintLine(); } PrintLine("Bracket Complete!"); challonge.FinalizeTournament(currentBracket.Id); PrintLine(); }