示例#1
0
        /// <summary>
        /// Создает новую ноду описывающую конкретное действие из плана ИИ.
        /// </summary>
        private AntAIDebuggerNode CreatePlanNode(AntAIAction aAction, AntAICondition aConditions,
                                                 AntAICondition aPrevConditions, ref Vector2 aNodePosition)
        {
            AntAICondition condCopy = aConditions.Clone();

            condCopy.name = aAction.name;

            int    numLines;
            string desc = DescribePlanAction(condCopy, aPrevConditions, out numLines);

            GUIStyle style;

            if (_currentPlan.isSuccess)
            {
                style = (aAction.name.Equals(_agent.currentPlan[0])) ? _activePlanStyle : _planStyle;
            }
            else
            {
                style = (aAction.name.Equals(_agent.currentPlan[0])) ? _activeFailedPlanStyle : _failedPlanStyle;
            }

            var node = AddNode(desc, 220.0f, CalcHeight(numLines), style, style, ref aNodePosition, false);

            node.value = aAction.state;
            node.SetOutput(node.rect.width - 10.0f, node.rect.height * 0.5f);
            node.SetInput(10.0f, node.rect.height * 0.5f);

            if (_genericNodes.Count > 0)
            {
                _genericNodes[_genericNodes.Count - 1].LinkTo(node, new Color(0.3f, 0.7f, 0.4f));
            }

            _genericNodes.Add(node);
            return(node);
        }
示例#2
0
        /// <summary>
        /// Выбирает новое состояние на основе текущего состояния мира.
        /// </summary>
        public string SelectNewState(AntAICondition aWorldState)
        {
            string newState = "";

            if (currentGoal != null)
            {
                planner.MakePlan(ref currentPlan, aWorldState, currentGoal);
                if (currentPlan.isSuccess)
                {
                    string actionName = planner.GetAction(currentPlan[0]).name;
                    newState = planner.GetState(actionName);

                    /* Отладочный вывод плана в консоль.
                     * AntAICondition condition = aConditions.Clone();
                     * string p = string.Format("Conditions: {0}\n", _planner.NameIt(condition.Description()));
                     * for (int i = 0; i < _currentPlan.Count; i++)
                     * {
                     *      AntAIAction action = _planner.GetAction(_currentPlan[i]);
                     *      condition.Act(action.post);
                     *      p += string.Format("<color=orange>{0}</color> => {1}\n", action.name, _planner.NameIt(condition.Description()));
                     * }
                     * AntLog.Trace(p);
                     * //*/
                }
            }
            else
            {
                AntLog.Report("AntAIAgent", "Goal not defined!");
            }

            return(newState);
        }
示例#3
0
        public AntAICondition post;         // Current world state.

        #endregion
        #region Public Methods

        public AntAIAction(string aName, int aCost = 1)
        {
            cost  = aCost;
            name  = aName;
            state = null;
            pre   = new AntAICondition();
            post  = new AntAICondition();
        }
        private void BuildPlanHandler()
        {
            // Create planner.
            var planner = new AntAIPlanner();

            // planner.DebugMode = true;
            planner.LoadScenario(_scenario);

            // Create current world state and set current conditions.
            var current = new AntAICondition();

            current.BeginUpdate(planner);
            for (int i = 0, n = _worldState.list.Length; i < n; i++)
            {
                current.Set(_scenario.conditions.GetName(_worldState.list[i].id), _worldState.list[i].value);
            }
            current.EndUpdate();

            // Create our goal world state.
            AntAIScenarioGoal defaultGoal = null;

            for (int i = 0, n = _scenario.goals.Length; i < n; i++)
            {
                if (_scenario.goals[i].isDefault)
                {
                    defaultGoal = _scenario.goals[i];
                    break;
                }
            }

            A.Assert(defaultGoal == null, "Default goal not found!");
            if (defaultGoal == null)
            {
                return;
            }

            // Copy conditions from the scenario goal to the goal conditions.
            var goal = new AntAICondition();

            goal.BeginUpdate(planner);
            for (int i = 0, n = defaultGoal.conditions.Length; i < n; i++)
            {
                goal.Set(_scenario.conditions.GetName(defaultGoal.conditions[i].id), defaultGoal.conditions[i].value);
            }
            goal.EndUpdate();

            // Create and build the plan.
            var plan = new AntAIPlan();

            planner.MakePlan(ref plan, current, goal);

            // Call event when plan is ready.
            if (EventBuildPlan != null)
            {
                EventBuildPlan(this, plan, planner);
            }
        }
