update everything

This commit is contained in:
2024-09-23 01:27:01 +02:00
parent 4a6378dab0
commit 27f87cefda
10 changed files with 710 additions and 469 deletions

View File

@@ -47,6 +47,12 @@ namespace Assets.Data
return BitWise.HammingWeight(champions);
}
/// <summary>
/// 0 to n-1
/// </summary>
/// <param name="champions"></param>
/// <param name="n"></param>
/// <returns></returns>
public static long GetNthChampion(long champions, int n)
{
int kThFoundChampion = 0;

View File

@@ -1,3 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using Assets.Data;
using TMPro;
@@ -20,33 +21,50 @@ public class TraitSelectorManager : MonoBehaviour
[SerializeField]
private int _traitThreshold = 7;
private Dictionary<TraitsEnum, int> emblemList;
public void ListAllActivableCompo()
{
emblemList = _emblemSelector.GetEmblems();
var emblemList = _emblemSelector.GetEmblems();
var mandatoryChampions = ChampionUtils.ToLong(_mandatorychampionSelector.GetSelectedChampions());
var acceptableChampions = ChampionUtils.ToLong(_acceptablechampionSelector.GetSelectedChampions());
int compositionSize = _compositionSize.text == "" ? 1 : int.Parse(_compositionSize.text);
var composition = TraitsMapping.GenerateCombinations(mandatoryChampions, acceptableChampions, compositionSize);
Coroutine coroutine = StartCoroutine(TraitsMapping.DisplayCompositions(composition));
//var coroutine = StartCoroutine(TraitsMapping.GetChampionSubsetsAsync(champList, compositionSize,emblemList, HandleCombination));
Coroutine coroutine = StartCoroutine(ComputeCompositionAsync(mandatoryChampions, acceptableChampions, compositionSize, emblemList));
}
public IEnumerator<float> ComputeCompositionAsync(long mandatoryChampions, long acceptableChampions, int compositionSize, Dictionary<int, int> emblemList)
{
var compositions = TraitsMapping.GenerateCombinations(mandatoryChampions, acceptableChampions, compositionSize);
Debug.Log($"{compositions.Count} Compositions generated.");
yield return 0f;
foreach (var composition in compositions)
{
HandleCombination(composition, emblemList);
yield return 0f;
}
}
private void HandleCombination(long combination)
private void HandleCombination(long combination, Dictionary<int, int> emblemList)
{
// var synergies = TraitsMapping.MergeEmblems(
// TraitsMapping.TraitCountInCompo(combination),
// emblemList
// );
// var activeSynergies = TraitsMapping.FilterActiveTraits(synergies);
// if (TraitUtils.TraitCountFromInt(activeSynergies) >= _traitThreshold)
// {
// var s = TraitsMapping.CompositionToString(combination, activeSynergies);
// Debug.Log(s);
// } else {
// Debug.LogWarning("Combination not valid");
// }
var synergies = TraitsMapping.TraitCountInCompo(combination);
var synergiesWithEmblem = TraitsMapping.MergeEmblems(
synergies,
emblemList
);
var activeSynergies = TraitsMapping.FilterActiveTraits(synergiesWithEmblem);
if (TraitUtils.TraitCountFromInt(activeSynergies) >= _traitThreshold)
{
HashSet<ChampionsEnum> champions = ChampionUtils.FromLong(combination);
var s = TraitsMapping.CompositionToString(champions);
Debug.Log(s);
}
// else
// {
// //Debug.LogWarning("Combination not valid");
// }
}
}

View File

