/// <summary> /// 复制带随机指针的链表 /// 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 /// 要求返回这个链表的 深拷贝。 /// 我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个[val, random_index] 表示: /// val:一个表示 Node.val 的整数。 /// random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。 /// </summary> /// <param name="head"></param> /// <returns></returns> public NodeRandom CopyRandomList(NodeRandom head) { //迭代法 if (head == null) { return(null); } if (visited.ContainsKey(head)) { return(visited[head]); } NodeRandom result = new NodeRandom(head.val); visited.Add(head, result); result.next = CopyRandomList(head.next); result.random = CopyRandomList(head.random); return(result); }
// TODO: merge documentation /// <summary> /// Method to tick every node forward one step, triggering events. Requires several calls if several top level nodes exist. /// </summary> /// <param name="graph">The Graph class created as part of the GraphSystem class. Can be passed a subGraph part of a node to partially tick forward the system.</param> /// <summary> /// Internal function to recursively iterate over several subgraphs. /// </summary> /// <param name="graph">the subgraph on which to iterate over</param> /// <param name="graphTree">the current graphs it has gone through</param> public void Tick(Graph graph, List <Graph> graphTree = null) { graphTree ??= new List <Graph>(); List <Graph> graphs = new List <Graph>(); ConcurrentBag <(Node, Action <Node, Graph, Graph>)> stack = new ConcurrentBag <(Node, Action <Node, Graph, Graph>)>(); graphs.AddRange(graphTree); graphs.Add(graph); var worldGraph = graphs[0]; var localGraph = graphs[graphs.Count - 1]; List <Task> taskList = new List <Task>(); foreach (Node n in graph.Nodes) { List <Event> posEvents = new List <Event>(); NodeRandom rng = Node.rng; foreach (Event ev in events.GetEventList(n.GetType())) { InvokeEvent(n, stack, ev, localGraph, worldGraph); } if (n.SubGraph != null) { taskList.Add(Task.Factory.StartNew((object g) => Tick((Graph)g, graphs), n.SubGraph)); } } if (taskList.Count > 0) { Task.WaitAll(taskList.ToArray()); } foreach (var item in stack) { item.Item1.InvokeAction(item.Item2, localGraph, worldGraph); } }
private NodeRoot GetNodeRoot(NodeValue nodeValue) { NodeRoot nodeRoot = null; switch (nodeValue.NodeType) { case NodeType.Select: // 选择节点 nodeRoot = new NodeSelect(); break; case NodeType.Sequence: // 顺序节点 nodeRoot = new NodeSequence(); break; case NodeType.Decorator: // 修饰节点 nodeRoot = new NodeDecorator(); break; case NodeType.Random: // 随机节点 nodeRoot = new NodeRandom(); break; case NodeType.Parallel: // 并行节点 nodeRoot = new NodeParallel(); break; case NodeType.Condition: // 条件节点 nodeRoot = GetLeafNode(nodeValue); break; case NodeType.Action: // 行为节点 nodeRoot = GetLeafNode(nodeValue); break; } return(nodeRoot); }
void Init() { NodeSequence nodeSequence_1 = new NodeSequence(); rootNode.AddNode(nodeSequence_1); #region 条件 1.1 是否饿了 { NodeConditionHungry cond_1_1 = new NodeConditionHungry(); cond_1_1.SetActor(this); nodeSequence_1.AddNode(cond_1_1); } #endregion #region 择条件 1.2 是否有饭 { NodeSelect sel_1_2 = new NodeSelect(); nodeSequence_1.AddNode(sel_1_2); // 1.2.1 是否有饭 NodeConditionHasFood hasFood_1_2_1 = new NodeConditionHasFood(); hasFood_1_2_1.SetActor(this); sel_1_2.AddNode(hasFood_1_2_1); // 没有饭的话, 走去厨房 => 做饭 // 1.2.2 顺序节点 NodeSequence sequence_1_2_2 = new NodeSequence(); sel_1_2.AddNode(sequence_1_2_2); // 1.2.2.1 走厨房 NodeActionMove move_1_2_2_1 = new NodeActionMove(); move_1_2_2_1.SetActor(this); move_1_2_2_1.myTransform = this.transform; move_1_2_2_1.targetTransform = doCookingTransform; sequence_1_2_2.AddNode(move_1_2_2_1); // 1.2.2.2 做饭 NodeActionCooking cooking_1_2_2_2 = new NodeActionCooking(); cooking_1_2_2_2.SetActor(this); sequence_1_2_2.AddNode(cooking_1_2_2_2); } #endregion #region 1.3 去餐桌 { NodeActionMove move_1_3 = new NodeActionMove(); move_1_3.SetActor(this); move_1_3.myTransform = this.transform; move_1_3.targetTransform = eatFoodTransform; nodeSequence_1.AddNode(move_1_3); } #endregion #region 1.4 吃饭 { NodeActionEat eat_1_4 = new NodeActionEat(); eat_1_4.SetActor(this); nodeSequence_1.AddNode(eat_1_4); } #endregion #region 2 // 并行节点 NodeParallel p_2 = new NodeParallel(); rootNode.AddNode(p_2); // 2.1 是否有钱 NodeConditionHasMoney hasMoney_2_1 = new NodeConditionHasMoney(); p_2.AddNode(hasMoney_2_1); // 2.2 走去酒馆 NodeSequence seq_saloon = new NodeSequence(); p_2.AddNode(seq_saloon); NodeActionMove move_2_2 = new NodeActionMove(); move_2_2.myTransform = this.transform; move_2_2.targetTransform = saloonTransform; seq_saloon.AddNode(move_2_2); // 2.3 随机点一份酒水 NodeRandom r_2_3 = new NodeRandom(); seq_saloon.AddNode(r_2_3); // 2.3.1 喝红酒 r_2_3.AddNode(new NodeActionDrinkRedWine()); // 2.3.2 喝白开水 r_2_3.AddNode(new NodeActionDrinkWater()); #endregion }