/// <summary> /// Called by <see cref="AIBrain"/> after <see cref="IsCompleted(AIBrain)"/> returned true /// </summary> virtual public void GeneralPostEffects(AIBrain ai) { if (repeatType != ET.ActionType.Repetitive) { StateDictionary.OverrideCombine(postEffects, ai.WorldState); } }
/// <summary> /// 创建行为列表 /// </summary> /// <param name="root">空节点</param> /// <param name="cWorldState">世界状态.</param> /// <param name="goalState">当前目的(想要的最终改变)</param> /// <param name="allActions">当前目标牵涉到的行为</param> /// <param name="matchNodes">Match nodes.</param> /// <param name="minCostPlanSoFar">Minimum cost plan so far.</param> private void CreateActionTree(Node root, StateDictionary cWorldState, StateDictionary goalState, List <AIAction> allActions, List <Node> matchNodes, ref float minCostPlanSoFar) { foreach (AIAction action in allActions) { //当前行为的产生的消耗必须小于低于minCostPlanSoFar && 当前世界状态必须满足当前行为的前提条件 if (root.cost + action.Cost < minCostPlanSoFar && action.CanApplyToWorld(cWorldState)) { //创建一个世界状态的拷贝 StateDictionary newWorldState = new StateDictionary(cWorldState.conditions); //把当前行为抛出的事件 合并(更新)到 世界状态里去 StateDictionary.OverrideCombine(action.postEffects, newWorldState); //创建一个新的节点 Node newNode = new Node(/*letter++ + "",*/ root.cost + action.Cost, root, action); // check to see if goal is satisfied //如果newWorldState包含所有的goalstate if (StateDictionary.ConditionsMatch(goalState, newWorldState)) { matchNodes.Add(newNode); minCostPlanSoFar = newNode.cost; minCostPlan.Clear(); Node tempNode = newNode; while (tempNode.parent != null) { //为什么要插入到第一个位置 ? 压入队列 从新到旧 minCostPlan.Insert(0, tempNode.upperAction); tempNode = tempNode.parent; } continue; } else { //丢弃当前的行为 List <AIAction> newActionsList = new List <AIAction>(allActions); newActionsList.Remove(action); CreateActionTree(newNode, newWorldState, goalState, newActionsList, matchNodes, ref minCostPlanSoFar); } } else { continue; } } return; }
private void CreateActionTree(Node root, StateDictionary cWorldState, StateDictionary goalState, List <AIAction> allActions, List <Node> matchNodes, ref float minCostPlanSoFar) { foreach (AIAction action in allActions) { if (root.cost + action.Cost < minCostPlanSoFar && action.CanApplyToWorld(cWorldState)) { StateDictionary newWorldState = new StateDictionary(cWorldState.conditions); StateDictionary.OverrideCombine(action.postEffects, newWorldState); Node newNode = new Node(/*letter++ + "",*/ root.cost + action.Cost, root, action); // check to see if goal is satisfied if (StateDictionary.ConditionsMatch(goalState, newWorldState)) { matchNodes.Add(newNode); minCostPlanSoFar = newNode.cost; minCostPlan.Clear(); Node tempNode = newNode; while (tempNode.parent != null) { minCostPlan.Insert(0, tempNode.upperAction); tempNode = tempNode.parent; } continue; } else { List <AIAction> newActionsList = new List <AIAction>(allActions); newActionsList.Remove(action); CreateActionTree(newNode, newWorldState, goalState, newActionsList, matchNodes, ref minCostPlanSoFar); } } else { continue; } } return; }