/// <summary>
        /// Method is an entry point that controls the operation of the algorithm (the sequence of launching other methods).
        /// </summary>
        public void Start()
        {
            // We read the settings and create the initial state of the world.
            // ReadUserSettingsInput();
            CreateInitialState();
            CreateConstraints();
            GenerateNewPDDLDomains();

            // We create a start node (root) based on the start state of the world.
            StoryNode root = new StoryNode();

            root.SetWorldState(currentStoryState);
            root.SetActivePlayer(false);
            root.SetActiveAgent(currentStoryState.GetFirstAgent());
            newStoryGraph.SetRoot(root);

            // We go through all the agents and remember their goals.
            storyworldConvergence.ExtractGoals(currentStoryState);

            // The algorithm calculates a SPECIFIC story.
            newStoryGraph = CreateStoryGraph(newStoryGraph.GetRoot());

            // Create a visual graph.
            graphСonstructor.CreateGraph(newStoryGraph, @"D:\Graphviz\bin\newStoryGraph.dt");

            // Create an HTML file including Twine engine and generated history.
            //twineGraphConstructor.ConstructGraph(newStoryGraph);
            //twineGraphConstructor.CreateHTMLFileWithGame();

            // SaveFile();
        }
Пример #2
0
        public void DuplicateNodeConnecting(WorldDynamic currentState,
                                            PlanAction action,
                                            KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                            StoryNode currentNode,
                                            int globalNodeNumber,
                                            ref Queue <StoryNode> queue,
                                            bool succsessControl,
                                            ref bool skip)
        {
            StoryNode testNode = CreateTestNode(currentState, action, agent, currentNode, false, globalNodeNumber, succsessControl);

            testNode.UpdateHashCode();

            if (!testNode.Equals(currentNode))
            {
                foreach (var checkedNode in nodes)
                {
                    if (TwoNodesComparison(testNode, checkedNode) && !currentNode.ConnectedWith(checkedNode))
                    {
                        DeleteTestNode(ref testNode);
                        ConnectionTwoNodes(action, currentNode, checkedNode, true);
                        break;
                    }
                }
            }
            else
            {
                DeleteTestNode(ref testNode);
                skip = true;
            }
        }
Пример #3
0
        public bool CyclesControl(WorldDynamic currentState,
                                  PlanAction action,
                                  StoryGraph currentGraph,
                                  KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                  StoryNode currentNode,
                                  bool duplicated,
                                  int globalNodeNumber,
                                  bool succsessControl)
        {
            bool result = false;

            // We create a test node similar to the one we are going to add to the graph as a result of the current action.
            StoryNode testNode = currentGraph.CreateTestNode(currentState, action, agent, currentNode, !duplicated, globalNodeNumber, succsessControl);

            StoryNode duplicatedNode = null;
            Edge      testEdge       = new Edge();

            if (!duplicated)
            {
                duplicatedNode = currentGraph.GetNode(testNode);

                if (currentNode.Equals(duplicatedNode))
                {
                    return(false);
                }

                testEdge.SetUpperNode(ref currentNode);
                testEdge.SetLowerNode(ref duplicatedNode);

                currentNode.AddEdge(testEdge);
                duplicatedNode.AddEdge(testEdge);

                currentNode.AddLinkToNode(ref duplicatedNode);
                duplicatedNode.AddLinkToNode(ref currentNode);
            }

            string[] colors = new string[currentGraph.GetNodes().Count + 2];
            for (int i = 0; i < currentGraph.GetNodes().Count + 2; i++)
            {
                colors[i] = "white";
            }

            result = TarjanAlgStep(currentGraph.GetRoot(), ref colors, !duplicated, duplicatedNode);

            if (!duplicated)
            {
                currentNode.RemoveEdge(testEdge);
                currentNode.DeleteLink(duplicatedNode);
                duplicatedNode.RemoveEdge(testEdge);
                duplicatedNode.DeleteLink(currentNode);
                testEdge.ClearUpperNode();
                testEdge.ClearLowerNode();
                testEdge = null;
            }

            // We delete the test node and mark the loop test as passed.
            currentGraph.DeleteTestNode(ref testNode);

            return(result);
        }
        /// <summary>
        /// The method that controls the creation of the history graph.
        /// </summary>
        public StoryGraph CreateStoryGraph(StoryNode rootNode)
        {
            // We clone the root into a separate variable.
            StoryNode originRoot = (StoryNode)rootNode.Clone();

            // We continue to work until at least one target state is reached.
            while (!reachedGoalState)
            {
                // We create a new graph by starting to expand the root.
                BFSTraversing(newStoryGraph.GetRoot());

                // We go through the created graph, looking for target states in it.
                BFSGoalAchieveControl(newStoryGraph.GetRoot());

                // If it was not possible to find even one target state in the constructed graph.
                if (!reachedGoalState || newStoryGraph.GetNodes().Count > maxNodes)
                {
                    graphСonstructor.CreateGraph(newStoryGraph, @"D:\Graphviz\bin\newStoryGraph.dt");

                    // Then we clear the graph, and all the links added to the root.
                    newStoryGraph = new StoryGraph();
                    originRoot.GetEdges().Clear();
                    originRoot.GetLinks().Clear();

                    // After that, we reassign to the previously cleared column an indication of the root.
                    newStoryGraph.SetRoot((StoryNode)originRoot.Clone());

                    reachedGoalState = false;
                }
            }

            // We return a graph that is guaranteed to have at least one target state.
            return(newStoryGraph);
        }
