private void UpdateCriterionNodes() { var criterionNodes = GoalNode.GetAllCriterionNodes().ToList(); var criterions = Manager.Hierarchy.GoalNode.SearchChildNodes <CriterionNode>(x => x is CriterionNode).OrderBy(x => x.Level).ToList(); foreach (var criterion in criterions) { var criterionNode = criterionNodes.SingleOrDefault(x => x.Criterion == criterion); if (criterionNode == null) { criterionNode = new CriterionNodeViewModel(this, criterion); criterionNodes.Add(criterionNode); } var parentNode = (criterion.GoalNode != null) ? (HierarchyNodeViewModel)GoalNode : (HierarchyNodeViewModel)criterionNodes.Single(x => x.Criterion == criterion.ParentCriterionNode); if (criterionNode.Parent != null && criterionNode.Parent != parentNode) { criterionNode.Parent.RemoveChild(criterionNode); } if (criterionNode.Parent != parentNode) { parentNode.AddChild(criterionNode); } } foreach (var criterionNode in criterionNodes.ToArray()) { var criterion = criterions.SingleOrDefault(x => x == criterionNode.Criterion); if (criterion == null) { criterionNode.Parent.RemoveChild(criterionNode); } } }
/// <summary> /// Recursively find a motion that can be executed /// </summary> /// <returns></returns> public override Motion FindMotion() { for (int i = targetObjectiveIndex; i < subGoals.Count; ++i) { if (!subGoals[i].IsCompleted()) { targetSubgoal = subGoals[i]; targetObjectiveIndex = i; break; } } if (targetSubgoal == null) { return(null); } else { if (!targetSubgoal.HasNecessaryData()) { ProvideNecessaryData(); } return(targetSubgoal.FindMotion()); } }
public override void OnHeaderGUI() { if (node == null) { node = target as GoalNode; } if (node.sourceGoal != null) { GUILayout.Label(node.sourceGoal.GetType().ToString(), NodeEditorResources.styles.nodeHeader, GUILayout.Height(30)); } else { inspectStuff.Show(); OdinEditorWindow.InspectObject(inspectStuff, node); } if (node == null) { node = target as GoalNode; } if (node.filter == null) { node.initNode(); window.Repaint(); } // Debug.Log("in the heeeead"); }
public static void AddTask(TaskNode T0, GoalNode g) { // Remove connections T0.removeConnection(Direction.Right); g.removeConnection(Direction.Left); // Create new task node AlphabetNode T1 = new TaskNode(); // Reorganize connections T0.setConnection(Direction.Right, T1); T1.setConnection(Direction.Left, T0); T1.setConnection(Direction.Right, g); g.setConnection(Direction.Left, T1); }
public static void StartMission(StartNode S, Graph graph) { // Create RHS nodes EntranceNode e = new EntranceNode(); TaskNode T = new TaskNode(); GoalNode g = new GoalNode(); // Connect the new nodes e.setConnection(Direction.Right, T); T.setConnection(Direction.Left, e); T.setConnection(Direction.Right, g); g.setConnection(Direction.Left, T); // Set the entrance node to be the root of the graph graph.setRootNode(e); }
void accedpDraggedGoal(Type type, MGoal goal) { if (dragAcceptPending) { if (Event.current.type == EventType.Repaint) { Convert.ChangeType(goal, type); Vector2 pos = NodeEditorWindow.current.WindowToGridPosition(Event.current.mousePosition); GoalNode node = CreateNode(typeof(GoalNode), pos) as GoalNode; node.sourceGoal = goal; node.goalType = type; node.filter = node.populateFilter(node.filter, goal.filter, PortOrientation.In); Debug.Log("Dragged goal"); dragAcceptPending = false; g = null; draggedType = null; } } }
public GoalNodeViewModel(HierarchyViewModel hierarchy, GoalNode goal) : base(hierarchy) { Goal = goal; }
// Method that will create the different nodes in the graphs and will organize them using the production rules public void GenerateMission(int minTaskNumber, int maxTaskNumber, int minOrganizeTaskTries, int maxOrganizeTaskTries, float probabiltyApplyOrganizationRule) { // Randomly choose the number task nodes int numberTaskNodes = Random.Range(minTaskNumber, maxTaskNumber); // Set the number of total nodes in the graph based on the number of task nodes plus the entance and goal nodes totalNodes = numberTaskNodes + 2; // Randomly choose the number of times the algorithm will try to apply the reorganize tasks production rules int numberOrganizeTaskTries = Random.Range(minOrganizeTaskTries, maxOrganizeTaskTries); // The graph always start with the start mission production rule ProductionRules.StartMission((StartNode)rootNode, this); // The first node to the right of the root of the graph is going to be always a task node TaskNode currentTaskNode = (TaskNode)rootNode.getConnection(Direction.Right); // The node to the right of the first task node is going to be always the goal node GoalNode goalNode = (GoalNode)currentTaskNode.getConnection(Direction.Right); // The first step to create the mission is to add all the tasks one by one for (int i = 0; i < numberTaskNodes; i++) { ProductionRules.AddTask(currentTaskNode, goalNode); currentTaskNode = (TaskNode)goalNode.getConnection(Direction.Left); } // The next and final step is to reorganize the tasks position starting from the right of the root node, at this stage the root is always going to be an entrance node and no rules can be applied to it AlphabetNode currentNode = rootNode.getConnection(Direction.Right); while (numberOrganizeTaskTries > 0) { // Decide whether to try apply rule from current node or go to the next one if (currentNode is TaskNode && !currentNode.isTerminal() && Random.Range(0.0f, 1.0f) < probabiltyApplyOrganizationRule) { // Get number of nodes from the current that are also non terminal task nodes towards the right AlphabetNode nextRightNode = currentNode.getConnection(Direction.Right); List <AlphabetNode> connections = new List <AlphabetNode>(); // The biggest number of task nodes taken by a production rule is six for (int i = 0; i < 6; i++) { if (nextRightNode != null && nextRightNode is TaskNode && !nextRightNode.isTerminal()) { connections.Add(nextRightNode); nextRightNode = nextRightNode.getConnection(Direction.Right); } } // Apply production rules based on the number of right task connections from current node, when multiple rules can be applied, all of them have the same probability of being picked switch (connections.Count) { case 2: // Only one rule can be applied ProductionRules.ReorganizeThreeTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1]); break; case 3: // Two rules can be applied if (Random.Range(0.0f, 1.0f) > 0.5f) { ProductionRules.ReorganizeThreeTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1]); } else { ProductionRules.ReorganizeFourTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1], (TaskNode)connections[2]); } break; case 4: // Three rules can be applied float random = Random.Range(0.0f, 1.0f); if (random < (1.0f / 3.0f)) { ProductionRules.ReorganizeThreeTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1]); } else if (random > (2.0f / 3.0f)) { ProductionRules.ReorganizeFourTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1], (TaskNode)connections[2]); } else { ProductionRules.ReorganizeFiveTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1], (TaskNode)connections[2], (TaskNode)connections[3]); } break; case 5: // Four rules can be applied random = Random.Range(0.0f, 1.0f); if (random < 0.25f) { ProductionRules.ReorganizeThreeTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1]); } else if (random > 0.25f && random < 0.5f) { ProductionRules.ReorganizeFourTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1], (TaskNode)connections[2]); } else if (random > 0.75f) { ProductionRules.ReorganizeFiveTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1], (TaskNode)connections[2], (TaskNode)connections[3]); } else { ProductionRules.ReorganizeSixTasks((TaskNode)currentNode, (TaskNode)connections[0], (TaskNode)connections[1], (TaskNode)connections[2], (TaskNode)connections[3], (TaskNode)connections[4]); } break; } } // Get next node, try right first and down second AlphabetNode previousCurrent = currentNode; currentNode = currentNode.getConnection(Direction.Right); if (currentNode == null) { currentNode = previousCurrent.getConnection(Direction.Down); } // If the goal node is reached, try to apply the productions rules from the beginnig if (currentNode is GoalNode || currentNode == null) { currentNode = rootNode; } // Decrease tries numberOrganizeTaskTries--; } }