@@ -826,14 +826,14 @@ namespace Assets.Data
},
};
public static Dictionary<int, int> minimalActivation = TraitsSteps.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value[0]
);
public static int GetMinimalActivation(int trait)
{
return TraitsSteps[trait][0];
}
public bool TraitEnabled(int trait, int traitChampCount)
{
return traitChampCount >= minimalActivation[trait];
return traitChampCount >= GetMinimalActivation(trait);
}
/// <summary>
@@ -844,24 +844,24 @@ namespace Assets.Data
public static Dictionary<int, int> TraitCountInCompo(long compo)
{
Dictionary<int, int> synergies = new Dictionary<int, int>();
for (int i = 0; i < 64; i++)
for (int i = 0; i < 60; i++)
{
if ((compo & (1L << i)) != 0)
{
var champ = (long)i;
var champ = (long)(1L << i);
var traits = ChampsTraits[champ];
// combine the traits within synergies using bitwise operation
for (int trait = 0; trait < 22; trait++)
{
if ((traits & (1 << trait)) != 0)
{
if (synergies.ContainsKey(trait))
if (synergies.ContainsKey(1 << trait))
{
synergies[trait]++;
synergies[1 << trait]++;
}
else
{
synergies.Add(trait, 1);
synergies.Add(1 << trait, 1);
}
}
}
@@ -882,7 +882,7 @@ namespace Assets.Data
int output = 0;
foreach (var kvp in synergies)
{
if (kvp.Value >= minimalActivation[kvp.Key])
if (kvp.Value >= GetMinimalActivation(kvp.Key))
{
output |= kvp.Key;
}
@@ -910,11 +910,6 @@ namespace Assets.Data
return mergedEmblems;
}
void Start()
{
}
public void DisplayTraits(Dictionary<TraitsEnum, int> traits)
{
@@ -934,139 +929,6 @@ namespace Assets.Data
return sb.ToString();
}
// public static IEnumerator GetChampionSubsetsAsync(
// long possibleChamp,
// long mandatoryChamps,
// int size,
// Dictionary<int, int> emblemList,
// System.Action<long> onCombinationGenerated
// )
// {
// List<long> possibleChampList = new List<long>();
// foreach (var champ in ChampsTraits.Keys)
// {
// if ((possibleChamp & champ) != 0)
// {
// possibleChampList.Add(champ);
// }
// }
// int n = possibleChampList.Count;
// }
/// <summary>
/// Create a list of compositions based on the possible champions, mandatory champions, size of the composition, and the list of emblems.
/// each composition much contain all mandatory champs, and can contain any number of possible champs.
/// No other champions are allowed in the composition.
/// Composition is stored in the shape of a long, where each bit represents a champion.
///
/// </summary>
/// <param name="possibleChamp"></param>
/// <param name="mandatoryChamps"></param>
/// <param name="size"></param>
/// <param name="emblemList"></param>
/// <param name="onCombinationGenerated"></param>
// /// <returns></returns>
// public static List<long> GetCompositionList(
// long possibleChamp,
// long mandatoryChamps,
// int size,
// Dictionary<int, int> emblemList,
// System.Action<long> onCombinationGenerated
// )
// {
// Dictionary<int,int> allTraits = emblemList;
// int alreadySelectionChampCount = mandatoryChamps.CountSetBits();
// }
public static List<HashSet<ChampionsEnum>> GetChampionSubsets(
HashSet<ChampionsEnum> champs,
int size
)
{
List<HashSet<ChampionsEnum>> result = new List<HashSet<ChampionsEnum>>();
if (size == 0)
{
result.Add(new HashSet<ChampionsEnum>());
return result;
}
List<ChampionsEnum> 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<ChampionsEnum> subset = new HashSet<ChampionsEnum>();
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<HashSet<ChampionsEnum>> GetChampionSubsetsRec(
HashSet<ChampionsEnum> champs,
int size
)
{
List<HashSet<ChampionsEnum>> result = new List<HashSet<ChampionsEnum>>();
if (size == 0)
{
result.Add(new HashSet<ChampionsEnum>());
return result;
}
if (champs.Count == 0)
{
return result;
}
ChampionsEnum first = champs.First();
HashSet<ChampionsEnum> rest = new HashSet<ChampionsEnum>(champs);
rest.Remove(first);
List<HashSet<ChampionsEnum>> subResult = GetChampionSubsetsRec(rest, size - 1);
foreach (var set in subResult)
{
set.Add(first);
}
result.AddRange(subResult);
result.AddRange(GetChampionSubsetsRec(rest, size));
return result;
}
public static int MaxIntForCombinationOfn(int n)
{
@@ -1116,22 +978,9 @@ namespace Assets.Data
Assert.IsTrue(champToSelectCount >= 0); // else we have too many mandatory champs
HashSet<long> combinations = BitWise.GetAllPermutation(champToSelectCount, possibleChampCount);
foreach (var combinationOfPossibleChamps in combinations)
{
// generating one composition based on the combination.
// combination 10010 will add the second and fifth champion of the possibleChamps list to the composition.
long composition = mandatoryChamps;
int possibleChampIterator = 0;
int kThChampFound = 0;
while (possibleChampIterator < champToSelectCount)
{
if ((combinationOfPossibleChamps & (1 << possibleChampIterator)) != 0)
{
long champ = ChampionUtils.GetNthChampion(possibleChamps,kThChampFound);
composition |= champ;
kThChampFound++;
}
possibleChampIterator++;
}
{
var composition = SelectSublistOfChampion(possibleChamps, combinationOfPossibleChamps);
composition |= mandatoryChamps;
compositions.Add(composition);
}
return compositions;
@@ -1149,5 +998,22 @@ namespace Assets.Data
yield return null;
}
}
public static long SelectSublistOfChampion(long accessibleChampions, long subselectedChampions)
{
var champs = ChampionUtils.FromLong(accessibleChampions).ToList<ChampionsEnum>();
// this list of champ is ordered. I want to filter this with the subselectedChampions bit flag
// where all bit to 1 are the champions I want to keep, and all bit to 0 are the champions I want to remove
HashSet<ChampionsEnum> selectedChamps = new HashSet<ChampionsEnum>();
for (int i = 0; i < champs.Count; i++)
{
if ((subselectedChampions & (1L << i)) != 0)
{
selectedChamps.Add(champs[i]);
}
}
return ChampionUtils.ToLong(selectedChamps);
}
}
}