using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace Assets.Data { public class TraitsMapping : MonoBehaviour { public static Dictionary> ChampsTraits = new Dictionary< ChampionsEnum, List > { { ChampionsEnum.ASHE, new List { TraitsEnum.ELDRICHT, TraitsEnum.MULTISTRIKER } }, { ChampionsEnum.BLITZCRANK, new List { TraitsEnum.HONEYMANCY, TraitsEnum.VANGUARD } }, { ChampionsEnum.ELISE, new List { TraitsEnum.ELDRICHT, TraitsEnum.SHAPESHIFTER } }, { ChampionsEnum.JAX, new List { TraitsEnum.CHRONO, TraitsEnum.MULTISTRIKER } }, { ChampionsEnum.JAYCE, new List { TraitsEnum.PORTAL, TraitsEnum.SHAPESHIFTER } }, { ChampionsEnum.LILLIA, new List { TraitsEnum.FAERIE, TraitsEnum.BASTION } }, { ChampionsEnum.NOMSY, new List { TraitsEnum.DRAGON, TraitsEnum.HUNTER } }, { ChampionsEnum.POPPY, new List { TraitsEnum.WITCHCRAFT, TraitsEnum.BASTION } }, { ChampionsEnum.SERAPHINE, new List { TraitsEnum.FAERIE, TraitsEnum.MAGE } }, { ChampionsEnum.SORAKA, new List { TraitsEnum.SUGARCRAFT, TraitsEnum.MAGE } }, { ChampionsEnum.TWITCH, new List { TraitsEnum.FROST, TraitsEnum.HUNTER } }, { ChampionsEnum.WARWICK, new List { TraitsEnum.FROST, TraitsEnum.VANGUARD } }, { ChampionsEnum.ZIGGS, new List { TraitsEnum.HONEYMANCY, TraitsEnum.INCANTATOR } }, { ChampionsEnum.ZOE, new List { TraitsEnum.WITCHCRAFT, TraitsEnum.SCHOLAR, TraitsEnum.PORTAL, } }, { ChampionsEnum.AHRI, new List { TraitsEnum.ARCANA, TraitsEnum.SCHOLAR } }, { ChampionsEnum.AKALI, new List { TraitsEnum.PYRO, TraitsEnum.MULTISTRIKER, TraitsEnum.WARRIOR, } }, { ChampionsEnum.CASSIOPEIA, new List { TraitsEnum.WITCHCRAFT, TraitsEnum.INCANTATOR } }, { ChampionsEnum.GALIO, new List { TraitsEnum.PORTAL, TraitsEnum.VANGUARD, TraitsEnum.MAGE } }, { ChampionsEnum.KASSADIN, new List { TraitsEnum.PORTAL, TraitsEnum.MULTISTRIKER } }, { ChampionsEnum.KOGMAW, new List { TraitsEnum.HONEYMANCY, TraitsEnum.HUNTER } }, { ChampionsEnum.NILAH, new List { TraitsEnum.ELDRICHT, TraitsEnum.WARRIOR } }, { ChampionsEnum.NUNU, new List { TraitsEnum.HONEYMANCY, TraitsEnum.BASTION } }, { ChampionsEnum.RUMBLE, new List { TraitsEnum.SUGARCRAFT, TraitsEnum.BLASTER, TraitsEnum.VANGUARD, } }, { ChampionsEnum.SHYVANA, new List { TraitsEnum.DRAGON, TraitsEnum.SHAPESHIFTER } }, { ChampionsEnum.SYNDRA, new List { TraitsEnum.ELDRICHT, TraitsEnum.INCANTATOR } }, { ChampionsEnum.TRISTANA, new List { TraitsEnum.FAERIE, TraitsEnum.BLASTER } }, { ChampionsEnum.ZILEAN, new List { TraitsEnum.FROST, TraitsEnum.CHRONO, TraitsEnum.PRESERVER } }, { ChampionsEnum.BARD, new List { TraitsEnum.SUGARCRAFT, TraitsEnum.SCHOLAR, TraitsEnum.PRESERVER, } }, { ChampionsEnum.EZREAL, new List { TraitsEnum.PORTAL, TraitsEnum.BLASTER } }, { ChampionsEnum.HECARIM, new List { TraitsEnum.ARCANA, TraitsEnum.MULTISTRIKER, TraitsEnum.BASTION, } }, { ChampionsEnum.HWEI, new List { TraitsEnum.FROST, TraitsEnum.BLASTER } }, { ChampionsEnum.JINX, new List { TraitsEnum.SUGARCRAFT, TraitsEnum.HUNTER } }, { ChampionsEnum.KATARINA, new List { TraitsEnum.FAERIE, TraitsEnum.WARRIOR } }, { ChampionsEnum.MORDEKAISER, new List { TraitsEnum.ELDRICHT, TraitsEnum.VANGUARD } }, { ChampionsEnum.NEEKO, new List { TraitsEnum.WITCHCRAFT, TraitsEnum.SHAPESHIFTER } }, { ChampionsEnum.SHEN, new List { TraitsEnum.PYRO, TraitsEnum.BASTION } }, { ChampionsEnum.SWAIN, new List { TraitsEnum.FROST, TraitsEnum.SHAPESHIFTER } }, { ChampionsEnum.VEIGAR, new List { TraitsEnum.HONEYMANCY, TraitsEnum.MAGE } }, { ChampionsEnum.VEX, new List { TraitsEnum.CHRONO, TraitsEnum.MAGE } }, { ChampionsEnum.WUKONG, new List { TraitsEnum.DRUID } }, { ChampionsEnum.FIORA, new List { TraitsEnum.WITCHCRAFT, TraitsEnum.WARRIOR } }, { ChampionsEnum.GWEN, new List { TraitsEnum.SUGARCRAFT, TraitsEnum.WARRIOR } }, { ChampionsEnum.KALISTA, new List { TraitsEnum.FAERIE, TraitsEnum.MULTISTRIKER } }, { ChampionsEnum.KARMA, new List { TraitsEnum.INCANTATOR, TraitsEnum.CHRONO } }, { ChampionsEnum.NAMI, new List { TraitsEnum.ELDRICHT, TraitsEnum.MAGE } }, { ChampionsEnum.NASUS, new List { TraitsEnum.SHAPESHIFTER, TraitsEnum.PYRO } }, { ChampionsEnum.OLAF, new List { TraitsEnum.FROST, TraitsEnum.HUNTER } }, { ChampionsEnum.RAKAN, new List { TraitsEnum.FAERIE, TraitsEnum.PRESERVER } }, { ChampionsEnum.RYZE, new List { TraitsEnum.PORTAL, TraitsEnum.SCHOLAR } }, { ChampionsEnum.TAHMKENCH, new List { TraitsEnum.ARCANA, TraitsEnum.VANGUARD } }, { ChampionsEnum.TARIC, new List { TraitsEnum.PORTAL, TraitsEnum.BASTION } }, { ChampionsEnum.VARUS, new List { TraitsEnum.PYRO, TraitsEnum.BLASTER } }, { ChampionsEnum.BRIAR, new List { TraitsEnum.ELDRICHT, TraitsEnum.SHAPESHIFTER } }, { ChampionsEnum.CAMILLE, new List { TraitsEnum.CHRONO, TraitsEnum.MULTISTRIKER } }, { ChampionsEnum.DIANA, new List { TraitsEnum.FROST, TraitsEnum.BASTION } }, { ChampionsEnum.MILLIO, new List { TraitsEnum.FAERIE, TraitsEnum.SCHOLAR } }, { ChampionsEnum.MORGANA, new List { TraitsEnum.WITCHCRAFT, TraitsEnum.PRESERVER } }, { ChampionsEnum.NORRA, new List { TraitsEnum.PORTAL, TraitsEnum.MAGE } }, { ChampionsEnum.SMOLDER, new List { TraitsEnum.DRAGON, TraitsEnum.BLASTER } }, { ChampionsEnum.XERATH, new List { TraitsEnum.ARCANA } }, }; public static Dictionary> TraitsChamp = new Dictionary< TraitsEnum, List > { { TraitsEnum.ARCANA, new List { ChampionsEnum.AHRI, ChampionsEnum.HECARIM, ChampionsEnum.TAHMKENCH, ChampionsEnum.XERATH, } }, { TraitsEnum.CHRONO, new List { ChampionsEnum.CAMILLE, ChampionsEnum.JAX, ChampionsEnum.KARMA, ChampionsEnum.VEX, ChampionsEnum.ZILEAN, } }, { TraitsEnum.DRAGON, new List { ChampionsEnum.SMOLDER, ChampionsEnum.SHYVANA, ChampionsEnum.NOMSY, } }, { TraitsEnum.DRUID, new List { ChampionsEnum.WUKONG } }, { TraitsEnum.ELDRICHT, new List { ChampionsEnum.ASHE, ChampionsEnum.BRIAR, ChampionsEnum.ELISE, ChampionsEnum.MORDEKAISER, ChampionsEnum.NAMI, ChampionsEnum.NILAH, ChampionsEnum.SYNDRA, } }, { TraitsEnum.FAERIE, new List { ChampionsEnum.KALISTA, ChampionsEnum.KATARINA, ChampionsEnum.LILLIA, ChampionsEnum.MILLIO, ChampionsEnum.RAKAN, ChampionsEnum.SERAPHINE, ChampionsEnum.TRISTANA, } }, { TraitsEnum.FROST, new List { ChampionsEnum.DIANA, ChampionsEnum.HWEI, ChampionsEnum.OLAF, ChampionsEnum.SWAIN, ChampionsEnum.TWITCH, ChampionsEnum.WARWICK, ChampionsEnum.ZILEAN, } }, { TraitsEnum.HONEYMANCY, new List { ChampionsEnum.BLITZCRANK, ChampionsEnum.KOGMAW, ChampionsEnum.NUNU, ChampionsEnum.VEIGAR, ChampionsEnum.ZIGGS, } }, { TraitsEnum.PORTAL, new List { ChampionsEnum.EZREAL, ChampionsEnum.GALIO, ChampionsEnum.JAYCE, ChampionsEnum.KASSADIN, ChampionsEnum.NORRA, ChampionsEnum.RYZE, ChampionsEnum.TARIC, ChampionsEnum.ZOE, } }, { TraitsEnum.PYRO, new List { ChampionsEnum.AKALI, ChampionsEnum.NASUS, ChampionsEnum.SHEN, ChampionsEnum.VARUS, } }, { TraitsEnum.SUGARCRAFT, new List { ChampionsEnum.BARD, ChampionsEnum.GWEN, ChampionsEnum.JINX, ChampionsEnum.RUMBLE, ChampionsEnum.SORAKA, } }, { TraitsEnum.WITCHCRAFT, new List { ChampionsEnum.CASSIOPEIA, ChampionsEnum.FIORA, ChampionsEnum.MORGANA, ChampionsEnum.NEEKO, ChampionsEnum.POPPY, ChampionsEnum.ZOE, } }, { TraitsEnum.BASTION, new List { ChampionsEnum.DIANA, ChampionsEnum.HECARIM, ChampionsEnum.LILLIA, ChampionsEnum.NUNU, ChampionsEnum.POPPY, ChampionsEnum.SHEN, ChampionsEnum.TARIC, } }, { TraitsEnum.BLASTER, new List { ChampionsEnum.EZREAL, ChampionsEnum.HWEI, ChampionsEnum.RUMBLE, ChampionsEnum.SMOLDER, ChampionsEnum.TRISTANA, ChampionsEnum.VARUS, } }, { TraitsEnum.HUNTER, new List { ChampionsEnum.JINX, ChampionsEnum.KOGMAW, ChampionsEnum.NOMSY, ChampionsEnum.OLAF, ChampionsEnum.TWITCH, } }, { TraitsEnum.INCANTATOR, new List { ChampionsEnum.CASSIOPEIA, ChampionsEnum.KARMA, ChampionsEnum.SYNDRA, ChampionsEnum.ZIGGS, } }, { TraitsEnum.MAGE, new List { ChampionsEnum.GALIO, ChampionsEnum.NAMI, ChampionsEnum.NORRA, ChampionsEnum.SERAPHINE, ChampionsEnum.SORAKA, ChampionsEnum.VEIGAR, ChampionsEnum.VEX, } }, { TraitsEnum.MULTISTRIKER, new List { ChampionsEnum.AKALI, ChampionsEnum.ASHE, ChampionsEnum.CAMILLE, ChampionsEnum.HECARIM, ChampionsEnum.JAX, ChampionsEnum.KALISTA, ChampionsEnum.KASSADIN, } }, { TraitsEnum.PRESERVER, new List { ChampionsEnum.BARD, ChampionsEnum.MORGANA, ChampionsEnum.RAKAN, ChampionsEnum.ZILEAN, } }, { TraitsEnum.SCHOLAR, new List { ChampionsEnum.AHRI, ChampionsEnum.BARD, ChampionsEnum.MILLIO, ChampionsEnum.RYZE, ChampionsEnum.ZOE, } }, { TraitsEnum.SHAPESHIFTER, new List { ChampionsEnum.BRIAR, ChampionsEnum.ELISE, ChampionsEnum.JAYCE, ChampionsEnum.NASUS, ChampionsEnum.NEEKO, ChampionsEnum.SHYVANA, ChampionsEnum.SWAIN, } }, { TraitsEnum.VANGUARD, new List { ChampionsEnum.BLITZCRANK, ChampionsEnum.GALIO, ChampionsEnum.MORDEKAISER, ChampionsEnum.RUMBLE, ChampionsEnum.TAHMKENCH, ChampionsEnum.WARWICK, } }, { TraitsEnum.WARRIOR, new List { ChampionsEnum.AKALI, ChampionsEnum.FIORA, ChampionsEnum.GWEN, ChampionsEnum.KATARINA, ChampionsEnum.NILAH, } }, }; public Dictionary ChampionCost = new Dictionary() { { ChampionsEnum.ASHE, 1 }, { ChampionsEnum.BLITZCRANK, 1 }, { ChampionsEnum.ELISE, 1 }, { ChampionsEnum.JAX, 1 }, { ChampionsEnum.JAYCE, 1 }, { ChampionsEnum.LILLIA, 1 }, { ChampionsEnum.NOMSY, 1 }, { ChampionsEnum.POPPY, 1 }, { ChampionsEnum.SERAPHINE, 1 }, { ChampionsEnum.SORAKA, 1 }, { ChampionsEnum.TWITCH, 1 }, { ChampionsEnum.WARWICK, 1 }, { ChampionsEnum.ZIGGS, 1 }, { ChampionsEnum.ZOE, 1 }, { ChampionsEnum.AHRI, 2 }, { ChampionsEnum.AKALI, 2 }, { ChampionsEnum.CASSIOPEIA, 2 }, { ChampionsEnum.GALIO, 2 }, { ChampionsEnum.KASSADIN, 2 }, { ChampionsEnum.KOGMAW, 2 }, { ChampionsEnum.NILAH, 2 }, { ChampionsEnum.NUNU, 2 }, { ChampionsEnum.RUMBLE, 2 }, { ChampionsEnum.SHYVANA, 2 }, { ChampionsEnum.SYNDRA, 2 }, { ChampionsEnum.TRISTANA, 2 }, { ChampionsEnum.ZILEAN, 2 }, { ChampionsEnum.BARD, 3 }, { ChampionsEnum.EZREAL, 3 }, { ChampionsEnum.HECARIM, 3 }, { ChampionsEnum.HWEI, 3 }, { ChampionsEnum.JINX, 3 }, { ChampionsEnum.KATARINA, 3 }, { ChampionsEnum.MORDEKAISER, 3 }, { ChampionsEnum.NEEKO, 3 }, { ChampionsEnum.SHEN, 3 }, { ChampionsEnum.SWAIN, 3 }, { ChampionsEnum.VEIGAR, 3 }, { ChampionsEnum.VEX, 3 }, { ChampionsEnum.WUKONG, 3 }, { ChampionsEnum.FIORA, 4 }, { ChampionsEnum.GWEN, 4 }, { ChampionsEnum.KALISTA, 4 }, { ChampionsEnum.KARMA, 4 }, { ChampionsEnum.NAMI, 4 }, { ChampionsEnum.NASUS, 4 }, { ChampionsEnum.OLAF, 4 }, { ChampionsEnum.RAKAN, 4 }, { ChampionsEnum.RYZE, 4 }, { ChampionsEnum.TAHMKENCH, 4 }, { ChampionsEnum.TARIC, 4 }, { ChampionsEnum.VARUS, 4 }, { ChampionsEnum.BRIAR, 5 }, { ChampionsEnum.CAMILLE, 5 }, { ChampionsEnum.DIANA, 5 }, { ChampionsEnum.MILLIO, 5 }, { ChampionsEnum.MORGANA, 5 }, { ChampionsEnum.NORRA, 5 }, { ChampionsEnum.SMOLDER, 5 }, { ChampionsEnum.XERATH, 5 }, }; public static Dictionary> TraitsSteps = new Dictionary< TraitsEnum, List > { { TraitsEnum.ARCANA, new List { 1, 2, 3, 4, 5 } }, { TraitsEnum.CHRONO, new List { 2, 4, 6 } }, { TraitsEnum.DRAGON, new List { 2, 3 } }, { TraitsEnum.DRUID, new List { 1 } }, { TraitsEnum.ELDRICHT, new List { 3, 5, 7, 10 } }, { TraitsEnum.FAERIE, new List { 3, 5, 7, 9 } }, { TraitsEnum.FROST, new List { 3, 5, 7, 9 } }, { TraitsEnum.HONEYMANCY, new List { 3, 5, 7 } }, { TraitsEnum.PORTAL, new List { 3, 6, 8, 10 } }, { TraitsEnum.PYRO, new List { 2, 3, 4, 5 } }, { TraitsEnum.SUGARCRAFT, new List { 2, 4, 6 } }, { TraitsEnum.WITCHCRAFT, new List { 2, 4, 6, 8 } }, { TraitsEnum.BASTION, new List { 2, 4, 6, 8 } }, { TraitsEnum.BLASTER, new List { 2, 4, 6 } }, { TraitsEnum.HUNTER, new List { 2, 4, 6 } }, { TraitsEnum.INCANTATOR, new List { 2, 4 } }, { TraitsEnum.MAGE, new List { 3, 5, 7, 10 } }, { TraitsEnum.MULTISTRIKER, new List { 3, 5, 7, 9 } }, { TraitsEnum.PRESERVER, new List { 2, 3, 4, 5 } }, { TraitsEnum.SCHOLAR, new List { 2, 4, 6 } }, { TraitsEnum.SHAPESHIFTER, new List { 2, 4, 6, 8 } }, { TraitsEnum.VANGUARD, new List { 2, 4, 6 } }, { TraitsEnum.WARRIOR, new List { 2, 4, 6 } }, }; public bool TestMappingCoherence() { foreach (var champTraits in ChampsTraits) { foreach (var trait in champTraits.Value) { if (!TraitsChamp[trait].Contains(champTraits.Key)) { Debug.Log($"Error in {champTraits.Key} with {champTraits.Value}"); return false; } } } foreach (var traitChamps in TraitsChamp) { foreach (var champ in traitChamps.Value) { if (!ChampsTraits[champ].Contains(traitChamps.Key)) { Debug.Log($"Error in {traitChamps.Key} with {traitChamps.Value}"); return false; } } } return true; } public bool TraitEnabled(TraitsEnum trait, int traitChampCount) { return traitChampCount >= TraitsSteps[trait][0]; } public static Dictionary TraitCountInCompo(HashSet compo) { Dictionary synergies = new Dictionary(); foreach (var champ in compo) { var traits = ChampsTraits[champ]; foreach (TraitsEnum trait in traits) { if (synergies.ContainsKey(trait)) { synergies[trait]++; } else { synergies[trait] = 1; } } } return synergies; } public static HashSet FilterActiveTraits(Dictionary synergies) { HashSet output = new HashSet(); foreach (var kvp in synergies) { int minActivation = TraitsSteps[kvp.Key][0]; if (kvp.Value >= minActivation) { output.Add(kvp.Key); } } return output; } public static Dictionary MergeEmblems( Dictionary synergies, Dictionary additionalEmblems ) { Dictionary mergedEmblems = new Dictionary(); mergedEmblems = synergies .Concat(additionalEmblems) .GroupBy(x => x.Key) .ToDictionary(x => x.Key, x => x.Sum(y => y.Value)); return mergedEmblems; } void Start() { var champList = new HashSet() { ChampionsEnum.ASHE, ChampionsEnum.BLITZCRANK, ChampionsEnum.ELISE, ChampionsEnum.JAX, ChampionsEnum.SERAPHINE, }; var combination = GetChampionSubsets(champList, 3); Debug.Log(DisplayComposition(champList)); Debug.Log("----------------------"); foreach (var compo in combination) { Debug.Log(DisplayComposition(compo)); } } public void DisplayTraits(Dictionary traits) { foreach (var kvp in traits) { Debug.Log($"{kvp.Key} : {kvp.Value}"); } } public string DisplayComposition(HashSet compo) { StringBuilder sb = new StringBuilder(); foreach (var champ in compo) { sb.Append(champ.ToString() + " / "); } return sb.ToString(); } public static IEnumerator GetChampionSubsetsAsync( HashSet champs, int size, Dictionary emblemList, System.Action> onCombinationGenerated ) { if (size == 0) { onCombinationGenerated(new HashSet()); yield break; } List champList = champs.ToList(); // Handle the edge case when size is greater than the number of available champions. if (size > champList.Count) { yield break; // No valid subsets if size is too large. } int n = champList.Count; int[] indices = new int[size]; for (int i = 0; i < size; i++) indices[i] = i; while (true) { HashSet subset = new HashSet(); foreach (int index in indices) { subset.Add(champList[index]); } onCombinationGenerated(subset); yield return null; // Generate the next combination of indices int i; for (i = size - 1; i >= 0; i--) { if (indices[i] != i + n - size) { break; } } if (i < 0) { break; // All combinations have been generated. } indices[i]++; for (int j = i + 1; j < size; j++) { indices[j] = indices[j - 1] + 1; } } } public static List> GetChampionSubsets( HashSet champs, int size ) { List> result = new List>(); if (size == 0) { result.Add(new HashSet()); return result; } List champList = champs.ToList(); // Handle the edge case when size is greater than the number of available champions. if (size > champList.Count) { return result; // No valid subsets if size is too large. } // Use a bit mask approach to generate all subsets of the specified size. int n = champList.Count; int[] indices = new int[size]; for (int i = 0; i < size; i++) indices[i] = i; while (true) { HashSet subset = new HashSet(); foreach (int index in indices) { subset.Add(champList[index]); } result.Add(subset); // Generate the next combination of indices int i; for (i = size - 1; i >= 0; i--) { if (indices[i] != i + n - size) { break; } } if (i < 0) { break; // All combinations have been generated. } indices[i]++; for (int j = i + 1; j < size; j++) { indices[j] = indices[j - 1] + 1; } } return result; } public static List> GetChampionSubsetsRec( HashSet champs, int size ) { List> result = new List>(); if (size == 0) { result.Add(new HashSet()); return result; } if (champs.Count == 0) { return result; } ChampionsEnum first = champs.First(); HashSet rest = new HashSet(champs); rest.Remove(first); List> subResult = GetChampionSubsetsRec(rest, size - 1); foreach (var set in subResult) { set.Add(first); } result.AddRange(subResult); result.AddRange(GetChampionSubsetsRec(rest, size)); return result; } internal static string CompositionToString( HashSet composition, HashSet activeSynergies ) { StringBuilder sb = new StringBuilder(); foreach (var champ in composition) { sb.Append(champ.ToString() + " / "); } sb.Append(" --------- "); foreach (var trait in activeSynergies) { sb.Append(trait.ToString() + " / "); } return sb.ToString(); } } }