Example #1
0
        /// <summary> 返回一个新的修改过的状态 </summary>
        /// <param name="_currentStates">当前状态</param>
        /// <param name="_effects">行为效果</param>
        private Dictionary <string, bool> PopulateState(Dictionary <string, bool> _currentStates, IReadOnlyList <GOAPState> _effects)
        {
            Dictionary <string, bool> newStates = DictionaryObjPool.Spawn();

            newStates.Clear();
            foreach (var state in _currentStates)
            {
                newStates[state.Key] = state.Value;
            }

            foreach (var effect in _effects)
            {
                newStates[effect.Key] = effect.Value;
            }

            return(newStates);
        }
Example #2
0
        /// <summary> 定制最优计划 </summary>
        /// <param name="_agent">代理</param>
        /// <param name="_availableActions">所有可用行为</param>
        /// <param name="_currentStates">当前状态</param>
        /// <param name="_goal">目标状态,想要达到的状态</param>
        public void Plan(GOAPAction[] _availableActions,
                         Dictionary <string, bool> _currentStates, GOAPGoal _goal, int _maxDepth, ref Queue <GOAPAction> _plan)
        {
            if (_currentStates.TryGetValue(_goal.Key, out bool value) && value.Equals(_goal.Value))
            {
                return;
            }

            NodePool.RecycleAll();

            // 所有可用的行为
            usableActions.Clear();
            foreach (var action in _availableActions)
            {
                if (action.IsUsable())
                {
                    action.DynamicallyEvaluateCost();
                    usableActions.Add(action);
                }
            }

            // 根节点
            root = NodePool.Spawn(null, 0, _currentStates, null);
            // 所有能达到目标的节点
            leaves.Clear();
            // 成本最低的计划节点
            cheapestNode = null;
            // 成本最低计划
            _plan.Clear();

            // 如果通过构建节点树找到了能够达成目标的计划
            if (BuildGraph(root, usableActions, _goal, 0, _maxDepth, leaves))
            {
                Stack <GOAPAction> goapActionStack = Stack_Pool.Spawn();

                foreach (GOAPNode leaf in leaves)
                {
                    if (cheapestNode == null)
                    {
                        cheapestNode = leaf;
                    }
                    else if (cheapestNode.runningCost > leaf.runningCost)
                    {
                        cheapestNode = leaf;
                    }
                }

                // 向上遍历并添加行为到栈中,直至根节点,因为从后向前遍历
                while (cheapestNode != null)
                {
                    goapActionStack.Push(cheapestNode.action);

                    if (cheapestNode.parent.action != null)
                    {
                        cheapestNode = cheapestNode.parent;
                    }
                    else
                    {
                        break;
                    }
                }

                //goapActions = new Queue<Action>();
                // 再将栈压入到队列中
                while (goapActionStack.Count > 0)
                {
                    _plan.Enqueue(goapActionStack.Pop());
                }
                Stack_Pool.Recycle(goapActionStack);
            }

            // 用完回收所有对象
            DictionaryObjPool.RecycleAll();
        }