Пример #5
0
        public bool DuplicateControl(WorldDynamic currentState,
                                     PlanAction action,
                                     StoryGraph currentGraph,
                                     KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                     StoryNode currentNode,
                                     int globalNodeNumber,
                                     bool succsessControl)
        {
            StoryNode testNode = currentGraph.CreateTestNode(currentState, action, agent, currentNode, false, globalNodeNumber, succsessControl);

            testNode.UpdateHashCode();

            foreach (var checkedNode in currentGraph.GetNodes())
            {
                checkedNode.UpdateHashCode();
                if (currentGraph.TwoNodesComparison(testNode, checkedNode))
                {
                    currentGraph.DeleteTestNode(ref testNode);
                    return(false);
                }
            }

            currentGraph.DeleteTestNode(ref testNode);
            return(true);
        }
Пример #6
0
        public void MultiAVandAC(ref PlanAction receivedAction,
                                 WorldDynamic currentState,
                                 KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                 CSP_Module cspModule,
                                 StoryGraph currentGraph,
                                 StoryNode currentNode,
                                 bool root,
                                 ref int globalNodeNumber,
                                 ref Queue <StoryNode> queue)
        {
            List <PlanAction> actionsList = cspModule.MassiveAssignVariables(ref receivedAction, currentState, agent);

            AgentStateStatic  sCurrentAgent = (AgentStateStatic)agent.Key.Clone();
            AgentStateDynamic dCurrentAgent = (AgentStateDynamic)agent.Value.Clone();
            KeyValuePair <AgentStateStatic, AgentStateDynamic> currentAgent =
                new KeyValuePair <AgentStateStatic, AgentStateDynamic>(sCurrentAgent, dCurrentAgent);

            WorldDynamic statePrefab = (WorldDynamic)currentState.Clone();

            foreach (var a in actionsList)
            {
                ActionControl(a, currentGraph, currentAgent, statePrefab, currentNode, root, ref globalNodeNumber, ref queue);
            }

            // Cleaning
            actionsList = null;
            currentNode = null;
            statePrefab = null;
            GC.Collect();
        }
Пример #7
0
        public void CounterreactionControl(PlanAction action,
                                           StoryGraph currentGraph,
                                           KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                           WorldDynamic currentState,
                                           StoryNode currentNode,
                                           bool root,
                                           ref int globalNodeNumber,
                                           ref Queue <StoryNode> queue,
                                           ref bool controlOne,
                                           ref bool controlTwo)
        {
            bool succsessControl = ProbabilityCalculating(action);

            action.success = succsessControl;
            action.fail    = !succsessControl;

            bool constraintsControl = ConstraintsControl(currentState, action, succsessControl);
            bool deadEndsControl    = DeadEndsControl(action, currentState, agent, succsessControl);
            bool duplicateControl   = DuplicateControl(currentState, action, currentGraph, agent, currentNode, globalNodeNumber, succsessControl);
            //bool cyclesControl = CyclesControl(currentState, action, currentGraph, agent, currentNode, duplicateControl, globalNodeNumber, succsessControl);
            bool cyclesControl = true;

            controlOne = constraintsControl & deadEndsControl & cyclesControl;
            controlTwo = duplicateControl;
        }
Пример #8
0
 public bool TwoNodesComparison(StoryNode nodeOne, StoryNode nodeTwo)
 {
     if (nodeOne.Equals(nodeTwo))
     {
         return(true);
     }
     return(false);
 }
