예제 #1
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;
            }
        }
 public override bool CheckPreconditions(WorldDynamic state)
 {
     return(Agent.Key.GetRole() == AgentRole.USUAL && Agent.Value.GetStatus() &&
            Killer.Key.GetRole() == AgentRole.KILLER && Killer.Value.GetStatus() &&
            Location.Value.SearchAgent(Agent.Key) && Location.Value.SearchAgent(Killer.Key) &&
            Agent.Value.GetObjectOfAngry().AngryCheckAtAgent(Killer.Key));
 }
예제 #3
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();
        }
        /// <summary>
        /// A method that creates a set of goals to pass to agents.
        /// </summary>
        public List <Goal> CreateGoalSet(List <AgentRole> roles)
        {
            // We create an empty list of goals.
            List <Goal> goals = new List <Goal>();

            // For each role, we define own goal type and add it to the list.
            foreach (var role in roles)
            {
                // We create an empty state of the world, which we will later transform into the goal state.
                WorldDynamic newGoalState = new WorldDynamic();

                switch (role)
                {
                case AgentRole.USUAL:
                    Goal standardAgentGoal = new Goal(false, true, false, newGoalState);
                    goals.Add(standardAgentGoal);
                    break;

                case AgentRole.KILLER:
                    Goal killerAgentGoal = new Goal(false, true, false, newGoalState);
                    goals.Add(killerAgentGoal);
                    break;

                case AgentRole.PLAYER:
                    Goal playerGoal = new Goal(false, true, false, newGoalState);
                    goals.Add(playerGoal);
                    break;
                }
            }

            // Returning a list of goals.
            return(goals);
        }
 public override bool CheckPreconditions(WorldDynamic state)
 {
     return(Agent.Key.GetRole() == AgentRole.USUAL && Agent.Value.GetStatus() &&
            Killer.Key.GetRole() == AgentRole.KILLER && Killer.Value.GetStatus() &&
            Location.Value.SearchAgent(Agent.Key) &&
            !Agent.Value.SearchAmongExploredLocations(Location.Key) && Location.Value.CheckEvidence());
 }
예제 #6
0
 /// <summary>
 /// Collects goals from all agents and adds them to the goal list.
 /// </summary>
 public void ExtractGoals(WorldDynamic currentState)
 {
     foreach (var agent in currentState.GetAgents())
     {
         allGoalStates.Add(agent.Value.GetGoal());
     }
 }
        public override void ApplyEffects(ref WorldDynamic state)
        {
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent    = state.GetAgentByName(Agent.Key.GetName());
            KeyValuePair <LocationStatic, LocationDynamic>     stateLocation = state.GetLocationByName(Location.Key.GetName());

            stateAgent.Value.SetTargetLocation(stateLocation.Key);
        }
예제 #8
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;
        }
예제 #9
0
        /// <summary>
        /// Checking whether the application of an action would violate the established constraints.
        /// </summary>
        public bool ConstraintsControl(WorldDynamic currentState, PlanAction action, bool succsessControl)
        {
            WorldDynamic worldForTest = (WorldDynamic)currentState.Clone();

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

            foreach (var constraint in constraints)
            {
                if (!constraint.IsSatisfied(worldForTest))
                {
                    // Cleaning
                    worldForTest = null;
                    GC.Collect();

                    // Return result
                    return(false);
                }
            }

            // Cleaning
            worldForTest = null;
            GC.Collect();

            // Return result
            return(true);
        }
예제 #10
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);
        }
예제 #11
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);
        }
        public override void Fail(ref WorldDynamic state)
        {
            fail = true;

            //KeyValuePair<AgentStateStatic, AgentStateDynamic> stateAgent = state.GetAgentByName(Agent.Key.GetName());
            //KeyValuePair<LocationStatic, LocationDynamic> stateLocation = state.GetLocationByName(Location.Key.GetName());
            //stateAgent.Value.AddExploredLocation(stateLocation.Key);
        }
예제 #13
0
        public override void ApplyEffects(ref WorldDynamic state)
        {
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent = state.GetAgentByName(Agent.Key.GetName());

            stateAgent.Value.IncreaseSkipedTurns();

            stateAgent.Value.DecreaseTimeToMove();
        }
예제 #14
0
 public Goal(Goal clone)
 {
     goalTypeIsLocation   = clone.goalTypeIsLocation;
     goalTypeIsStatus     = clone.goalTypeIsStatus;
     goalTypeIsPossession = clone.goalTypeIsPossession;
     goalState            = (WorldDynamic)clone.goalState.Clone();
     hasHashCode          = clone.hasHashCode;
     hashCode             = clone.hashCode;
 }
예제 #15
0
 public Goal(bool goalTypeLocation, bool goalTypeStatus, bool goalTypePossession, WorldDynamic goalState)
 {
     this.goalTypeIsLocation   = goalTypeLocation;
     this.goalTypeIsStatus     = goalTypeStatus;
     this.goalTypeIsPossession = goalTypePossession;
     this.goalState            = goalState;
     hasHashCode = false;
     hashCode    = 0;
 }
예제 #16
0
 public Goal()
 {
     goalTypeIsLocation   = false;
     goalTypeIsStatus     = false;
     goalTypeIsPossession = false;
     goalState            = new WorldDynamic();
     hasHashCode          = false;
     hashCode             = 0;
 }
예제 #17
0
        public override void ApplyEffects(ref WorldDynamic state)
        {
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent  = state.GetAgentByName(Agent.Key.GetName());
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateKiller = state.GetAgentByName(Killer.Key.GetName());

            stateAgent.Value.ClearTempStates();
            stateKiller.Value.ClearTempStates();

            stateKiller.Value.SetStatus(false);
        }
