private void SwapEvents() { // Get the required variables to swap an event from r0 with an event from r1 int r0Index = Globals.Rand.Next(this.Rounds.Length); RoundPlanning r0 = this.Rounds[r0Index]; int e0Index = Globals.Rand.Next(r0.Events.Length); Event e0 = r0.Events[e0Index]; int r1Index = Globals.Rand.Next(this.Rounds.Length); RoundPlanning r1 = this.Rounds[r1Index]; int e1Index = Globals.Rand.Next(r1.Events.Length); Event e1 = r1.Events[e1Index]; // Check if the rounds' available resources allow for the swap (bool legalSwapInR0, var newCategoryCountsForR0) = r0.LegalEventSwap(e0, e1); (bool legalSwapInR1, var newCategoryCountsForR1) = r1.LegalEventSwap(e1, e0); if (!legalSwapInR0 || !legalSwapInR1) { return; } // Swap r0.Events[e0Index] = e1; r1.Events[e1Index] = e0; // Update round player counts r0.PlayersPerMatchType = newCategoryCountsForR0; r1.PlayersPerMatchType = newCategoryCountsForR1; // Update relevant team stats, i.e. each team's events played per round this.ModifyEventTeamsEventsPerRound(e0, r0Index, -1); this.ModifyEventTeamsEventsPerRound(e0, r1Index, 1); this.ModifyEventTeamsEventsPerRound(e1, r1Index, -1); this.ModifyEventTeamsEventsPerRound(e1, r0Index, 1); }
/// <summary> /// Fully initialises this schedule's team statistics for the given team based on the given round. Note that /// the player counts per round should be updated separately. /// </summary> /// <param name="teamIndex"></param> /// <param name="roundIndex"></param> private void UpdateTeamStats(int teamIndex, int roundIndex) { ScheduleTeamStatistics teamStats = _teamStats[teamIndex]; RoundPlanning round = this.Rounds[roundIndex]; // Update team statistics for each event and match in which the given team participates foreach (Event e in round.Events) { // Determine the opponent's team ID bool givenTeamIsTeamOne = e.TeamOneId == teamIndex; bool givenTeamIsTeamTwo = e.TeamTwoId == teamIndex; int opponentId = givenTeamIsTeamOne ? e.TeamTwoId : e.TeamOneId; // Continue if the given team is not involved in this event. if (!givenTeamIsTeamOne && !givenTeamIsTeamTwo) { continue; } // The team is involved in the event, so update all relevant statistics teamStats.UpdateAfterEventAddition(opponentId, roundIndex); foreach (SportsMatch match in e.Matches) { teamStats.UpdateAfterSportsMatchAddition(match, roundIndex); } } }
public override string ToString() { string result = ""; for (int i = 0; i < Rounds.Length; i++) { RoundPlanning round = Rounds[i]; result += $"Round {i}:\n==========\n"; result += $"{round}\n"; } return(result); }
public BallStarsSchedule Clone() { // Construct deep copies of the required array objects var roundsClone = new RoundPlanning[Rounds.Length]; for (int i = 0; i < Rounds.Length; i++) { roundsClone[i] = Rounds[i].Clone(); } var teamStatsClone = new ScheduleTeamStatistics[_teamStats.Length]; for (int i = 0; i < _teamStats.Length; i++) { teamStatsClone[i] = _teamStats[i].Clone(); } return(new BallStarsSchedule(roundsClone, _amountOfTeams, _avgPlayersPerTeam, teamStatsClone)); }
/// <summary> /// Constructs a random schedule consisting of a given amount of rounds where teams are randomly scheduled to /// compete against each other in random events. /// </summary> /// <param name="amountOfTeams"></param> /// <param name="eventsPerRound"></param> /// <param name="regularEventsPerRound"></param> /// <param name="amountOfRounds"></param> /// <param name="matchPool"></param> /// <param name="breakRound"></param> /// <param name="avgPlayersPerTeam"></param> /// <param name="predefinedMatchUps">Given match-up tuples that cover the minimal requirements. These are /// assumed to be sorted.</param> public static BallStarsSchedule Random(int amountOfTeams, int eventsPerRound, int regularEventsPerRound, int amountOfRounds, List <SportsMatch> matchPool, bool breakRound, int avgPlayersPerTeam, List <Tuple <int, int> > predefinedMatchUps = null) { var schedule = new BallStarsSchedule(amountOfRounds, amountOfTeams, avgPlayersPerTeam); bool usePredefinedMatchUps = predefinedMatchUps != null; // Generate each random round independently unless match-ups are provided int currentMatchUpIndex = 0; for (int i = 0; i < amountOfRounds; i++) { if (!usePredefinedMatchUps) { schedule.Rounds[i] = RoundPlanning.Random(amountOfTeams, eventsPerRound, regularEventsPerRound, matchPool, avgPlayersPerTeam, breakRound); } else { // Get the desired subset of event match-ups List <Tuple <int, int> > eventMatchUps = predefinedMatchUps.GetRange(currentMatchUpIndex, regularEventsPerRound); currentMatchUpIndex += regularEventsPerRound; schedule.Rounds[i] = RoundPlanning.Random(amountOfTeams, eventsPerRound, regularEventsPerRound, matchPool, avgPlayersPerTeam, breakRound, eventMatchUps); // Go back to random generation if we've iterated through all the predefined match-ups usePredefinedMatchUps = currentMatchUpIndex < predefinedMatchUps.Count; } } schedule.UpdateScheduleStats(); return(schedule); }
public void SaveToCsv(string outputFile) { File.WriteAllText(outputFile, "Team 1,Team 2,Match 1,Match 2,Match 3,RoundNr\n"); var lines = new List <string>(); for (int i = 0; i < this.Rounds.Length; i++) { RoundPlanning round = this.Rounds[i]; foreach (Event e in round.Events) { string line = $"{e.TeamOneId},{e.TeamTwoId},"; // Append each match string to the line if it exists. Append a placeholder otherwise. for (int j = 0; j < 3; j++) { line += e.Matches.Count > j ? $"{e.Matches[j]}," : "None,"; } line += i; lines.Add(line); } } File.AppendAllLines(outputFile, lines); }