Improve rounds generation
This commit is contained in:
1 parent
76859942b8
commit
24edcc7328
3 files changed
+67
-12
No files matched your search
@@ -46,6 +46,18 @@ namespace VocaluxeLib.PartyModes.Challenge
|
|||||||
playersPerRound = numPlayer;
|
playersPerRound = numPlayer;
|
||||||
|
|
||||||
_BuildRounds(numRounds, numPlayer, playersPerRound);
|
_BuildRounds(numRounds, numPlayer, playersPerRound);
|
||||||
|
if (Count > numRounds)
|
||||||
|
{
|
||||||
|
//Try again and take the better one
|
||||||
|
List<CRound> old = new List<CRound>(_Rounds);
|
||||||
|
_Rounds.Clear();
|
||||||
|
_BuildRounds(numRounds, numPlayer, playersPerRound);
|
||||||
|
if (Count > old.Count)
|
||||||
|
{
|
||||||
|
_Rounds.Clear();
|
||||||
|
_Rounds.AddRange(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -74,7 +86,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
|||||||
combinations.Shuffle();
|
combinations.Shuffle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CRound _GetMatchingCombination(List<int> playersInRound, List<CRound> combinations)
|
private static CRound _GetMatchingCombination(List<int> playersInRound, List<int> numSung, List<CRound> combinations)
|
||||||
{
|
{
|
||||||
foreach (CRound round in combinations)
|
foreach (CRound round in combinations)
|
||||||
{
|
{
|
||||||
@@ -83,8 +95,23 @@ namespace VocaluxeLib.PartyModes.Challenge
|
|||||||
if (matching == round.Players.Count || matching == playersInRound.Count)
|
if (matching == round.Players.Count || matching == playersInRound.Count)
|
||||||
return round;
|
return round;
|
||||||
}
|
}
|
||||||
Debug.Assert(false, "This should not happen!");
|
// 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
|
||||||
return combinations[0];
|
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)
|
private void _BuildRounds(int numRounds, int numPlayer, int playersPerRound)
|
||||||
@@ -101,16 +128,15 @@ namespace VocaluxeLib.PartyModes.Challenge
|
|||||||
if (combinations.Count == 0)
|
if (combinations.Count == 0)
|
||||||
_AddCombinations(numPlayer, playersPerRound, combinations);
|
_AddCombinations(numPlayer, playersPerRound, combinations);
|
||||||
List<int> playersInRound = _GetPlayersForRound(numSung);
|
List<int> playersInRound = _GetPlayersForRound(numSung);
|
||||||
CRound curRound = _GetMatchingCombination(playersInRound, combinations);
|
CRound curRound = _GetMatchingCombination(playersInRound, numSung, combinations);
|
||||||
foreach (int player in curRound.Players)
|
foreach (int player in curRound.Players)
|
||||||
numSung[player]++;
|
numSung[player]++;
|
||||||
_Rounds.Add(curRound);
|
_Rounds.Add(curRound);
|
||||||
|
combinations.Remove(curRound);
|
||||||
//Stop if we have enough rounds and all players sung the same amount of songs
|
//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]))
|
if (_Rounds.Count >= numRounds && numSung.All(ct => ct == numSung[0]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (_Rounds.Count != numRounds)
|
|
||||||
CBase.Log.LogDebug("Number of rounds does not match. Expected: " + numRounds + ", Is: " + _Rounds.Count + " for " + numPlayer + "/" + playersPerRound);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,18 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
playersPerRound = numPlayer;
|
playersPerRound = numPlayer;
|
||||||
|
|
||||||
_BuildRounds(numRounds, numPlayer, playersPerRound);
|
_BuildRounds(numRounds, numPlayer, playersPerRound);
|
||||||
|
if (Count > numRounds)
|
||||||
|
{
|
||||||
|
//Try again and take the better one
|
||||||
|
List<CRound> old = new List<CRound>(_Rounds);
|
||||||
|
_Rounds.Clear();
|
||||||
|
_BuildRounds(numRounds, numPlayer, playersPerRound);
|
||||||
|
if (Count > old.Count)
|
||||||
|
{
|
||||||
|
_Rounds.Clear();
|
||||||
|
_Rounds.AddRange(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -74,7 +86,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
combinations.Shuffle();
|
combinations.Shuffle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CRound _GetMatchingCombination(List<int> playersInRound, List<CRound> combinations)
|
private static CRound _GetMatchingCombination(List<int> playersInRound, List<int> numSung, List<CRound> combinations)
|
||||||
{
|
{
|
||||||
foreach (CRound round in combinations)
|
foreach (CRound round in combinations)
|
||||||
{
|
{
|
||||||
@@ -83,8 +95,23 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
if (matching == round.Players.Count || matching == playersInRound.Count)
|
if (matching == round.Players.Count || matching == playersInRound.Count)
|
||||||
return round;
|
return round;
|
||||||
}
|
}
|
||||||
Debug.Assert(false, "This should not happen!");
|
// 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
|
||||||
return combinations[0];
|
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)
|
private void _BuildRounds(int numRounds, int numPlayer, int playersPerRound)
|
||||||
@@ -101,16 +128,15 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
|
|||||||
if (combinations.Count == 0)
|
if (combinations.Count == 0)
|
||||||
_AddCombinations(numPlayer, playersPerRound, combinations);
|
_AddCombinations(numPlayer, playersPerRound, combinations);
|
||||||
List<int> playersInRound = _GetPlayersForRound(numSung);
|
List<int> playersInRound = _GetPlayersForRound(numSung);
|
||||||
CRound curRound = _GetMatchingCombination(playersInRound, combinations);
|
CRound curRound = _GetMatchingCombination(playersInRound, numSung, combinations);
|
||||||
foreach (int player in curRound.Players)
|
foreach (int player in curRound.Players)
|
||||||
numSung[player]++;
|
numSung[player]++;
|
||||||
_Rounds.Add(curRound);
|
_Rounds.Add(curRound);
|
||||||
|
combinations.Remove(curRound);
|
||||||
//Stop if we have enough rounds and all players sung the same amount of songs
|
//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]))
|
if (_Rounds.Count >= numRounds && numSung.All(ct => ct == numSung[0]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (_Rounds.Count != numRounds)
|
|
||||||
CBase.Log.LogDebug("Number of rounds does not match. Expected: " + numRounds + ", Is: " + _Rounds.Count + " for " + numPlayer + "/" + playersPerRound);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ namespace VocaluxeTests
|
|||||||
CChallengeRounds rounds = new CChallengeRounds(numRounds, numPlayer, numMic);
|
CChallengeRounds rounds = new CChallengeRounds(numRounds, numPlayer, numMic);
|
||||||
Assert.IsTrue(rounds.Count >= numRounds);
|
Assert.IsTrue(rounds.Count >= numRounds);
|
||||||
_CheckRounds(rounds, numPlayer);
|
_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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user