示例#5
0
 public bool IsFinished(AntAIAgent aAgent, AntAICondition aWorldState)
 {
     if (_isFinished || OverlapInterrupts(aAgent.planner, aWorldState))
     {
         Reset();
         return(true);
     }
     return(false);
 }
示例#6
0
 /// <summary>
 /// Устанавливает указанную цель как текущую.
 /// </summary>
 public void SetGoal(string aGoalName)
 {
     currentGoal = FindGoal(aGoalName);
     if (currentGoal == null)
     {
         AntLog.Report("AIControl", "Can't find \"{0}\" goal.", aGoalName);
         SetDefaultGoal();
     }
 }
示例#7
0
        public AntAICondition defaultGoal;           // Цель по умолчанию.

        public AntAIAgent()
        {
            sense        = null;
            currentState = null;
            defaultState = null;
            worldState   = new AntAICondition();
            planner      = new AntAIPlanner();
            currentPlan  = new AntAIPlan();
            currentGoal  = null;
        }
示例#8
0
 /// <summary>
 /// Устанавливает цель по умолчанию как текущее.
 /// </summary>
 public void SetDefaultGoal()
 {
     if (defaultGoal != null)
     {
         currentGoal = defaultGoal;
     }
     else
     {
         AntLog.Report("AIControl", "Default Goal not defined!");
     }
 }
 private int FindEqual(List <AntAINode> aList, AntAICondition aCondition)
 {
     for (int i = 0, n = aList.Count; i < n; i++)
     {
         if (aList[i].world.Equals(aCondition))
         {
             return(i);
         }
     }
     return(-1);
 }
示例#10
0
 /// <summary>
 /// Устанавливает цель по умолчанию как текущее.
 /// </summary>
 public void SetDefaultGoal()
 {
     if (defaultGoal != null)
     {
         currentGoal = defaultGoal;
     }
     else
     {
         AntLog.Report("AntAIAgent", "Default <b>Goal</b> is not defined!");
     }
 }
示例#11
0
        private void UpdatePlan(Vector2 aNodePosition, out float aMaxHeight)
        {
            for (int i = 0, n = _genericNodes.Count; i < n; i++)
            {
                _genericNodes[i].isActive = false;
            }

            aMaxHeight = 0.0f;
            int curIndex = 0;
            AntAIDebuggerNode node;

            if (_genericNodes.Count > 0)
            {
                node = _genericNodes[curIndex];
                UpdateWorldStateNode(_agent.planner.debugConditions, node);
                node.isActive    = true;
                node.rect.x      = aNodePosition.x;
                aNodePosition.x += node.rect.width;
            }
            else
            {
                node = CreateWorldStateNode(_agent.planner.debugConditions, ref aNodePosition);
            }

            curIndex++;
            AntAIAction    action;
            AntAICondition conditions = _agent.planner.debugConditions;
            AntAICondition prevConditions;

            for (int i = 0, n = _currentPlan.Count; i < n; i++)
            {
                action         = _agent.planner.GetAction(_currentPlan[i]);
                prevConditions = conditions.Clone();
                conditions.Act(action.post);
                if (curIndex < _genericNodes.Count)
                {
                    node = _genericNodes[curIndex];
                    UpdatePlanNode(action, conditions, prevConditions, node);
                    node.isActive    = true;
                    node.rect.x      = aNodePosition.x;
                    aNodePosition.x += node.rect.width;
                }
                else
                {
                    node = CreatePlanNode(action, conditions, prevConditions, ref aNodePosition);
                }

                aMaxHeight = (node.rect.height > aMaxHeight)
                                        ? node.rect.height
                                        : aMaxHeight;
                curIndex++;
            }
        }
        /// <summary>
        /// Gets goal by goal name.
        /// </summary>
        /// <param name="aGoalName">Goal name.</param>
        /// <returns>Returns goal by name. If goal not found, will be created new one.</returns>
        public AntAICondition GetGoal(string aGoalName)
        {
            var goal = FindGoal(aGoalName);

            if (goal == null)
            {
                goal = new AntAICondition {
                    name = aGoalName
                };
                goals.Add(goal);
            }
            return(goal);
        }
        private List <AntAIAction> GetPossibleTransitions(AntAICondition aCurrent)
        {
            var possible = new List <AntAIAction>();

            for (int i = 0, n = actions.Count; i < n; i++)
            {
                if (actions[i].pre.Match(aCurrent))
                {
                    possible.Add(actions[i]);
                }
            }
            return(possible);
        }
