예제 #1
0
        internal string[] GetGroupBinding(float intendedDifficulty, TrackedValue[] currentValues, int totalSelections)
        {
            if (!m_isGroupBinding)
            {
                CFLog.SendMessage("Trying to get group selection on individual selection. Returning null.", MessageType.ERROR);
                return(null);
            }
            StringBuilder sb = new StringBuilder();

            sb.Append("Beginning Group Query:\n Individual Values:\n");
            //Precalculate all of the output's results
            m_outputList.ForEach(o => o.CalculateDifficulty(currentValues, sb));
            //Try combinations until we find one of size n with the closest value to intendedDifficulty
            m_recursiveBestValue = float.MaxValue;
            m_recursiveBestArray = new int[totalSelections];
            GetBestGroupBinding(0, 0, totalSelections, new int[totalSelections], intendedDifficulty);
            string[] output = new string[totalSelections];
            sb.Append("Group Query Returning:\n");
            for (int j = 0; j < totalSelections; j++)
            {
                output[j] = m_outputList[m_recursiveBestArray[j]].returnString;
                sb.Append('\t');
                sb.Append(m_recursiveBestArray[j]);
                sb.Append(':');
                sb.Append(output[j]);
                sb.Append('\n');
            }
            sb.Append("With total difficulty delta of ");
            sb.Append(m_recursiveBestValue);
            CFLog.SendMessage(sb.ToString(), MessageType.STATUS);
            return(output);
        }
예제 #2
0
 private void GetBestGroupBinding(int listIndex, int arrIndex, int remainingSelections, int[] current, float diff)
 {
     remainingSelections--;
     if (remainingSelections == -1)
     {
         //Has reached the bottom (and current is filled with all values)
         //Sum the values
         float total = 0.0f;
         for (int j = 0; j < current.Length; j++)
         {
             total += m_outputList[current[j]].lastDifficulty;
         }
         float delta = Math.Abs(diff - total);
         CFLog.SendMessage(delta.ToString("G"), MessageType.DEBUG);
         if (delta < m_recursiveBestValue)
         {
             //Don't do the repeat checking math if the number is already too high
             //Technically this means that repeat mods of less than 1 won't work
             if (m_allowGroupDuplicates)
             {
                 int dupeCount = current.Length - current.Distinct().Count();
                 if (dupeCount != 0)
                 {
                     delta *= (dupeCount * m_groupRepeatMultiplier);
                 }
                 if (delta > m_recursiveBestValue)
                 {
                     return;
                 }
             }
             m_recursiveBestValue = delta;
             current.CopyTo(m_recursiveBestArray, 0);
         }
     }
     else
     {
         if (m_allowGroupDuplicates)
         {
             for (int j = listIndex; j < m_outputList.Count; j++)
             {
                 //Recurses for every possible case this number can be
                 //Since in a list of 5, 444 is valid output, top number *can* be 3 or 4
                 current[arrIndex] = j;
                 GetBestGroupBinding(j, arrIndex + 1, remainingSelections, current, diff);
             }
         }
         else
         {
             for (int j = listIndex; j < m_outputList.Count - remainingSelections; j++)
             {
                 //Recurses for every possible case this number can be
                 //IE with an output count of 5 and a selection of 3, top number can never be 3 or 4
                 current[arrIndex] = j;
                 GetBestGroupBinding(j + 1, arrIndex + 1, remainingSelections, current, diff);
             }
         }
     }
 }
예제 #3
0
 internal void SetValue(string name, float value)
 {
     if (!m_profile.ContainsKey(name))
     {
         CFLog.SendMessage(name + " is not a registered value.", MessageType.ERROR);
         return;
     }
     m_profile[name].SetValue(value);
 }
예제 #4
0
 internal TrackedValue GetTrackedValue(string name)
 {
     if (!m_profile.ContainsKey(name))
     {
         CFLog.SendMessage(name + " is not a registered value.", MessageType.ERROR);
         return(null);
     }
     return(m_profile[name]);
 }
예제 #5
0
        public OutputQuery(string xmlString)
        {
            m_outputList = new List <Output>();
            //Parses the file back into an object
            //TODO try catch
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(xmlString);
            m_name = doc.SelectSingleNode("/Query").Attributes["Name"].InnerText;
            //Do things on the settings node here
            var repeatNodes = doc.SelectSingleNode("/Query/Settings/RepeatSelection");

            m_discourageRepeatSelection = repeatNodes.Attributes["Enabled"].InnerText == "True";
            if (m_discourageRepeatSelection)
            {
                m_repeatSelectionWeight = float.Parse(repeatNodes["RepeatSelectionWeight"].InnerText);
                m_previousTrackedValues = int.Parse(repeatNodes["PreviousValuesTracked"].InnerText);
                m_diminishingWeight     = bool.Parse(repeatNodes["DiminishingWeight"].InnerText);
            }

            var groupNodes = doc.SelectSingleNode("/Query/Settings/GroupBinding");

            m_isGroupBinding = groupNodes.Attributes["Enabled"].InnerText == "True";
            if (m_isGroupBinding)
            {
                m_allowGroupDuplicates = bool.Parse(groupNodes["AllowDuplicates"].InnerText);
            }

            //Load the outputs
            var outputNodes = doc.SelectNodes("/Query/Output");

            foreach (XmlNode node in outputNodes)
            {
                Output outputObject = new Output(m_nextID, node["Name"].InnerText);
                m_nextID++;
                var skillNodes = node.SelectNodes("Skill");
                foreach (XmlNode skillNode in skillNodes)
                {
                    Weight weight = new Weight
                    {
                        value      = float.Parse(skillNode["Value"].InnerText),
                        multiplier = float.Parse(skillNode["Weight"].InnerText)
                    };
                    outputObject.queryValues.Add(skillNode["Name"].InnerText, weight);
                }
                m_outputList.Add(outputObject);
            }
            var lockNodes = doc.SelectSingleNode("/Query/Settings/SelectionLock");

            m_enableSelectionLock = lockNodes.Attributes["Enabled"].InnerText == "True";
            CFLog.SendMessage("XML Successfully Loaded.", MessageType.STATUS);
        }