Пример #9
0
 public void ClearLowerNode()
 {
     if (lowerNode != null)
     {
         lowerNode.GetEdges().Remove(this);
         lowerNode = null;
     }
 }
Пример #10
0
        /// <summary>
        /// Create a new node for the story graph and inserts it.
        /// </summary>
        public void CreateNewNode(PlanAction action,
                                  KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                  WorldDynamic currentState,
                                  StoryNode currentNode,
                                  ref int globalNodeNumber,
                                  bool succsessControl,
                                  bool counteract)
        {
            WorldDynamic newState = (WorldDynamic)currentState.Clone();

            if (!succsessControl)
            {
                action.Fail(ref newState);
            }
            else
            {
                action.ApplyEffects(ref newState);
            }
            newState.UpdateHashCode();

            // Create an empty new node.
            StoryNode newNode = new StoryNode();

            if (counteract)
            {
                newNode.counteract = true;
            }

            // We assign the state of the world (transferred) to the new node.
            newNode.SetWorldState((WorldDynamic)newState.Clone());

            newNode.SetActiveAgent(newNode.GetWorldState().GetAgentByName(agent.Key.GetName()));
            if (agent.Key.GetRole() == AgentRole.PLAYER)
            {
                newNode.SetActivePlayer(true);
            }
            else
            {
                newNode.SetActivePlayer(false);
            }

            ConnectionTwoNodes(action, currentNode, newNode, false);

            globalNodeNumber++;
            newNode.SetNumberInSequence(globalNodeNumber);

            if (nodes.Contains(newNode))
            {
                bool test = true;
            }

            // Add a new node to the graph.
            AddNode(newNode);
        }
Пример #11
0
        public StoryNode GetNode(StoryNode node)
        {
            foreach (var n in nodes)
            {
                if (node.Equals(n))
                {
                    return(n);
                }
            }

            throw new KeyNotFoundException();
        }
Пример #12
0
        public bool TarjanAlgStep(StoryNode checkedNode, ref string[] colors, bool duplicated, StoryNode duplicatedNode)
        {
            bool result = true;

            colors[checkedNode.GetNumberInSequence()] = "grey";

            foreach (StoryNode nextNode in checkedNode.GetLinks())
            {
                if (!result)
                {
                    return(result);
                }

                if (colors[nextNode.GetNumberInSequence()] == "grey")
                {
                    if (duplicated)
                    {
                        if (duplicatedNode.Equals(nextNode))
                        {
                            bool test = true;
                        }
                    }

                    if (checkedNode.isChildren(nextNode) && !duplicated)
                    {
                        continue;
                    }
                    else if (duplicated && checkedNode.isChildren(nextNode) && !duplicatedNode.Equals(nextNode))
                    {
                        continue;
                    }

                    result = false;
                    return(result);
                }
                else if (colors[nextNode.GetNumberInSequence()] == "black")
                {
                    continue;
                }
                else
                {
                    result = TarjanAlgStep(nextNode, ref colors, duplicated, duplicatedNode);
                    if (!result)
                    {
                        return(result);
                    }
                }
            }

            colors[checkedNode.GetNumberInSequence()] = "black";

            return(result);
        }