示例#14
0
        public bool OverlapInterrupts(AntAIPlanner aPlanner, AntAICondition aConditions)
        {
            int index = -1;

            for (int i = 0, n = _interruptions.Count; i < n; i++)
            {
                index = aPlanner.GetAtomIndex(_interruptions[i]);
                if (aConditions.GetValue(index))
                {
                    return(true);
                }
            }
            return(false);
        }
示例#15
0
        /// <summary>
        /// Checking if current world state is equal interruption settings.
        /// </summary>
        /// <param name="aAgent">Ref to the AntAIAgent.</param>
        /// <param name="aWorldState">Current world state.</param>
        /// <returns></returns>
        public bool OverlapInterrupts(AntAIAgent aAgent, AntAICondition aWorldState)
        {
            int index = -1;

            for (int i = 0, n = _interruptions.Count; i < n; i++)
            {
                index = aAgent.planner.GetAtomIndex(_interruptions[i]);
                if (aWorldState.GetValue(index))
                {
                    return(true);
                }
            }
            return(false);
        }
示例#16
0
        /// <summary>
        /// Описывает состояние.
        /// </summary>
        private void DescribeCondition(AntAICondition aCondition, ref List <string> aResult)
        {
            bool value;

            for (int i = 0; i < AntAIPlanner.MAX_ATOMS; i++)
            {
                if (aCondition.GetMask(i))
                {
                    value = aCondition.GetValue(i);
                    aResult.Add(string.Format("      '<color={2}>{0}</color>' = <color={2}>{1}</color>",
                                              _agent.planner.atoms[i], value, (value) ? _trueColor : _falseColor));
                }
            }
        }
示例#17
0
        /// <summary>
        /// Обновляет информацию уже существующей ноды описывающей состояние мира (условий ИИ).
        /// </summary>
        private void UpdateWorldStateNode(AntAICondition aCondition, AntAIDebuggerNode aNode)
        {
            List <string> desc = new List <string>();

            desc.Add(string.Format("<b><color={0}>WORLD STATE</color></b>", _titleColor));
            desc.Add("   <b>Current Conditions</b>");
            DescribeCondition(aCondition, ref desc);

            StringBuilder text = new StringBuilder();

            for (int i = 0, n = desc.Count; i < n; i++)
            {
                text.AppendLine(desc[i]);
            }

            aNode.title       = text.ToString();
            aNode.rect.height = CalcHeight(desc.Count);
        }
示例#18
0
        /// <summary>
        /// Создает новую ноду описывающую поставленную задачу (состояния к которым стримится ИИ).
        /// </summary>
        private AntAIDebuggerNode CreateGoalNode(AntAICondition aGoal, ref Vector2 aNodePosition)
        {
            List <string> desc = new List <string>();

            desc.Add(string.Format("<b><color={1}>GOAL</color> '<color={2}>{0}</color>'</b>",
                                   aGoal.name, _titleColor, _nameColor));
            desc.Add("   <b>Tends to conditions</b>");
            DescribeCondition(aGoal, ref desc);

            StringBuilder text = new StringBuilder();

            for (int i = 0, n = desc.Count; i < n; i++)
            {
                text.AppendLine(desc[i]);
            }

            return(AddNode(text.ToString(), 220.0f, CalcHeight(desc.Count), _goalStyle, _activeGoalStyle, ref aNodePosition));
        }