예제 #6
0
        internal void AppendValue(float nextValue)
        {
            float oldValue = m_currentValue;

            switch (m_type)
            {
            case ValueType.ADDITIVE:
                SetCurrentValueInBounds(m_currentValue + nextValue);
                m_additionCount++;
                break;

            case ValueType.AVERAGE:
                m_currentValue = ((m_currentValue * m_additionCount) + nextValue) / (m_additionCount + 1);
                m_additionCount++;
                break;

            case ValueType.SET:
                //Log error
                CFLog.SendMessage("Tried to append to set only value: " + m_name, MessageType.ERROR);
                break;

            case ValueType.AVERAGEWEIGHTED:
                //Use addition count as a max. Count current value as additionCount - 1 then add new value/addition count
                m_currentValue = ((m_currentValue * (m_additionCount - 1)) + nextValue) / m_additionCount;
                break;
            }
            StringBuilder sb = new StringBuilder();

            sb.Append(m_name);
            sb.Append(" Old Value: ");
            sb.Append(oldValue.ToString("G"));
            sb.Append(" New Value: ");
            sb.Append(m_currentValue);
            sb.Append(" Type: ");
            sb.Append(m_type);

            CFLog.SendMessage(sb.ToString(), MessageType.STATUS);
        }
예제 #7
0
        internal string CalculateOptimalSelection(float intendedDifficulty, CFProfile profile)
        {
            if (m_isGroupBinding)
            {
                CFLog.SendMessage("Trying to calculate single selection on group binding. Continuing...", MessageType.ERROR);
            }
            StringBuilder sb = new StringBuilder();

            TrackedValue[] currentValues    = profile.GetAllValues();
            float          currentBestDelta = float.MaxValue;
            int            currentBestIndex = -1;

            for (int j = 0; j < m_outputList.Count; j++)
            {
                if (m_enableSelectionLock && profile.IsOutputLocked(m_name, m_outputList[j].returnString))
                {
                    sb.Append("Selection Locked: ");
                    sb.Append(m_outputList[j].returnString);
                    sb.Append("\n");
                    continue;
                }
                float difficulty = m_outputList[j].CalculateDifficulty(currentValues, sb);
                float delta      = Math.Abs(intendedDifficulty - difficulty);
                sb.Append("Delta: ");
                sb.Append(delta);
                sb.Append('\n');
                //This needs to mod delta, not difficulty
                if (m_discourageRepeatSelection)
                {
                    int position = m_previousValues.IndexOf(m_outputList[j].id);
                    //If the ID is in the previous list
                    if (position != -1)
                    {
                        if (m_diminishingWeight)
                        {
                            position = m_previousTrackedValues - position;
                            delta   += delta * m_repeatSelectionWeight *
                                       //Ie if this object is 3rd in a 3 object list, 3/3 weight applied
                                       (position + 1) / m_previousTrackedValues;
                        }
                        else
                        {
                            delta *= m_repeatSelectionWeight;
                        }
                        sb.Append("\tIn previous Selection at Index ");
                        sb.Append(position);
                        sb.Append(". Modded to ");
                        sb.Append(delta);
                        sb.Append("\n");
                    }
                }
                if (delta < currentBestDelta)
                {
                    currentBestDelta = delta;
                    currentBestIndex = j;
                }
            }
            if (m_discourageRepeatSelection)
            {
                //Removes the value if it has already been placed into the queue
                m_previousValues.Remove(m_outputList[currentBestIndex].id);
                m_previousValues.Insert(0, m_outputList[currentBestIndex].id);
                //If the queue has exceded its count
                if (m_previousValues.Count > m_previousTrackedValues)
                {
                    m_previousValues.RemoveAt(m_previousTrackedValues);
                }
            }
            sb.Append("Query Returning ");
            sb.Append(m_outputList[currentBestIndex].returnString);
            sb.Append(" delta: ");
            sb.Append(currentBestDelta);
            CFLog.SendMessage(sb.ToString(), MessageType.STATUS);
            if (m_enableSelectionLock)
            {
                profile.LockOutput(m_name, m_outputList[currentBestIndex].returnString);
            }
            return(m_outputList[currentBestIndex].returnString);
        }
예제 #8
0
 /// <summary>
 /// Sets up CurveFlow's logging system to a custom callback function
 /// </summary>
 /// <param name="log">The Callback function where the string will be pushed</param>
 /// <param name="messageTypeMask">Bitmask of the MessageTypes that will be sent</param>
 public void InitializeLog(LogCallback log, MessageType messageTypeMask)
 {
     CFLog.SetupLog(messageTypeMask, log);
 }