Пример #13
0
        public bool NodeExistenceControl(StoryNode checkedNode)
        {
            foreach (var node in GetNodes())
            {
                if (TwoNodesComparison(node, checkedNode))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #14
0
        public StoryNode CreateTestNode(WorldDynamic currentState,
                                        PlanAction action,
                                        KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                        StoryNode currentNode,
                                        bool connection,
                                        int globalNodeNumber,
                                        bool succsessControl)
        {
            WorldDynamic worldForTest = (WorldDynamic)currentState.Clone();

            if (!succsessControl)
            {
                action.Fail(ref worldForTest);
            }
            else
            {
                action.ApplyEffects(ref worldForTest);
            }
            worldForTest.UpdateHashCode();

            StoryNode testNode = new StoryNode();

            //if (counteract) { testNode.counteract = true; }
            //testNode.SetWorldState(worldForTest);
            testNode.SetWorldState((WorldDynamic)worldForTest.Clone());

            // Create a clone of the agent.
            //KeyValuePair<AgentStateStatic, AgentStateDynamic> newAgent =
            //    new KeyValuePair<AgentStateStatic, AgentStateDynamic>((AgentStateStatic)agent.Key.Clone(), (AgentStateDynamic)agent.Value.Clone());
            testNode.SetActiveAgent(testNode.GetWorldState().GetAgentByName(agent.Key.GetName()));

            // We take the last node from the list of all nodes and assign whether the player is active and which of the agents was active on this turn.
            if (agent.Key.GetRole() == AgentRole.PLAYER)
            {
                testNode.SetActivePlayer(true);
            }
            else
            {
                testNode.SetActivePlayer(false);
            }

            //testNode.SetActiveAgent(newAgent);

            /*if (connection)
             * {
             *  ConnectionTwoNodes(action, currentNode, testNode, false);
             * }*/

            testNode.SetNumberInSequence(globalNodeNumber + 1);

            return(testNode);
        }
Пример #15
0
        /// <summary>
        /// Checks the achievement of any of the goal conditions (in state).
        /// </summary>
        /// <param name="currentWorldState"></param>
        public bool ControlToAchieveGoalState(ref StoryNode currentNode)
        {
            foreach (var goal in allGoalStates)
            {
                // todo: convert to switch
                // todo: supplement the types of goals - group and specific

                if (goal.goalTypeIsStatus)
                {
                    int  killCounter = 0;
                    bool killerDied  = false;

                    foreach (var agent in currentNode.GetWorldState().GetAgents())
                    {
                        switch (agent.Key.GetRole())
                        {
                        case AgentRole.USUAL: if (!agent.Value.GetStatus())
                            {
                                killCounter++;
                            }
                            break;

                        case AgentRole.PLAYER: if (!agent.Value.GetStatus())
                            {
                                killCounter++;
                            }
                            break;

                        case AgentRole.KILLER: if (!agent.Value.GetStatus())
                            {
                                killerDied = true;
                            }
                            break;
                        }
                    }

                    if (killCounter == currentNode.GetWorldState().GetAgents().Count - 1)
                    {
                        currentNode.goalState = true;
                        return(true);
                    }
                    if (killerDied)
                    {
                        currentNode.goalState = true;
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #16
0
        /// <summary>
        /// Checking the action for violation of the established constraints and the reachability of the goal state (control of cycles and deadends).
        /// </summary>
        public void ActionControl(PlanAction action,
                                  StoryGraph currentGraph,
                                  KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                  WorldDynamic currentState,
                                  StoryNode currentNode,
                                  bool root,
                                  ref int globalNodeNumber,
                                  ref Queue <StoryNode> queue)
        {
            bool succsessControl = ProbabilityCalculating(action);

            action.success = succsessControl;
            action.fail    = !succsessControl;

            bool constraintsControl = ConstraintsControl(currentState, action, succsessControl);
            bool deadEndsControl    = DeadEndsControl(action, currentState, agent, succsessControl);
            bool duplicateControl   = DuplicateControl(currentState, action, currentGraph, agent, currentNode, globalNodeNumber, succsessControl);
            //bool cyclesControl = CyclesControl(currentState, action, currentGraph, agent, currentNode, duplicateControl, globalNodeNumber, succsessControl);
            bool cyclesControl = true;

            if (constraintsControl && deadEndsControl && cyclesControl && duplicateControl)
            {
                // If all checks are passed, then we apply the action.
                ApplyAction(action, currentGraph, agent, currentState, currentNode, root, ref globalNodeNumber, succsessControl, false);
            }
            else if (!constraintsControl && deadEndsControl && cyclesControl && duplicateControl)
            {
                // If the action violates the constraints, then convergence will not apply it, but will apply its counter-reaction.
                ActionCounteract(action, currentGraph, agent, currentState, currentNode, root, ref globalNodeNumber, ref queue);
            }
            else if (!duplicateControl && cyclesControl)
            {
                bool skip = false;

                // connection current node --> finded node
                currentGraph.DuplicateNodeConnecting(currentState, action, agent, currentNode, globalNodeNumber, ref queue, succsessControl, ref skip);

                if (skip)
                {
                    //NothingToDo newAction = new NothingToDo();
                    //newAction.Arguments.Add(agent);
                    //ApplyAction(newAction, currentGraph, agent, currentState, currentNode, root, ref globalNodeNumber, succsessControl, true);

                    ActionCounteract(action, currentGraph, agent, currentState, currentNode, root, ref globalNodeNumber, ref queue);
                }
            }
            else
            {
                ActionCounteract(action, currentGraph, agent, currentState, currentNode, root, ref globalNodeNumber, ref queue);
            }
        }
Пример #17
0
        public void DeleteTestNode(ref StoryNode testNode)
        {
            foreach (var edge in testNode.GetEdges().ToList())
            {
                edge.GetUpperNode().RemoveEdge(edge);
                edge.GetLowerNode().RemoveEdge(edge);
                edge.ClearEdge();
            }

            foreach (var link in testNode.GetLinks().ToList())
            {
                testNode.DeleteLink(link);
            }
        }
Пример #18
0
        public void SingleAVandAC(ref PlanAction receivedAction,
                                  WorldDynamic currentState,
                                  KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                  CSP_Module cspModule,
                                  StoryGraph currentGraph,
                                  StoryNode currentNode,
                                  bool root,
                                  ref int globalNodeNumber,
                                  ref Queue <StoryNode> queue)
        {
            cspModule.AssignVariables(ref receivedAction, currentState, agent);

            ActionControl(receivedAction, currentGraph, agent, currentState, currentNode, root, ref globalNodeNumber, ref queue);

            // Cleaning
            currentNode = null;
            GC.Collect();
        }
        /// <summary>
        /// Convergence in turn asks agents for actions, checks them, applies them, counteracts them, or does not.
        /// </summary>
        public void Step(StoryNode currentNode, int agentIndex, bool root, ref int globalNodeNumber, ref Queue <StoryNode> queue)
        {
            // Convergence assigns who is on the turn to the node and then applies the changes to the state of the world.
            currentStoryState = currentNode.GetWorldState();
            currentStoryState.GetStaticWorldPart().IncreaseTurnNumber();

            while (!currentStoryState.GetAgentByIndex(agentIndex).Value.GetStatus())
            {
                agentIndex = GetActualAgentNumber(agentIndex, ref currentNode);
            }

            // We check if the agent from whom we are going to request an action is alive (i.e. capable of doing it).
            if (currentStoryState.GetAgentByIndex(agentIndex).Value.GetStatus())
            {
                // We create a request for action of the specified agent from the specified state.
                storyworldConvergence.ActionRequest(currentStoryState.GetAgentByIndex(agentIndex), ref newStoryGraph, ref currentStoryState,
                                                    currentNode, root, ref globalNodeNumber, ref queue);
            }
        }
        /// <summary>
        /// A method that traverses the graph according to the concept of breadth-first search
        ///    and determines the presence of at least one target state in it.
        /// </summary>
        public bool BFSGoalAchieveControl(StoryNode rootNode)
        {
            // We create a queue and a list of visited nodes.
            Queue <StoryNode>   queue        = new Queue <StoryNode>();
            HashSet <StoryNode> visitedNodes = new HashSet <StoryNode>();

            // Add the root node to the queue and the list of visited nodes.
            queue.Enqueue(rootNode);
            visitedNodes.Add(rootNode);

            // We are in a loop until the queue is empty.
            while (queue.Count > 0)
            {
                // We take the current node under consideration from the queue.
                StoryNode currentNode = queue.Dequeue();

                // We check if the target state has been reached in the node under consideration.
                reachedGoalState = storyworldConvergence.ControlToAchieveGoalState(ref currentNode);

                // If so, terminate the method and return true.
                if (reachedGoalState)
                {
                    return(true);
                }

                // Otherwise, we go through the nodes associated with the node in question.
                foreach (StoryNode nextNode in currentNode.GetLinks())
                {
                    // If they have already been visited earlier, then we continue, moving on to the next.
                    if (visitedNodes.Contains(nextNode))
                    {
                        continue;
                    }

                    // Otherwise, we add to the queue and the list of visited nodes.
                    queue.Enqueue(nextNode);
                    visitedNodes.Add(nextNode);
                }
            }

            // If no target state was found, then terminate the method and return false.
            return(false);
        }
Пример #21
0
 /// <summary>
 /// The probability of success of the action is calculated, and if successful, it is applied.
 /// </summary>
 public void ApplyAction(PlanAction action,
                         StoryGraph currentGraph,
                         KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                         WorldDynamic currentState,
                         StoryNode currentNode,
                         bool root,
                         ref int globalNodeNumber,
                         bool succsessControl,
                         bool counteract)
 {
     // We apply a successful/unsuccessful option to perform an action.
     if (root)
     {
         currentGraph.CreateRootNode(action, agent, currentState, currentNode, ref globalNodeNumber, succsessControl);
     }
     else
     {
         currentGraph.CreateNewNode(action, agent, currentState, currentNode, ref globalNodeNumber, succsessControl, counteract);
     }
 }
Пример #22
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="firstNode">Current node</param>
        /// <param name="secondNode">New node</param>
        public void ConnectionTwoNodes(PlanAction action, StoryNode firstNode, StoryNode secondNode, bool duplicate)
        {
            Edge newEdge = new Edge();

            newEdge.SetAction(action);

            newEdge.SetUpperNode(ref firstNode);
            newEdge.SetLowerNode(ref secondNode);

            firstNode.AddEdge(newEdge);
            secondNode.AddEdge(newEdge);

            firstNode.AddLinkToNode(ref secondNode);
            secondNode.AddLinkToNode(ref firstNode);

            if (firstNode.GetEdges().Count != firstNode.GetLinks().Count)
            {
                bool test = true;
            }
        }
        /// <summary>
        /// A method that returns the index of the agent that should perform the action.
        /// </summary>
        /// <param name="prevNumber">Index of the agent who performed the action in the previous state.</param>
        public int GetActualAgentNumber(int prevNumber, ref StoryNode currentNode)
        {
            // Flag for checking if the agent being checked is alive.
            bool aliveControl = false;

            // Determine how many agents exist in the current state.
            int maxNumber = currentNode.GetWorldState().GetNumberOfAgents();

            // Default result.
            int result = 0;

            // Until the flag signaling the status of the agent being checked is omitted.
            while (!aliveControl)
            {
                // If the index of the previous agent is equal to the maximum possible index.
                if (prevNumber == maxNumber - 1)
                {
                    // Then we go back to the beginning of the index list and set 0 as the result (the circle is passed).
                    result     = 0;
                    prevNumber = 0;
                }
                else
                {
                    // Otherwise, we increase the value of the index of the previous agent by one and write it down as a result.
                    prevNumber++;
                    result = prevNumber;
                }

                // We check if the agent with the received index is alive. If not, we continue the cycle.
                if (!currentNode.GetWorldState().GetAgentByIndex(result).Value.GetStatus())
                {
                    continue;
                }

                // Otherwise, we raise the flag that the control has been passed.
                aliveControl = true;
            }

            // We return the result - the index of the guaranteed living agent acting after the specified in the parameters.
            return(result);
        }
Пример #24
0
        public void CreateRootNode(PlanAction action,
                                   KeyValuePair <AgentStateStatic, AgentStateDynamic> agent,
                                   WorldDynamic currentState,
                                   StoryNode currentNode,
                                   ref int globalNodeNumber,
                                   bool succsessControl)
        {
            WorldDynamic newState = (WorldDynamic)currentState.Clone();

            if (!succsessControl)
            {
                action.Fail(ref newState);
            }
            else
            {
                action.ApplyEffects(ref newState);
            }

            if (agent.Key.GetRole() == AgentRole.PLAYER)
            {
                currentNode.SetActivePlayer(true);
            }
            else
            {
                currentNode.SetActivePlayer(false);
            }

            // We assign the state of the world (transferred) to the new node.
            currentNode.SetWorldState((WorldDynamic)newState.Clone());

            //Edge newEdge = new Edge();

            // We adjust the edge - assign its action and indicate the nodes that it connects.
            //newEdge.SetAction(action);
            //newEdge.SetUpperNode(ref currentNode);

            //currentNode.AddEdge(newEdge);

            globalNodeNumber++;
            currentNode.SetNumberInSequence(globalNodeNumber);
        }
        /// <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;
            }
        }
Пример #26
0
 public void SetLowerNode(ref StoryNode node)
 {
     lowerNode = node;
 }
Пример #27
0
 /// <summary>
 /// Constructor method for story graph, no parameters.
 /// </summary>
 public StoryGraph()
 {
     root  = new StoryNode();
     nodes = new HashSet <StoryNode>();
 }
Пример #28
0
 public void SetRoot(StoryNode newRoot)
 {
     root = newRoot;
     AddNode(newRoot);
 }
Пример #29
0
 public bool FindNode(StoryNode node)
 {
     return(nodes.Contains(node));
 }
Пример #30
0
 /// <summary>
 /// Adds a node to the list of nodes in the story graph.
 /// </summary>
 /// <param name="newNode"></param>
 public void AddNode(StoryNode newNode)
 {
     nodes.Add(newNode);
 }