示例#19
0
        public void BindData(string aTitle, AntAIPlanner aPlanner, AntAICondition aCur, AntAICondition aPre)
        {
            title = string.Concat("▶ ", aTitle);

            _items = new List <Item>();
            bool v;

            for (int i = 0, n = AntAIPlanner.MAX_ATOMS; i < n; i++)
            {
                if (aCur.GetMask(i))
                {
                    v = aCur.GetValue(i);
                    _items.Add(new Item
                    {
                        name      = aPlanner.atoms[i],
                        value     = v,
                        isChanged = (v != aPre.GetValue(i))
                    });
                }
            }
        }
示例#20
0
        /// <summary>
        /// Создает новую ноду описывающуюу текущее состояние мира (условия ИИ).
        /// </summary>
        private AntAIDebuggerNode CreateWorldStateNode(AntAICondition aCondition, ref Vector2 aNodePosition)
        {
            List <string> desc = new List <string>();

            desc.Add(string.Format("<b><color={0}>WORLD STATE</color></b>", _titleColor));
            desc.Add("   <b>Current Conditions</b>");
            DescribeCondition(aCondition, ref desc);

            StringBuilder text = new StringBuilder();

            for (int i = 0, n = desc.Count; i < n; i++)
            {
                text.AppendLine(desc[i]);
            }

            var node = AddNode(text.ToString(), 220.0f, CalcHeight(desc.Count), _nodeStyle, _nodeStyle, ref aNodePosition, false);

            node.SetOutput(node.rect.width - 10.0f, node.rect.height * 0.5f);
            node.SetInput(10.0f, node.rect.height * 0.5f);
            _genericNodes.Add(node);
            return(node);
        }
示例#21
0
        /// <summary>
        /// Обновляет ноду описывающую конкретное действие из плана ИИ.
        /// </summary>
        private void UpdatePlanNode(AntAIAction aAction, AntAICondition aConditions,
                                    AntAICondition aPrevConditions, AntAIDebuggerNode aNode)
        {
            AntAICondition condCopy = aConditions.Clone();

            condCopy.name = aAction.name;
            aNode.value   = aAction.state;

            int numLines;

            aNode.title       = DescribePlanAction(condCopy, aPrevConditions, out numLines);
            aNode.rect.height = CalcHeight(numLines);

            if (_currentPlan.isSuccess)
            {
                aNode.defaultNodeStyle = (aAction.name.Equals(_agent.currentPlan[0])) ? _activePlanStyle : _planStyle;
            }
            else
            {
                aNode.defaultNodeStyle = (aAction.name.Equals(_agent.currentPlan[0])) ? _activeFailedPlanStyle : _failedPlanStyle;
            }
        }
示例#22
0
        /// <summary>
        /// Описывает конкретное действие из плана ИИ.
        /// </summary>
        private string DescribePlanAction(AntAICondition aCur, AntAICondition aPre, out int aNumLines)
        {
            var lines = new List <string>();

            lines.Add(string.Format("<b><color={1}>ACTION</color> '<color={2}>{0}</color>'</b>",
                                    aCur.name, _titleColor, _nameColor));
            lines.Add("   <b>Post Conditions</b>");

            bool value;

            for (int j = 0; j < AntAIPlanner.MAX_ATOMS; j++)
            {
                if (aCur.GetMask(j))
                {
                    value = aCur.GetValue(j);
                    if (value != aPre.GetValue(j))
                    {
                        lines.Add(string.Format("      <color=#a873dd><b>></b></color> <i>'<color={2}>{0}</color>' = <color={2}>{1}</color></i>",
                                                _agent.planner.atoms[j], value, (value) ? _trueColor : _falseColor));
                    }
                    else
                    {
                        lines.Add(string.Format("      '<color={2}>{0}</color>' = <color={2}>{1}</color>",
                                                _agent.planner.atoms[j], value, (value) ? _trueColor : _falseColor));
                    }
                }
            }

            StringBuilder text = new StringBuilder();

            for (int i = 0, n = lines.Count; i < n; i++)
            {
                text.AppendLine(lines[i]);
            }

            aNumLines = lines.Count;
            return(text.ToString());
        }
