void Awake() { singleCharas = new HashSet <SingleChara>(); allSingles = new CrossList <SingleChara>(); allKeys = new Dictionary <KeyCode, string>(); allKeys[KeyCode.A] = "A"; allKeys[KeyCode.B] = "B"; allKeys[KeyCode.C] = "C"; allKeys[KeyCode.D] = "D"; allKeys[KeyCode.E] = "E"; allKeys[KeyCode.F] = "F"; allKeys[KeyCode.G] = "G"; allKeys[KeyCode.H] = "H"; allKeys[KeyCode.I] = "I"; allKeys[KeyCode.J] = "J"; allKeys[KeyCode.K] = "K"; allKeys[KeyCode.L] = "L"; allKeys[KeyCode.M] = "M"; allKeys[KeyCode.N] = "N"; allKeys[KeyCode.O] = "O"; allKeys[KeyCode.P] = "P"; allKeys[KeyCode.Q] = "Q"; allKeys[KeyCode.R] = "R"; allKeys[KeyCode.S] = "S"; allKeys[KeyCode.T] = "T"; allKeys[KeyCode.U] = "U"; allKeys[KeyCode.V] = "V"; allKeys[KeyCode.W] = "W"; allKeys[KeyCode.X] = "X"; allKeys[KeyCode.Y] = "Y"; allKeys[KeyCode.Z] = "Z"; score = 0; }
/// <summary> /// Called by BasicCross/distance crosses to encapsulate final CrossList build. Do not call elsewhere. /// </summary> /// <param name="p_possibilities">.</param> /// <param name="p_count">.</param> /// <returns>A built CrossList</returns> private CrossList FinishCross(List<CrossTrait> p_possibilities, int p_count) { CrossList returnList = new CrossList(); returnList.Traits = p_possibilities.ToArray(); returnList.Count = p_count; return returnList; }
/// <summary> /// Turns a list of crosses into all possible fly trait combinations /// </summary> /// <param name="p_crosses">An array of cross possibilities</param> /// <returns>A phatty sorted list of trait combinations</returns> private List<List<CrossTrait>> CombineTraits(CrossList[] p_crosses) { //CHECK FOR DISTANCE BASED CROSSING IN HERE //combine an indiscriminate number of crosslists into a list of lists of possible combos w rates attached //use array bc its easier to access these by index in query syntax implementation of Cartesian Product CrossList[] non_wild = p_crosses.Where(t => t.Traits.Count(u => u.Trait.Name.ToLower() != "wild") != 0).ToArray(); //use list so addrange works almost natively List<CrossTrait> wild = p_crosses.Where(t => !non_wild.Contains(t)).Select(g => g.Traits[0]).ToList(); List<List<CrossTrait>> r_lists = new List<List<CrossTrait>>(); List<CrossTrait> building = null; int num_of_lists = non_wild.Length; if (num_of_lists == 0) { //if there are no non wilds the flies will be 100% wild-type no variance r_lists.Add(wild); } if (num_of_lists == 1) { //add all non wilds then concatenate wilds onto them List<CrossTrait> split = (from trait in non_wild[0].Traits select trait).ToList(); foreach (CrossTrait current in split.ToList()) { building = new List<CrossTrait>(); building.Add(current); building.AddRange(wild.AsEnumerable()); r_lists.Add(building.OrderBy(t => t.Trait.CategoryId).ToList()); } } if (num_of_lists == 2) { //cartesian product of 2 lists //this syntax courtesy of Eric Lippert's MSDN blog //Selects 1 element from each list, makes combo, //iterates to next item in first list until all combos //are made and starts iterating thru next list /*EX: * list1 = { A, B, C } * list2 = { 1, 2, 3 } * cartesian(list1, list2) = { {A, 1}, {B, 1}, {C, 1}, * {A, 2}, {B, 2}, {C, 2}, * {A, 3}, {B, 3}, {C, 3} } */ var split = (from trait1 in non_wild[0].Traits from trait2 in non_wild[1].Traits select new { trait1, trait2 }); foreach (var current in split) { building = new List<CrossTrait>(); building.Add(current.trait1); building.Add(current.trait2); building.AddRange(wild.AsEnumerable()); r_lists.Add(building.OrderBy(t => t.Trait.CategoryId).ToList()); } } if (num_of_lists == 3) { //cartesian product of 3 lists //same concept as 2 list syntax and implementation but w a third layer var split = (from trait1 in non_wild[0].Traits from trait2 in non_wild[1].Traits from trait3 in non_wild[2].Traits select new { trait1, trait2, trait3 }); foreach (var current in split) { building = new List<CrossTrait>(); building.Add(current.trait1); building.Add(current.trait2); building.Add(current.trait3); building.AddRange(wild.AsEnumerable()); r_lists.Add(building.OrderBy(t => t.Trait.CategoryId).ToList()); } } return r_lists; }
/// <summary> /// Main workhorse for the cross engine, actually arranges the results of the cross methods /// </summary> /// <param name="p_module">Call ID of module in use</param> /// <param name="p_offspring">Total number of offspring to create</param> /// <param name="p_generation">Which generation of fly is being created (1 or 2)</param> /// <param name="p_cross_results"></param> /// <returns></returns> private List<FlyViewModel> BuildChildren(int p_module, int p_offspring, int p_generation, CrossList[] p_cross_results) { //parse all lists and calculate total required flies from counts List<FlyViewModel> r_flies = new List<FlyViewModel>(); //try something different List<List<CrossTrait>> all_possible_combinations = CombineTraits(p_cross_results); //need to iterate thru and build some flyviewmodels, we can make records later FlyViewModel cur = null; foreach (List<CrossTrait> working_set in all_possible_combinations) { //check for chromosome matches in case of module == 2 or 3 //then perform distance crosses if (working_set.Count(t => t.DistanceBased) > 0 && p_module > 2) { //iterate thru list and format appropriately //make non-distance list first List<ReducedTraitModel> reg_traits = working_set.Where(t => !t.DistanceBased).Select(g => new ReducedTraitModel(g.Trait)).ToList(); List<ReducedTraitModel> dis_traits = working_set.Single(t => t.DistanceBased).DistanceCrossedTraits.Select(g => new ReducedTraitModel(g)).ToList(); List<ReducedTraitModel> fin_traits = new List<ReducedTraitModel>(); fin_traits.AddRange(reg_traits); fin_traits.AddRange(dis_traits); //create freqs double male_freq = .5 * p_offspring; double female_freq = .5 * p_offspring; foreach (CrossTrait traversing in working_set) { male_freq *= (traversing.Male) ? traversing.Rate : 0; female_freq *= (traversing.Female) ? traversing.Rate : 0; } cur = new FlyViewModel() { Traits = fin_traits.OrderBy(t => t.CategoryId).ToArray(), Frequency = (int)male_freq, Gender = Constants.Male }; r_flies.Add(cur); cur = new FlyViewModel() { Traits = fin_traits.OrderBy(t => t.CategoryId).ToArray(), Frequency = (int)female_freq, Gender = Constants.Female }; r_flies.Add(cur); } else { cur = new FlyViewModel() { Traits = working_set.Select(g => new ReducedTraitModel(g.Trait)).ToArray(), Frequency = (int)(.5 * working_set.Aggregate(p_offspring, (a, b) => (int)(a * (b.Male ? b.Rate : 0)))), Gender = Constants.Male }; r_flies.Add(cur); cur = new FlyViewModel() { Traits = working_set.Select(g => new ReducedTraitModel(g.Trait)).ToArray(), Frequency = (int)(.5 * working_set.Aggregate(p_offspring, (a, b) => (int)(a * (b.Female ? b.Rate : 0)))), Gender = Constants.Female }; r_flies.Add(cur); } } //need to filter out flies here SoftMatch(ref r_flies); return r_flies; }