From 24edcc732839000f9ace06f709c329296ea9c3b2 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 21 Dec 2014 12:06:47 +0100 Subject: [PATCH 1/4] Improve rounds generation --- .../PartyModeChallenge/CChallengeRounds.cs | 38 ++++++++++++++++--- .../CChallengeRounds.cs | 38 ++++++++++++++++--- VocaluxeTests/PartyModeTests.cs | 3 ++ 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/PartyModes/PartyModeChallenge/CChallengeRounds.cs b/PartyModes/PartyModeChallenge/CChallengeRounds.cs index d09a3b3b..37d46362 100644 --- a/PartyModes/PartyModeChallenge/CChallengeRounds.cs +++ b/PartyModes/PartyModeChallenge/CChallengeRounds.cs @@ -46,6 +46,18 @@ namespace VocaluxeLib.PartyModes.Challenge playersPerRound = numPlayer; _BuildRounds(numRounds, numPlayer, playersPerRound); + if (Count > numRounds) + { + //Try again and take the better one + List old = new List(_Rounds); + _Rounds.Clear(); + _BuildRounds(numRounds, numPlayer, playersPerRound); + if (Count > old.Count) + { + _Rounds.Clear(); + _Rounds.AddRange(old); + } + } } /// @@ -74,7 +86,7 @@ namespace VocaluxeLib.PartyModes.Challenge combinations.Shuffle(); } - private static CRound _GetMatchingCombination(List playersInRound, List combinations) + private static CRound _GetMatchingCombination(List playersInRound, List numSung, List combinations) { foreach (CRound round in combinations) { @@ -83,8 +95,23 @@ namespace VocaluxeLib.PartyModes.Challenge if (matching == round.Players.Count || matching == playersInRound.Count) return round; } - Debug.Assert(false, "This should not happen!"); - return combinations[0]; + // 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 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) @@ -101,16 +128,15 @@ namespace VocaluxeLib.PartyModes.Challenge if (combinations.Count == 0) _AddCombinations(numPlayer, playersPerRound, combinations); List playersInRound = _GetPlayersForRound(numSung); - CRound curRound = _GetMatchingCombination(playersInRound, combinations); + 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; } - if (_Rounds.Count != numRounds) - CBase.Log.LogDebug("Number of rounds does not match. Expected: " + numRounds + ", Is: " + _Rounds.Count + " for " + numPlayer + "/" + playersPerRound); } } diff --git a/PartyModes/PartyModeChallengeMedley/CChallengeRounds.cs b/PartyModes/PartyModeChallengeMedley/CChallengeRounds.cs index caa15ccc..92e5438f 100644 --- a/PartyModes/PartyModeChallengeMedley/CChallengeRounds.cs +++ b/PartyModes/PartyModeChallengeMedley/CChallengeRounds.cs @@ -46,6 +46,18 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley playersPerRound = numPlayer; _BuildRounds(numRounds, numPlayer, playersPerRound); + if (Count > numRounds) + { + //Try again and take the better one + List old = new List(_Rounds); + _Rounds.Clear(); + _BuildRounds(numRounds, numPlayer, playersPerRound); + if (Count > old.Count) + { + _Rounds.Clear(); + _Rounds.AddRange(old); + } + } } /// @@ -74,7 +86,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley combinations.Shuffle(); } - private static CRound _GetMatchingCombination(List playersInRound, List combinations) + private static CRound _GetMatchingCombination(List playersInRound, List numSung, List combinations) { foreach (CRound round in combinations) { @@ -83,8 +95,23 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley if (matching == round.Players.Count || matching == playersInRound.Count) return round; } - Debug.Assert(false, "This should not happen!"); - return combinations[0]; + // 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 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) @@ -101,16 +128,15 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley if (combinations.Count == 0) _AddCombinations(numPlayer, playersPerRound, combinations); List playersInRound = _GetPlayersForRound(numSung); - CRound curRound = _GetMatchingCombination(playersInRound, combinations); + 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; } - if (_Rounds.Count != numRounds) - CBase.Log.LogDebug("Number of rounds does not match. Expected: " + numRounds + ", Is: " + _Rounds.Count + " for " + numPlayer + "/" + playersPerRound); } } diff --git a/VocaluxeTests/PartyModeTests.cs b/VocaluxeTests/PartyModeTests.cs index 1678b7ff..c0363123 100644 --- a/VocaluxeTests/PartyModeTests.cs +++ b/VocaluxeTests/PartyModeTests.cs @@ -60,6 +60,9 @@ namespace VocaluxeTests CChallengeRounds rounds = new CChallengeRounds(numRounds, numPlayer, numMic); Assert.IsTrue(rounds.Count >= numRounds); _CheckRounds(rounds, numPlayer); + if (rounds.Count != numRounds) + CBase.Log.LogDebug("Number of rounds does not match. Expected: " + numRounds + ", Is: " + rounds.Count + " for " + numPlayer + "/" + + ((numPlayer < numMic) ? numPlayer : numMic)); } } } From 9a5ac282c56ffe0d7f25bc107dfc21c3b8447222 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 21 Dec 2014 12:18:08 +0100 Subject: [PATCH 2/4] Fix selected button but unselected text --- VocaluxeLib/Menu/CButton.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/VocaluxeLib/Menu/CButton.cs b/VocaluxeLib/Menu/CButton.cs index fad72b20..b0ca4a48 100644 --- a/VocaluxeLib/Menu/CButton.cs +++ b/VocaluxeLib/Menu/CButton.cs @@ -300,11 +300,6 @@ namespace VocaluxeLib.Menu } } - public void ProcessMouseMove(int x, int y) - { - Selected = CHelper.IsInBounds(Rect, x, y); - } - public void UnloadSkin() { if (!ThemeLoaded) @@ -318,6 +313,7 @@ namespace VocaluxeLib.Menu return; Text = new CText(_Theme.Text, _PartyModeID); Text.LoadSkin(); + Text.Selected = Selected; if (_Theme.SelText.HasValue) { From aa77d2d95c0a7decdf56aaf3b9c88b8089af4044 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 21 Dec 2014 12:38:40 +0100 Subject: [PATCH 3/4] Fix drag&drop of playlist --- VocaluxeLib/Menu/CObjectInteractions.cs | 9 +++++++++ VocaluxeLib/Menu/CPlaylist.cs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/VocaluxeLib/Menu/CObjectInteractions.cs b/VocaluxeLib/Menu/CObjectInteractions.cs index 0520e451..e7623787 100644 --- a/VocaluxeLib/Menu/CObjectInteractions.cs +++ b/VocaluxeLib/Menu/CObjectInteractions.cs @@ -91,6 +91,15 @@ namespace VocaluxeLib.Menu private void _SetSelected(int newSelection) { IMenuElement el = _GetElement(_Selection); + if (newSelection == _Selection) + { + // Don't change current selection + if (el == null) + _Selection = -1; + else if (!el.Selected) + el.Selected = true; + return; + } if (el != null) el.Selected = false; _Selection = newSelection; diff --git a/VocaluxeLib/Menu/CPlaylist.cs b/VocaluxeLib/Menu/CPlaylist.cs index ced7bb57..f22387d8 100644 --- a/VocaluxeLib/Menu/CPlaylist.cs +++ b/VocaluxeLib/Menu/CPlaylist.cs @@ -1039,7 +1039,7 @@ namespace VocaluxeLib.Menu en.Cover.LoadSkin(); en.Cover.Y += Rect.Y + (i * _Theme.EntryHeight); - en.Cover.X += Rect.X; + en.Cover.X += Rect.X; en.Text1 = new CText(_Text1); en.Text1.X += Rect.X; From 9e4a14985ebe4a0dd3dbbbd1095376f966c2cb43 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 21 Dec 2014 13:35:55 +0100 Subject: [PATCH 4/4] More fixes for playlist handling --- Vocaluxe/Screens/CScreenSong.cs | 65 ++++++++++++++++----------------- VocaluxeLib/Menu/CPlaylist.cs | 20 +++++++--- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/Vocaluxe/Screens/CScreenSong.cs b/Vocaluxe/Screens/CScreenSong.cs index fb89cc72..8a4d5ff1 100644 --- a/Vocaluxe/Screens/CScreenSong.cs +++ b/Vocaluxe/Screens/CScreenSong.cs @@ -80,7 +80,6 @@ namespace Vocaluxe.Screens private readonly List _ButtonsJoker = new List(); private readonly List _TextsPlayer = new List(); private ESongOptionsView _CurSongOptionsView; - private bool _PlaylistActive; private readonly List _AvailableGameModes; private SScreenSongOptions _Sso; @@ -163,16 +162,26 @@ namespace Vocaluxe.Screens public override bool HandleInput(SKeyEvent keyEvent) { + if (_Playlist.Visible) + { + keyEvent.Handled = _Playlist.HandleInput(keyEvent); + if (keyEvent.Handled) + return true; + if (!keyEvent.KeyPressed && keyEvent.Key == Keys.Escape) + { + _ClosePlaylist(); + keyEvent.Handled = true; + return true; + } + } + + // Playlist selection is handled below not in base! + _Playlist.Selectable = false; base.HandleInput(keyEvent); + _Playlist.Selectable = true; if (keyEvent.Handled) return true; - if (_PlaylistActive) - { - _Playlist.HandleInput(keyEvent); - return true; - } - if (_CurSongOptionsView == ESongOptionsView.None) { if (keyEvent.KeyPressed && !Char.IsControl(keyEvent.Unicode) && keyEvent.Mod != EModifier.Ctrl) @@ -233,9 +242,8 @@ namespace Vocaluxe.Screens case Keys.Tab: if (_Playlist.Visible) { - _PlaylistActive = !_PlaylistActive; - _Playlist.Selected = _PlaylistActive; - _SongMenu.Selected = !_PlaylistActive; + _Playlist.Selected = !_Playlist.Selected; + _SongMenu.Selected = !_Playlist.Selected; } break; @@ -392,27 +400,18 @@ namespace Vocaluxe.Screens _OldMousePosX = mouseEvent.X; _OldMousePosY = mouseEvent.Y; - if (_Playlist.Visible && _Playlist.IsMouseOver(mouseEvent)) + if (_Playlist.Visible && _Playlist.Selected) { - _PlaylistActive = true; - _Playlist.Selected = _PlaylistActive; - _SongMenu.Selected = !_PlaylistActive; + _SongMenu.Selected = false; _ToggleSongOptions(ESongOptionsView.None); - } - else if (CHelper.IsInBounds(_SongMenu.Rect, mouseEvent)) - { - _PlaylistActive = false; - _Playlist.Selected = _PlaylistActive; - _SongMenu.Selected = !_PlaylistActive; - } - - - if (_Playlist.Visible && _PlaylistActive) - { if (_Playlist.HandleMouse(mouseEvent)) return true; } - + else if (CHelper.IsInBounds(_SongMenu.Rect, mouseEvent)) + { + _Playlist.Selected = false; + _SongMenu.Selected = true; + } if (mouseEvent.RB) { @@ -630,12 +629,12 @@ namespace Vocaluxe.Screens if (_Sso.Selection.PartyMode) { - _PlaylistActive = false; + _ClosePlaylist(); _ToggleSongOptions(ESongOptionsView.None); _SelectElement(_Buttons[_ButtonStart]); } - _SongMenu.Selected = !_PlaylistActive; + _SongMenu.Selected = !_Playlist.Visible; _SongMenu.SmallView = _Playlist.Visible; if (_Playlist.ActivePlaylistID != -1) @@ -660,7 +659,7 @@ namespace Vocaluxe.Screens public override bool UpdateGame() { - if (_PlaylistActive) + if (_Playlist.Visible) { if (_Playlist.ActivePlaylistID == -1) _ClosePlaylist(); @@ -1257,12 +1256,12 @@ namespace Vocaluxe.Screens private void _ClosePlaylist() { - if (_Playlist.Visible || _PlaylistActive) + if (_Playlist.Visible) { _SongMenu.SmallView = false; - _PlaylistActive = false; - _Playlist.Selected = _PlaylistActive; - _SongMenu.Selected = !_PlaylistActive; + _Playlist.Visible = false; + _Playlist.Selected = false; + _SongMenu.Selected = false; _Playlist.ClosePlaylist(); } } diff --git a/VocaluxeLib/Menu/CPlaylist.cs b/VocaluxeLib/Menu/CPlaylist.cs index f22387d8..0b39d443 100644 --- a/VocaluxeLib/Menu/CPlaylist.cs +++ b/VocaluxeLib/Menu/CPlaylist.cs @@ -169,15 +169,16 @@ namespace VocaluxeLib.Menu private readonly CStatic _StaticPlaylistHeader; private readonly CStatic _StaticPlaylistFooter; - private bool _Selected; public SRectF Rect { get { return MaxRect; } } public SRectF MaxRect { get; set; } + private bool _Selectable = true; public bool Selectable { - get { return Visible; } + get { return Visible && _Selectable; } + set { _Selectable = value; } } public bool Visible { @@ -185,6 +186,7 @@ namespace VocaluxeLib.Menu set { _Active = value; } } public bool Highlighted { get; set; } + private bool _Selected; public bool Selected { get { return _Selected; } @@ -204,6 +206,8 @@ namespace VocaluxeLib.Menu _ChangeOrderElement = null; _EditMode = EEditMode.None; } + else if (_CurrentPlaylistElement == -1 && _PlaylistElements.Count > 0) + _SelectElement(_PlaylistElements[0].SelectSlide); } } @@ -420,7 +424,7 @@ namespace VocaluxeLib.Menu public override bool HandleInput(SKeyEvent keyEvent) { if (!Selected) - return true; + return false; //Active EditMode ignores other input! if (_EditMode == EEditMode.PlaylistName) { @@ -446,6 +450,8 @@ namespace VocaluxeLib.Menu if (!String.IsNullOrEmpty(_ButtonPlaylistName.Text.Text)) _ButtonPlaylistName.Text.Text = _ButtonPlaylistName.Text.Text.Remove(_ButtonPlaylistName.Text.Text.Length - 1); break; + default: + return false; } } return true; @@ -453,10 +459,10 @@ namespace VocaluxeLib.Menu if (_CurrentPlaylistElement == -1 || _PlaylistElementContents.Count == 0) { //no song is selected - base.HandleInput(keyEvent); + bool handled = base.HandleInput(keyEvent); _CurrentPlaylistElement = _GetSelectedElementNr(); - if (_CurrentPlaylistElement != -1) + if (_CurrentPlaylistElement != -1 || handled) return true; } else if (_CurrentPlaylistElement != -1) @@ -669,6 +675,8 @@ namespace VocaluxeLib.Menu UpdatePlaylist(); } break; + default: + return false; } return true; } @@ -720,6 +728,8 @@ namespace VocaluxeLib.Menu case Keys.PageUp: _SetSelectionToFirstEntry(); break; + default: + return false; } return true; }