private double EvaluatePotentialValue(Horse horse, TraitValuator valuator, HorseTrait trait)
 {
     double result = 0;
     if (trait.IsUnknownForThisHorse(horse))
     {
         var traitval = trait.GetTraitValue(valuator);
         if (traitval > 0)
         {
             result += traitval * _options.PotentialValuePositiveWeight;
         }
         else if (traitval < 0)
         {
             result += traitval * _options.PotentialValueNegativeWeight;
         }
         // we dont care when its 0
     }
     return result;
 }
 /// <summary>
 /// get evaluation results for these horse,
 /// null if evaluation does not return any valid results
 /// </summary>
 /// <param name="horse1">first evaluated horse</param>
 /// <param name="horse2">other evaluated horse</param>
 /// <param name="valuator">current trait valuator used by granger</param>
 /// <returns></returns>
 public abstract BreedingEvalResults? Evaluate(Horse horse1, Horse horse2, TraitValuator valuator);
        public override BreedingEvalResults? Evaluate(Horse horse1, Horse horse2, TraitValuator valuator)
        {
            if (horse1 == horse2) return null;

            BreedingEvalResults results = new BreedingEvalResults();

            var allPossibleTraits = HorseTrait.GetAllPossibleTraits();
            var traits1 = horse1.Traits;
            var traits2 = horse2.Traits;
            var concatTraits = traits1.Concat<HorseTrait>(traits2).ToArray(); //horse1 + horse2
            var presentTraits = concatTraits.Distinct().ToArray(); //horse1 + horse2 but without duplicates
            // not using these for now:
            //var uniqueTraits = GetUniqueTraits(presentTraits, traits1, traits2);  //traits which only one horse have
            //var missingTraits = HorseTrait.GetAllTraits().Where(x => !presentTraits.Contains(x)).ToArray(); //all traits that horses dont have
            double value2 = horse2.Value;

            if (horse1.IsMale == horse2.IsMale) results.Ignored = true;

            if (_options.IgnoreNotInMood)
                if (horse1.NotInMood || horse2.NotInMood) results.Ignored = true;

            if (_options.IgnorePregnant)
                if (horse1.Pregnant || horse2.Pregnant) results.Ignored = true;

            if (_options.IgnoreRecentlyPregnant)
                if (horse1.PregnantInLast24h || horse2.PregnantInLast24h) results.Ignored = true;

            if (_options.IgnoreOtherHerds)
                if (horse1.Herd != horse2.Herd) results.Ignored = true;

            if (_options.IgnorePairedHorses)
                if (horse1.HasMate() || horse2.HasMate())
                    results.Ignored = true;

            if (_options.IgnoreSold)
                if (horse1.CheckTag("sold") || horse2.CheckTag("sold"))
                    results.Ignored = true;

            if (_options.IgnoreDead)
                if (horse1.CheckTag("dead") || horse2.CheckTag("dead"))
                    results.Ignored = true;

            if (_options.IgnoreFoals)
                if ((horse1.IsFoal() && !_options.AgeIgnoreOnlyOtherHorses) ||
                    horse2.IsFoal()) results.Ignored = true;

            if (_options.IgnoreYoung)
                if (((horse1.Age.EnumVal == HorseAge.Age.Young) && !_options.AgeIgnoreOnlyOtherHorses) ||
                    horse2.Age.EnumVal == HorseAge.Age.Young)
                    results.Ignored = true;

            if (_options.IgnoreAdolescent)
                if (((horse1.Age.EnumVal == HorseAge.Age.Adolescent) && !_options.AgeIgnoreOnlyOtherHorses) ||
                    horse2.Age.EnumVal == HorseAge.Age.Adolescent)
                    results.Ignored = true;

            if (_options.ExcludeExactAgeEnabled)
            {

                if (DateTime.Now - horse1.BirthDate < _options.ExcludeExactAgeValue ||
                    DateTime.Now - horse2.BirthDate < _options.ExcludeExactAgeValue)
                {
                    results.Ignored = true;
                }
            }

            if (horse1.IsInbreedWith(horse2))
            {
                if (_options.DiscardOnInbreeding) results.Discarded = true;
                else
                {
                    // get all potential inbreeding-specific bad traits this horse doesnt yet have,
                    // average a value out of these traits,
                    // multiply by 2 (because this is like both horses having one bad trait)
                    // multiply by inbreed weight (NOT bad trait weight)
                    // we add this to results
                    var potentialBadTraits = HorseTrait.GetInbreedBadTraits().Where(x => !presentTraits.Contains(x)).ToArray();
                    double sum = 0;
                    foreach (var trait in potentialBadTraits)
                    {
                        sum += trait.GetTraitValue(valuator);
                    }
                    sum /= potentialBadTraits.Length;
                    sum *= _options.InbreedingPenaltyWeight * 2;
                    results.Value += sum;
                }
            }

            if (_options.DiscardOnAnyNegativeTraits)
            {
                if (horse2.Traits.Where(x => x.GetTraitValue(valuator) < 0).Count() > 0)
                    results.Discarded = true;
            }

            // continue only if horse is still evaluated
            if (results.Discarded != true && results.Ignored != true)
            {
                // calculate value for each trait:
                // use 1.0, bad trait or unique trait weights if appropriate
                // use dict to check, which traits were already handled, 
                // the value of keys is meaningless, only key presence check is needed
                Dictionary<HorseTrait, int> uniqueTraitCounter = new Dictionary<HorseTrait, int>();
                foreach (var trait in concatTraits)
                {
                    //add this trait to counter for PreferUniqueTraits
                    if (uniqueTraitCounter.ContainsKey(trait))
                    {
                        uniqueTraitCounter[trait] += 1;
                    }
                    else
                    {
                        uniqueTraitCounter[trait] = 1;
                    }
                    var traitval = trait.GetTraitValue(valuator);
                    double result = 0;
                    if (traitval < 0) result += traitval * _options.BadTraitWeight;
                    else if (traitval > 0) result += traitval;

                    results.Value += result;
                }

                //apply bonus for unique traits
                if (_options.PreferUniqueTraits)
                {
                    foreach (var keyval in uniqueTraitCounter)
                    {
                        if (keyval.Value == 1) //this trait was unique in this evaluation
                        {
                            var traitval = keyval.Key.GetTraitValue(valuator);
                            if (traitval > 0) //apply bonus if the trait is positive value
                            {
                                results.Value += (traitval * _options.UniqueTraitWeight) - traitval;
                                //subtracting initial traitval because it was already applied
                                //this works for any weight, a 0.5 weight causes unique trait to have half value for result
                                //0.0 weight causes trait to have 0 value for result (effectively nullifying this trait value)

                                // NOTE: if in future good trait value has any other weights applied,
                                // this WILL break. This class is not expected to be improved,
                                // please write your own, new evaluator by subclassing BreedingEvaluator class
                                // and writing your own complete logic!
                            }
                        }
                    }

                }

                if (_options.IncludePotentialValue)
                {
                    // here we need to take care of potential trait values
                    // this is hard to figure, because horse can contain many different hidden traits,
                    // that all can participate in breeding

                    // we handle this naively, asume horses have all of their potential traits
                    // we regulate how much this affects result with the weight

                    // we need to loop over all possible traits twice, for each horse
                    // pick traits that req AH above their inspect skill and do eval for these
                    // we do this explicitly rather than in methods to improve readability
                    foreach (var trait in allPossibleTraits)
                    {
                        double result = 0;
                        result += EvaluatePotentialValue(horse1, valuator, trait);
                        result += EvaluatePotentialValue(horse2, valuator, trait);
                        results.Value += result;
                    }
                }

                // boost or lower value based on potential color of offspring
                if (results.Value > 0)
                {
                    var h1colVal = _options.GetValueForColor(horse1.Color);
                    var h2colVal = _options.GetValueForColor(horse2.Color);
                    var colValAdj = (h1colVal + h2colVal)*0.5f;
                    results.Value *= colValAdj;
                }
            }
            return results;
        }
 void RefreshValuator()
 {
     try
     {
         CurrentValuator = new TraitValuator(this, comboBoxValuePreset.Text, Context);
     }
     catch (Exception _e)
     {
         CurrentValuator = new TraitValuator(this);
         Logger.LogError("failed to create TraitValuator for valuemapid: " + comboBoxValuePreset.Text + "; using defaults", this, _e);
     }
     Settings.Value.ValuePresetID = CurrentValuator.ValueMapID;
     Settings.DelayedSave();
     if (Granger_ValuatorChanged != null) Granger_ValuatorChanged(this, new EventArgs());
 }
Beispiel #5
0
 internal static HorseTrait[] GetBadTraits(HorseTrait[] traits, TraitValuator traitValuator)
 {
     return traits.Where(x => x.GetTraitValue(traitValuator) < 0).ToArray();
 }
Beispiel #6
0
 internal static string GetShortString(HorseTrait[] traits, TraitValuator valuator)
 {
     List<string> shorts = new List<string>();
     foreach (var trait in traits)
     {
         int value = 0;
         if (valuator != null) value = valuator.GetValueForTrait(trait);
         shorts.Add(Helper.GetShortcutForTrait(trait, value));
     }
     return string.Join(",", shorts.OrderBy(x => x));
 }
Beispiel #7
0
 /// <summary>
 /// Get value of this trait in given value context
 /// </summary>
 /// <param name="valueContextID"></param>
 /// <returns></returns>
 public int GetTraitValue(TraitValuator traitvaluator)
 {
     return traitvaluator.GetValueForTrait(this);
 }