예제 #18
0
        public bool TakeAction(WorldDynamic state)
        {
            if (CheckPreconditions(state))
            {
                ApplyEffects(ref state);
                return(true);
            }

            return(false);
        }
예제 #19
0
 public override bool CheckPreconditions(WorldDynamic state)
 {
     return(Agent1.Key.GetRole() == AgentRole.USUAL && Agent1.Value.GetStatus() &&
            Agent2.Key.GetRole() == AgentRole.USUAL && Agent2.Value.GetStatus() &&
            Agent3.Key.GetRole() == AgentRole.USUAL &&
            Killer.Key.GetRole() == AgentRole.KILLER &&
            Location.Value.SearchAgent(Agent1.Key) && Location.Value.SearchAgent(Agent2.Key) &&
            (Agent1.Value.GetObjectOfAngry().AngryCheckAtAgent(Agent3.Key) || Agent1.Value.GetObjectOfAngry().AngryCheckAtAgent(Killer.Key)) &&
            !Agent1.Value.GetBeliefs().GetAgentByRole(AgentRole.KILLER).Equals(Killer));
 }
예제 #20
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);
        }
        public override void ApplyEffects(ref WorldDynamic state)
        {
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent1 = state.GetAgentByName(Agent1.Key.GetName());
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent2 = state.GetAgentByName(Agent2.Key.GetName());

            stateAgent1.Value.ClearTempStates();
            stateAgent2.Value.ClearTempStates();

            stateAgent1.Value.SetInterlocutor(stateAgent2);
            stateAgent2.Value.SetInterlocutor(stateAgent1);
        }
예제 #22
0
        public override void ApplyEffects(ref WorldDynamic state)
        {
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent  = state.GetAgentByName(Agent1.Key.GetName());
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent2 = state.GetAgentByName(Agent2.Key.GetName());

            stateAgent.Value.ClearTempStates();
            stateAgent2.Value.ClearTempStates();

            stateAgent2.Value.SetStatus(false);

            stateAgent.Value.DecreaseTimeToMove();
        }
예제 #23
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);
        }
        public override void ApplyEffects(ref WorldDynamic state)
        {
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent     = state.GetAgentByName(Agent.Key.GetName());
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateKiller    = state.GetAgentByName(Killer.Key.GetName());
            KeyValuePair <LocationStatic, LocationDynamic>     stateLocation2 = state.GetLocationByName(Location2.Key.GetName());

            stateAgent.Value.ClearTempStates();
            stateKiller.Value.ClearTempStates();

            stateAgent.Value.SetTargetLocation(stateLocation2.Key);

            stateAgent.Value.DecreaseTimeToMove();
        }
        public override bool IsSatisfied(WorldDynamic state)
        {
            if (temporaryInvulnerability && !permanentInvulnerability && targetAgent.Key != null && targetAgent.Value != null && termOfProtection != 0)
            {
                return((targetAgent.Value.GetStatus() && state.GetStaticWorldPart().GetTurnNumber() <= termOfProtection) || state.GetStaticWorldPart().GetTurnNumber() > termOfProtection);
            }
            else if (permanentInvulnerability && !temporaryInvulnerability && targetAgent.Key != null && targetAgent.Value != null)
            {
                return(targetAgent.Value.GetStatus());
            }

            return(false);
        }
예제 #26
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);
            }
        }
예제 #27
0
        public override void ApplyEffects(ref WorldDynamic state)
        {
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent1 = state.GetAgentByName(Agent1.Key.GetName());
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent2 = state.GetAgentByName(Agent2.Key.GetName());
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent3 = state.GetAgentByName(Agent3.Key.GetName());
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateKiller = state.GetAgentByName(Killer.Key.GetName());

            stateAgent1.Value.ClearTempStates();
            stateAgent2.Value.ClearTempStates();
            stateAgent3.Value.ClearTempStates();
            stateKiller.Value.ClearTempStates();

            stateAgent1.Value.CalmDown();
        }
예제 #28
0
        public override void ApplyEffects(ref WorldDynamic state)
        {
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent  = state.GetAgentByName(Agent.Key.GetName());
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateKiller = state.GetAgentByName(Killer.Key.GetName());

            stateAgent.Value.ClearTempStates();
            stateKiller.Value.ClearTempStates();

            stateAgent.Value.SetStatus(false);
            stateAgent.Value.GetBeliefs().GetAgentByName(stateAgent.Key.GetName()).Dead();
            stateKiller.Value.GetBeliefs().GetAgentByName(stateAgent.Key.GetName()).Dead();

            state.GetLocationByName(state.SearchAgentAmongLocations(stateAgent.Key).GetName()).Value.GetAgent(stateAgent).Value.Die();
        }
        public override void ApplyEffects(ref WorldDynamic state)
        {
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgent      = state.GetAgentByName(Agent.Key.GetName());
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateAgentClone = state.GetLocationByName(Location.Key.GetName()).Value.GetAgent(Agent);
            KeyValuePair <AgentStateStatic, AgentStateDynamic> stateKiller     = state.GetAgentByName(Killer.Key.GetName());
            KeyValuePair <LocationStatic, LocationDynamic>     stateLocation   = state.GetLocationByName(Location.Key.GetName());

            stateAgent.Value.ClearTempStates();
            stateKiller.Value.ClearTempStates();

            stateAgent.Value.AddEvidence(stateKiller.Key);
            stateAgent.Value.GetBeliefs().GetAgentByName(stateKiller.Key.GetName()).AssignRole(AgentRole.KILLER);
            stateAgent.Value.SetObjectOfAngry(stateKiller.Key);
            stateAgent.Value.AddExploredLocation(stateLocation.Key);
        }
예제 #30
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();
        }