/// <summary> /// A method in which we sequentially create a story graph, node by node, starting at the root, using the concept of Breadth First Search. /// </summary> public void BFSTraversing(StoryNode rootNode, bool root = true) { // We create a queue and a list of visited nodes. Queue <StoryNode> queue = new Queue <StoryNode>(); HashSet <StoryNode> visitedNodes = new HashSet <StoryNode>(); // Добавляем узел в очередь и список посещённых узлов. queue.Enqueue(rootNode); visitedNodes.Add(rootNode); // We initialize numeric variables storing the number of the current agent and the number of the last node in the sequence. int actualAgentNumber = 0; int globalNodeNumber = -1; // We will perform the action in a loop until the queue becomes empty. while (queue.Count > 0 && newStoryGraph.GetNodes().Count <= maxNodes) { // We take the node in question from the queue. StoryNode currentNode = queue.Dequeue(); // If we come across a node with a target state, then we do not expand it. if (storyworldConvergence.ControlToAchieveGoalState(ref currentNode)) { //currentNode.goalState = true; continue; } else { // If the node in question is a root. if (currentNode.Equals(rootNode) && root) { // We call the method for creating a new node. Step(newStoryGraph.GetRoot(), actualAgentNumber, root, ref globalNodeNumber, ref queue); // Add the considered node back to the queue (in the case of the root, we only changed it and will consider it again), // and also to the list of visited nodes. We remove the flag indicating that we are considering the root node. queue.Enqueue(currentNode); visitedNodes.Add(currentNode); root = false; } // If the node in question IS NOT a root. else { // We determine the index of the agent, which will have to act when creating a new node. actualAgentNumber = GetActualAgentNumber(currentNode.GetWorldState().GetIndexOfAgent(currentNode.GetActiveAgent()), ref currentNode); // We call the method to create a new node. Step(newStoryGraph.GetNode(currentNode), actualAgentNumber, root, ref globalNodeNumber, ref queue); } } // We go through the nodes associated with the considered one. foreach (StoryNode nextNode in currentNode.GetLinks()) { // If one of them has already been visited earlier, then we continue, moving on to the next. if (visitedNodes.Contains(nextNode)) { continue; } // Otherwise, we add them to the queue and the list of visited nodes. queue.Enqueue(nextNode); visitedNodes.Add(nextNode); } // We clear the link pointing to the node in question. currentNode = null; } }