示例#23
0
 public bool IsFinished(AntAIAgent aAgent, AntAICondition aWorldState)
 {
     return(_isFinished || OverlapInterrupts(aAgent.planner, aWorldState));
 }
示例#24
0
 /// <summary>
 /// Определяет какая цель будет целью по умолчанию.
 /// </summary>
 public void DefaultGoalIs(string aGoalName)
 {
     defaultGoal = FindGoal(aGoalName);
 }
        /// <summary>
        /// Builds the plan.
        /// </summary>
        /// <param name="aPlan">Reference to the result Plan.</param>
        /// <param name="aCurrent">Current World State.</param>
        /// <param name="aGoal">Goal World State that we want reach.</param>
        public void MakePlan(ref AntAIPlan aPlan, AntAICondition aCurrent, AntAICondition aGoal)
        {
#if UNITY_EDITOR
            DebugConditions = aCurrent.Clone();
#endif
            var opened = new List <AntAINode>();
            var closed = new List <AntAINode>();

            opened.Add(new AntAINode
            {
                world     = aCurrent,
                parent    = null,
                cost      = 0,
                heuristic = aCurrent.Heuristic(aGoal),
                sum       = aCurrent.Heuristic(aGoal),
                action    = string.Empty
            });

            AntAINode current = opened[0];
            while (opened.Count > 0)
            {
                // Find lowest rank.
                current = opened[0];
                for (int i = 1, n = opened.Count; i < n; i++)
                {
                    if (opened[i].sum < current.sum)
                    {
                        current = opened[i];
                    }
                }

                opened.Remove(current);

                if (current.world.Match(aGoal))
                {
                    // Plan is found!
                    ReconstructPlan(ref aPlan, closed, current);
                    aPlan.isSuccess = true;
                    if (EventPlanUpdated != null)
                    {
                        EventPlanUpdated(aPlan);
                    }

                    return;
                }

                closed.Add(current);

                // Get neighbors.
                List <AntAIAction> neighbors = GetPossibleTransitions(current.world);
                AntAICondition     neighbor;
                int openedIndex = -1;
                int closedIndex = -1;
                int cost        = -1;
                for (int i = 0, n = neighbors.Count; i < n; i++)
                {
                    cost = current.cost + neighbors[i].cost;

                    neighbor = current.world.Clone();
                    neighbor.Act(neighbors[i].post);

                    openedIndex = FindEqual(opened, neighbor);
                    closedIndex = FindEqual(closed, neighbor);

                    if (openedIndex > -1 && cost < opened[openedIndex].cost)
                    {
                        opened.RemoveAt(openedIndex);
                        openedIndex = -1;
                    }

                    if (closedIndex > -1 && cost < closed[closedIndex].cost)
                    {
                        closed.RemoveAt(closedIndex);
                        closedIndex = -1;
                    }

                    if (openedIndex == -1 && closedIndex == -1)
                    {
                        opened.Add(new AntAINode
                        {
                            world     = neighbor,
                            cost      = cost,
                            heuristic = neighbor.Heuristic(aGoal),
                            sum       = cost + neighbor.Heuristic(aGoal),
                            action    = neighbors[i].name,
                            parent    = current.world
                        });
                    }
                }
            }

            // Failed plan.
            ReconstructPlan(ref aPlan, closed, current);
            aPlan.isSuccess = false;

            if (EventPlanUpdated != null)
            {
                EventPlanUpdated(aPlan);
            }
        }