diff --git a/PartyModeChallenge/ChallengeRounds.cs b/PartyModeChallenge/ChallengeRounds.cs index 5a40bc1e..95bf2b98 100644 --- a/PartyModeChallenge/ChallengeRounds.cs +++ b/PartyModeChallenge/ChallengeRounds.cs @@ -2,84 +2,250 @@ using System.Collections.Generic; using System.Text; +using Vocaluxe.Menu; + namespace Vocaluxe.PartyModes { public class ChallengeRounds { - private List _Rounds; + private Random _Rand; + private List _Rounds; + private int _NumPlayer; + public ChallengeRounds(int NumRounds, int NumPlayer, int NumPlayerAtOnce) { - BuildRounds(NumRounds, NumPlayer, NumPlayerAtOnce); - } + _Rounds = new List(); + _Rand = new Random(System.DateTime.Now.Millisecond); - public ChallengeRound GetRound(int RoundNr) - { - return null; - } - - private void BuildRounds(int NumRounds, int NumPlayer, int NumPlayerAtOnce) - { - _Rounds = new List(); - - if (NumPlayerAtOnce < 1 || NumPlayerAtOnce > 6 || NumPlayer < 1 || NumRounds < 1) - return; - - switch (NumPlayerAtOnce) + if (NumPlayerAtOnce < 1 || NumRounds < 1 || NumPlayer == 0) + _NumPlayer = 0; + else { - case 1: - for (int i = 0; i < NumRounds; i++) - { - - } - break; - - case 2: - break; - - case 3: - break; - - case 4: - break; - - case 5: - break; - - case 6: - break; - - default: - break; + _NumPlayer = NumPlayer; + BuildRounds(NumRounds, NumPlayerAtOnce, _Rand); } } - + public Combination GetRound(int RoundNr) + { + if (RoundNr >= _Rounds.Count || _NumPlayer == 0 || _Rounds.Count == 0) + return null; + + return _Rounds[RoundNr]; + } + + private void BuildRounds(int NumRounds, int NumPlayerAtOnce, Random Rand) + { + Combinations Combinations = new Combinations(_NumPlayer, NumPlayerAtOnce, Rand); + _Rounds.Add(Combinations.GetNextCombination(null)); + + for (int i = 1; i < NumRounds; i++) + { + + _Rounds.Add(Combinations.GetNextCombination(GetPlayerDemand(i))); + } + } + + private List GetPlayerDemand(int RoundIndex) + { + List NumPlayed = new List(_NumPlayer); + for (int i = 0; i < _NumPlayer; i++) + { + NumPlayed.Add(0); + } + + for (int i = 0; i < RoundIndex; i++) + { + foreach (int PlayerIndex in _Rounds[i].Player) + { + NumPlayed[PlayerIndex]++; + } + } + + int max = 0; + foreach (int p in NumPlayed) + { + if (p > max) + max = p; + } + + int num = _Rounds[0].Player.Count; + List result = new List(); + List other = new List(); + List last = new List(); + + for (int i = 0; i < NumPlayed.Count; i++) + { + if (NumPlayed[i] == 0 || NumPlayed[i] < max) + result.Add(i); + else + { + if (RoundIndex > 0) + { + if (!_Rounds[RoundIndex - 1].IsAvailable(i)) + other.Add(i); + else + last.Add(i); + } + else + last.Add(i); + + } + } + + while (result.Count < num && other.Count > 0) + { + int n = other.Count; + int r = _Rand.Next(n); + result.Add(other[r]); + other.RemoveAt(r); + } + + while (result.Count < num) + { + int n = last.Count; + int r = _Rand.Next(n); + result.Add(last[r]); + last.RemoveAt(r); + } + + + result.Sort(); + return result; + } } - public class ChallengeRound + class Combinations { - private List _ProfileIDs; + private List _Combs; + private Random _Rand; + private int _NumPlayer; + private int _NumMics; - public int NumPlayer { get{ return _ProfileIDs.Count; } } - - - public ChallengeRound() + public Combinations(int NumPlayer, int NumMics, Random Rand) { - _ProfileIDs = new List(); + _Combs = new List(); + _NumMics = NumMics; + _NumPlayer = NumPlayer; + _Rand = Rand; } - public void AddPlayer(int ProfileID) + public Combination GetNextCombination(List PlayerNrDemand) { - _ProfileIDs.Add(ProfileID); + if (_Combs.Count == 0) + Create(); + + Combination combs = new Combination(); + + if (_NumPlayer == _NumMics) + { + return _Combs[0]; + } + + //filter against PlayerNrDemand + List combsFiltered = new List(); + if (PlayerNrDemand != null) + { + for (int i = 0; i < _Combs.Count; i++) + { + if (_Combs[i].IsAvailableAll(PlayerNrDemand)) + combsFiltered.Add(_Combs[i]); + } + } + + //1st fallback + if (PlayerNrDemand != null && combsFiltered.Count == 0) + { + for (int i = 0; i < _Combs.Count; i++) + { + if (_Combs[i].IsAvailableSomeone(PlayerNrDemand)) + combsFiltered.Add(_Combs[i]); + } + } + + //2nd fallback + if (combsFiltered.Count == 0) + { + for (int i = 0; i < _Combs.Count; i++) + { + combsFiltered.Add(_Combs[i]); + } + } + + int num = combsFiltered.Count; + int rand = _Rand.Next(num); + Combination c = new Combination(); + for (int i = 0; i < combsFiltered[rand].Player.Count; i++) + { + c.Player.Add(combsFiltered[rand].Player[i]); + } + _Combs.Remove(combsFiltered[rand]); + + return combsFiltered[rand]; } - public int GetPlayer(int Nr) + private void Create() { - if (Nr >= _ProfileIDs.Count) - return -1; + _Combs.Clear(); - return _ProfileIDs[Nr]; + int num = (int)Math.Pow(2, _NumPlayer); + + for (int i = 1; i <= num; i++) + { + Combination c = new Combination(); + + for (int j = 0; j < _NumPlayer; j++) + { + if ((i & (1 << j)) > 0) + { + c.Player.Add(j); + } + } + + if (c.Player.Count == _NumMics) + _Combs.Add(c); + } + } + } + + public class Combination + { + public List Player; + + public Combination() + { + Player = new List(); + } + + public bool IsAvailable(int PlayerIndex) + { + foreach (int p in Player) + { + if (p == PlayerIndex) + return true; + } + return false; + } + + public bool IsAvailableAll(List PlayerIndices) + { + bool result = true; + foreach (int p in PlayerIndices) + { + result &= IsAvailable(p); + } + return result; + } + + public bool IsAvailableSomeone(List PlayerIndices) + { + bool result = false; + foreach (int p in PlayerIndices) + { + result |= IsAvailable(p); + } + return result; } } } diff --git a/PartyModeChallenge/PartyModeChallenge.cs b/PartyModeChallenge/PartyModeChallenge.cs index 76e5dbe7..b4ce5bec 100644 --- a/PartyModeChallenge/PartyModeChallenge.cs +++ b/PartyModeChallenge/PartyModeChallenge.cs @@ -81,6 +81,8 @@ namespace Vocaluxe.PartyModes public int NumRounds; public List ProfileIDs; + public ChallengeRounds Rounds; + public int CurrentRoundNr; } @@ -113,7 +115,7 @@ namespace Vocaluxe.PartyModes GameData.NumPlayerAtOnce = 2; GameData.NumRounds = 2; GameData.CurrentRoundNr = 1; - GameData.ProfileIDs = new List(); + GameData.ProfileIDs = new List(); } public override bool Init() @@ -230,7 +232,10 @@ namespace Vocaluxe.PartyModes case EStage.Names: _Screens.TryGetValue("PartyScreenChallengeMain", out Screen); if (_Screens != null) + { + GameData.Rounds = new ChallengeRounds(GameData.NumRounds, GameData.NumPlayer, GameData.NumPlayerAtOnce); Screen.DataToScreen(ToScreenMain); + } break; case EStage.Main: AlternativeScreen = EScreens.ScreenSong;