private static CRound _GetMatchingCombination(List <int> playersInRound, List <int> numSung, List <CRound> combinations) { foreach (CRound round in combinations) { int matching = round.Players.Count(playersInRound.Contains); // A valid round contains only players from playersInRound or all players from playersInRound (and some others) if (matching == round.Players.Count || matching == playersInRound.Count) { return(round); } } // It may happen, that there are only players that already sung against each other. So create a 2nd best option with the most number of players that should sing in it int maxMatching = combinations.Max(c => c.Players.Count(playersInRound.Contains)); List <CRound> nextOptions = combinations.Where(c => c.Players.Count(playersInRound.Contains) == maxMatching).ToList(); // And select the combination that minimizes the sum of the number of songs sung (--> favor rounds with players that sung less than others) CRound result = null; int minSung = int.MaxValue; foreach (CRound round in nextOptions) { int curNumSung = round.Players.Sum(pl => numSung[pl]); if (curNumSung < minSung) { minSung = curNumSung; result = round; } } Debug.Assert(result != null); return(result); }
private void _BuildRounds(int numRounds, int numPlayer, int playersPerRound) { // What we want is that every player sung the same amount of songs // So we keep track how many songs each palyer sung List <int> numSung = new List <int>(numPlayer); for (int i = 0; i < numPlayer; i++) { numSung.Add(0); } List <CRound> combinations = new List <CRound>(); // Posibly add more rounds than requested if the song count per player is unequal for (int i = 0; i < numRounds * 10; i++) { if (combinations.Count == 0) { _AddCombinations(numPlayer, playersPerRound, combinations); } List <int> playersInRound = _GetPlayersForRound(numSung); CRound curRound = _GetMatchingCombination(playersInRound, numSung, combinations); foreach (int player in curRound.Players) { numSung[player]++; } _Rounds.Add(curRound); combinations.Remove(curRound); //Stop if we have enough rounds and all players sung the same amount of songs if (_Rounds.Count >= numRounds && numSung.All(ct => ct == numSung[0])) { break; } } }
private bool _PrepareGame() { CBase.Game.Reset(); CBase.Game.ClearSongs(); #region PlayerNames CBase.Game.SetNumPlayer(GameData.NumPlayerAtOnce); SPlayer[] players = CBase.Game.GetPlayers(); if (players == null) { return(false); } if (players.Length < GameData.NumPlayerAtOnce) { return(false); } CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1]; for (int i = 0; i < GameData.NumPlayerAtOnce; i++) { //try to fill with the right data if (c != null) { players[i].ProfileID = GameData.ProfileIDs[c.Players[i]]; } else { players[i].ProfileID = -1; } } #endregion PlayerNames #region SongQueue for (int i = 0; i < GameData.NumSongs; i++) { if (GameData.Songs.Count == 0) { _UpdateSongList(); } CBase.Game.AddSong(GameData.Songs[0], EGameMode.TR_GAMEMODE_MEDLEY); GameData.Songs.RemoveAt(0); } return(true); #endregion SongQueue }
private void _SetTeamNames() { CProfile[] profiles = CBase.Profiles.GetProfiles(); if (profiles == null) { _ScreenSongOptions.Selection.TeamNames = new string[] { "foo", "bar" }; return; } if (GameData.NumPlayerAtOnce < 1 || GameData.ProfileIDs.Count < GameData.NumPlayerAtOnce || profiles.Length < GameData.NumPlayerAtOnce) { _ScreenSongOptions.Selection.TeamNames = new string[] { "foo", "bar" }; return; } _ScreenSongOptions.Selection.TeamNames = new string[GameData.NumPlayerAtOnce]; CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1]; for (int i = 0; i < GameData.NumPlayerAtOnce; i++) { if (c != null) { if (GameData.ProfileIDs[c.Players[i]] < profiles.Length) { _ScreenSongOptions.Selection.TeamNames[i] = profiles[GameData.ProfileIDs[c.Players[i]]].PlayerName; } else { _ScreenSongOptions.Selection.TeamNames[i] = "foobar"; } } else { _ScreenSongOptions.Selection.TeamNames[i] = "foobar"; } } }