From 452c9d0fc136dbecdf20476fc873bc10c376a8fd Mon Sep 17 00:00:00 2001 From: Sarah Faey Date: Tue, 6 Dec 2022 09:19:32 +0100 Subject: [PATCH] split up randomizer in smaller functions randomizer now checks if the build is allowed in random raids --- Lieb/Data/RaidRandomizerService.cs | 164 ++++++++++++++++++----------- 1 file changed, 101 insertions(+), 63 deletions(-) diff --git a/Lieb/Data/RaidRandomizerService.cs b/Lieb/Data/RaidRandomizerService.cs index 6102d31..a52ed29 100644 --- a/Lieb/Data/RaidRandomizerService.cs +++ b/Lieb/Data/RaidRandomizerService.cs @@ -55,7 +55,7 @@ namespace Lieb.Data foreach (RaidSignUp signUp in raid.SignUps) { HashSet possibleClasses = new HashSet(); - foreach (Equipped build in signUp.GuildWars2Account.EquippedBuilds) + foreach (Equipped build in signUp.GuildWars2Account.EquippedBuilds.Where(b => b.GuildWars2Build.UseInRandomRaid)) { possibleClasses.Add(build.GuildWars2Build.Class); } @@ -79,7 +79,7 @@ namespace Lieb.Data foreach (RaidSignUp signUp in raid.SignUps) { HashSet possibleEliteSpecs = new HashSet(); - foreach (Equipped build in signUp.GuildWars2Account.EquippedBuilds) + foreach (Equipped build in signUp.GuildWars2Account.EquippedBuilds.Where(b => b.GuildWars2Build.UseInRandomRaid)) { possibleEliteSpecs.Add(build.GuildWars2Build.EliteSpecialization); } @@ -102,13 +102,36 @@ namespace Lieb.Data { int noGroups = (raid.SignUps.Where(s => s.SignUpType != SignUpType.Flex && s.SignUpType != SignUpType.SignedOff).Count() / 5) +1; - List usedAccounts = raid.SignUps.Where(s => s.GuildWars2Account != null && s.GuildWars2Account.EquippedBuilds.Count > 0).Select(s => s.GuildWars2Account).ToList(); - Dictionary addedAccounts = new Dictionary(); + HashSet signedUpAccounts = raid.SignUps.Where(s => s.GuildWars2Account != null && s.GuildWars2Account.EquippedBuilds.Where(b => b.GuildWars2Build.UseInRandomRaid).Count() > 0 + && s.SignUpType != SignUpType.Flex && s.SignUpType != SignUpType.SignedOff) + .Select(s => s.GuildWars2Account).ToHashSet(); + + List> possibleBoonCombinations = GetPossibleBoonCombinations(signedUpAccounts); - List alacHealers = usedAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType == DamageType.Heal && b.GuildWars2Build.Alacrity).Any()).ToList(); - List quickHealers = usedAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType == DamageType.Heal && b.GuildWars2Build.Quickness).Any()).ToList(); - List alacDps = usedAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType != DamageType.Heal && b.GuildWars2Build.Alacrity).Any()).ToList(); - List quickDps = usedAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType != DamageType.Heal && b.GuildWars2Build.Quickness).Any()).ToList(); + List> usedBoonCombinations = ChooseCombinations(possibleBoonCombinations, noGroups); + + Dictionary randomizedAccounts = CreateBoonRoles(raid, signedUpAccounts, usedBoonCombinations); + + if(usedBoonCombinations.Count < noGroups) + { + int neededHealers = noGroups - usedBoonCombinations.Count; + AddHealers(raid, signedUpAccounts, randomizedAccounts, neededHealers); + } + + if(randomizedAccounts.Where(a => a.Value.Might).Count() < noGroups ) + { + AddMight(raid, signedUpAccounts, randomizedAccounts, noGroups); + } + + AddDps(raid, signedUpAccounts, randomizedAccounts); + } + + private List> GetPossibleBoonCombinations(HashSet signedUpAccounts) + { + List alacHealers = signedUpAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType == DamageType.Heal && b.GuildWars2Build.Alacrity && b.GuildWars2Build.UseInRandomRaid).Any()).ToList(); + List quickHealers = signedUpAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType == DamageType.Heal && b.GuildWars2Build.Quickness && b.GuildWars2Build.UseInRandomRaid).Any()).ToList(); + List alacDps = signedUpAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType != DamageType.Heal && b.GuildWars2Build.Alacrity && b.GuildWars2Build.UseInRandomRaid).Any()).ToList(); + List quickDps = signedUpAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType != DamageType.Heal && b.GuildWars2Build.Quickness && b.GuildWars2Build.UseInRandomRaid).Any()).ToList(); List> possibleBoonCombinations = new List>(); foreach(GuildWars2Account alac in alacHealers) @@ -127,7 +150,11 @@ namespace Lieb.Data possibleBoonCombinations.Add(new Tuple(quick.GuildWars2AccountId, alac.GuildWars2AccountId)); } } + return possibleBoonCombinations; + } + private List> ChooseCombinations(List> possibleBoonCombinations, int noGroups) + { possibleBoonCombinations = possibleBoonCombinations.OrderBy(u => _random.Next()).ToList(); List> usedBoonCombinations = new List>(); foreach(var boonCombination in possibleBoonCombinations) @@ -139,72 +166,29 @@ namespace Lieb.Data usedBoonCombinations.Add(new Tuple(boonCombination.Item1, boonCombination.Item2)); } } + return usedBoonCombinations; + } - - //TODO: avoid the same GW2 account multiple times in a raid? + private Dictionary CreateBoonRoles(Raid raid, HashSet signedUpAccounts, List> usedBoonCombinations) + { + Dictionary randomizedAccounts = new Dictionary(); foreach(var boonCombination in usedBoonCombinations) { - GuildWars2Account healer = usedAccounts.First(a => a.GuildWars2AccountId == boonCombination.Item1); - GuildWars2Account boonDps = usedAccounts.First(a => a.GuildWars2AccountId == boonCombination.Item2); + GuildWars2Account healer = signedUpAccounts.First(a => a.GuildWars2AccountId == boonCombination.Item1); + GuildWars2Account boonDps = signedUpAccounts.First(a => a.GuildWars2AccountId == boonCombination.Item2); Tuple builds = GetBoonBuilds(healer, boonDps); AddRole(raid, builds.Item1, raid.SignUps.First(s => s.GuildWars2AccountId == boonCombination.Item1)); - addedAccounts.Add(healer, builds.Item1); + randomizedAccounts.Add(healer, builds.Item1); AddRole(raid, builds.Item2, raid.SignUps.First(s => s.GuildWars2AccountId == boonCombination.Item2)); - addedAccounts.Add(boonDps, builds.Item2); - } - - //add aditional healers - if(usedBoonCombinations.Count < noGroups) - { - List additionalHealers = usedAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType == DamageType.Heal).Any() - && !addedAccounts.Where(x => x.Key.GuildWars2AccountId == a.GuildWars2AccountId).Any()).ToList(); - additionalHealers = additionalHealers.OrderBy(u => _random.Next()).ToList(); - int neededHealers = noGroups - usedBoonCombinations.Count; - foreach(GuildWars2Account healer in additionalHealers) - { - if(neededHealers > 0) - { - GuildWars2Build build = healer.EquippedBuilds.First(b => b.GuildWars2Build.DamageType == DamageType.Heal).GuildWars2Build; - AddRole(raid, build, raid.SignUps.First(s => s.GuildWars2AccountId == healer.GuildWars2AccountId)); - addedAccounts.Add(healer, build); - neededHealers --; - } - } - } - - //add might - if(addedAccounts.Where(a => a.Value.Might).Count() < noGroups ) - { - List additionalMight = usedAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType != DamageType.Heal && b.GuildWars2Build.Might).Any() - && !addedAccounts.Where(x => x.Key.GuildWars2AccountId == a.GuildWars2AccountId).Any()).ToList(); - additionalMight = additionalMight.OrderBy(u => _random.Next()).ToList(); - int neededMight = noGroups - addedAccounts.Where(a => a.Value.Might).Count(); - foreach(GuildWars2Account mightAccount in additionalMight) - { - if(neededMight > 0) - { - GuildWars2Build build = mightAccount.EquippedBuilds.First(b => b.GuildWars2Build.DamageType != DamageType.Heal && b.GuildWars2Build.Might).GuildWars2Build; - AddRole(raid, build, raid.SignUps.First(s => s.GuildWars2AccountId == mightAccount.GuildWars2AccountId)); - addedAccounts.Add(mightAccount, build); - neededMight --; - } - } - } - - //add dps - List dpsPlayers = usedAccounts.Where(a => !addedAccounts.Where(x => x.Key.GuildWars2AccountId == a.GuildWars2AccountId).Any()).ToList(); - foreach(GuildWars2Account dps in dpsPlayers) - { - GuildWars2Build build = dps.EquippedBuilds.First(b => b.GuildWars2Build.DamageType != DamageType.Heal && !b.GuildWars2Build.Alacrity && !b.GuildWars2Build.Quickness).GuildWars2Build; - AddRole(raid, build, raid.SignUps.First(s => s.GuildWars2AccountId == dps.GuildWars2AccountId)); - addedAccounts.Add(dps, build); + randomizedAccounts.Add(boonDps, builds.Item2); } + return randomizedAccounts; } private Tuple GetBoonBuilds(GuildWars2Account healer, GuildWars2Account boonDps) { - List healBuilds = healer.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType == DamageType.Heal && (b.GuildWars2Build.Alacrity || b.GuildWars2Build.Quickness)).Select(b => b.GuildWars2Build).ToList(); - List boonBuilds = boonDps.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType != DamageType.Heal && (b.GuildWars2Build.Alacrity || b.GuildWars2Build.Quickness)).Select(b => b.GuildWars2Build).ToList(); + List healBuilds = healer.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType == DamageType.Heal && (b.GuildWars2Build.Alacrity || b.GuildWars2Build.Quickness) && b.GuildWars2Build.UseInRandomRaid).Select(b => b.GuildWars2Build).ToList(); + List boonBuilds = boonDps.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType != DamageType.Heal && (b.GuildWars2Build.Alacrity || b.GuildWars2Build.Quickness) && b.GuildWars2Build.UseInRandomRaid).Select(b => b.GuildWars2Build).ToList(); healBuilds.OrderBy(u => _random.Next()).ToList(); boonBuilds.OrderBy(u => _random.Next()).ToList(); @@ -218,6 +202,60 @@ namespace Lieb.Data } return new Tuple(new GuildWars2Build(), new GuildWars2Build()); } + + private void AddHealers(Raid raid, HashSet signedUpAccounts, Dictionary randomizedAccounts, int neededHealers) + { + List additionalHealers = signedUpAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType == DamageType.Heal && b.GuildWars2Build.UseInRandomRaid).Any() + && !randomizedAccounts.Where(x => x.Key.GuildWars2AccountId == a.GuildWars2AccountId).Any()).ToList(); + additionalHealers = additionalHealers.OrderBy(u => _random.Next()).ToList(); + foreach(GuildWars2Account healer in additionalHealers) + { + if(neededHealers > 0) + { + GuildWars2Build build = healer.EquippedBuilds.OrderBy(u => _random.Next()).First(b => b.GuildWars2Build.DamageType == DamageType.Heal && b.GuildWars2Build.UseInRandomRaid).GuildWars2Build; + AddRole(raid, build, raid.SignUps.First(s => s.GuildWars2AccountId == healer.GuildWars2AccountId)); + randomizedAccounts.Add(healer, build); + neededHealers --; + } + } + } + + private void AddMight(Raid raid, HashSet signedUpAccounts, Dictionary randomizedAccounts, int noGroups) + { + List might = signedUpAccounts.Where(a => a.EquippedBuilds.Where(b => b.GuildWars2Build.DamageType != DamageType.Heal && b.GuildWars2Build.Might && b.GuildWars2Build.UseInRandomRaid).Any() + && !randomizedAccounts.Where(x => x.Key.GuildWars2AccountId == a.GuildWars2AccountId).Any()).ToList(); + might = might.OrderBy(u => _random.Next()).ToList(); + int neededMight = noGroups - randomizedAccounts.Where(a => a.Value.Might).Count(); + foreach(GuildWars2Account mightAccount in might) + { + if(neededMight > 0) + { + GuildWars2Build build = mightAccount.EquippedBuilds.OrderBy(u => _random.Next()).First(b => b.GuildWars2Build.DamageType != DamageType.Heal && b.GuildWars2Build.Might && b.GuildWars2Build.UseInRandomRaid).GuildWars2Build; + AddRole(raid, build, raid.SignUps.First(s => s.GuildWars2AccountId == mightAccount.GuildWars2AccountId)); + randomizedAccounts.Add(mightAccount, build); + neededMight --; + } + } + } + + private void AddDps(Raid raid, HashSet signedUpAccounts, Dictionary randomizedAccounts) + { + List dpsPlayers = signedUpAccounts.Where(a => !randomizedAccounts.Where(x => x.Key.GuildWars2AccountId == a.GuildWars2AccountId).Any()).ToList(); + foreach(GuildWars2Account dps in dpsPlayers) + { + GuildWars2Build build = dps.EquippedBuilds.OrderBy(u => _random.Next()).FirstOrDefault(b => b.GuildWars2Build.DamageType != DamageType.Heal && !b.GuildWars2Build.Alacrity && !b.GuildWars2Build.Quickness && b.GuildWars2Build.UseInRandomRaid).GuildWars2Build; + if(build == null) + { + build = dps.EquippedBuilds.OrderBy(u => _random.Next()).FirstOrDefault(b => b.GuildWars2Build.DamageType != DamageType.Heal && b.GuildWars2Build.UseInRandomRaid).GuildWars2Build; + } + if(build == null) + { + build = dps.EquippedBuilds.OrderBy(u => _random.Next()).FirstOrDefault(b => b.GuildWars2Build.UseInRandomRaid).GuildWars2Build; + } + AddRole(raid, build, raid.SignUps.First(s => s.GuildWars2AccountId == dps.GuildWars2AccountId)); + randomizedAccounts.Add(dps, build); + } + } private void AddRole(Raid raid, GuildWars2Build usedBuild, RaidSignUp signUp ) {