コード例 #1
0
        public override ExecutionResult Execute(SuperMetroidModel model, InGameState inGameState, int times = 1, bool usePreviousRoom = false)
        {
            IEnumerable <int> visitedNodeIds = inGameState.GetVisitedNodeIds(usePreviousRoom);

            // If the node at which we entered is not allowed, this is not fulfilled.
            if (!NodeIds.Contains(visitedNodeIds.First()))
            {
                return(null);
            }

            // If we have visited a node to avoid, this is not fulfilled.
            if (NodeIdsToAvoid.Intersect(visitedNodeIds).Any())
            {
                return(null);
            }

            // If we were supposed to stay put but have visited more than the starting node, this is not fulfilled
            if (MustStayPut && visitedNodeIds.Count() > 1)
            {
                return(null);
            }

            // If we have destroyed an obstacle that needed to be preserved, this is not fulfilled
            if (ObstaclesIdsToAvoid.Intersect(inGameState.GetDestroyedObstacleIds(usePreviousRoom)).Any())
            {
                return(null);
            }

            // We've avoided all pitfalls. This ResetRoom is fulfilled. Clone the InGameState to fulfill method contract
            return(new ExecutionResult(inGameState.Clone()));
        }
コード例 #2
0
        public AbstractNavigationAction(string intent, SuperMetroidModel model, InGameState initialInGameState, ExecutionResult executionResult) : this(intent)
        {
            Succeeded = true;

            // Initialize position change
            if (initialInGameState.GetCurrentNode() != executionResult.ResultingState.GetCurrentNode())
            {
                PositionChange = (initialInGameState.GetCurrentNode(), executionResult.ResultingState.GetCurrentNode());
            }

            // Initialize gained and lost items
            ItemInventory gainedInventory = executionResult.ResultingState.GetInventoryExceptWith(initialInGameState);
            ItemsGained = gainedInventory;
            // Cannot lose items, just create an empty inventory
            ItemsLost = new ItemInventory(model.StartConditions.BaseResourceMaximums);

            // Initialize enabled and disabled items
            ItemsDisabledNames = executionResult.ResultingState.GetDisabledItemNames().Except(initialInGameState.GetDisabledItemNames());
            ItemsEnabledNames  = initialInGameState.GetDisabledItemNames().Except(executionResult.ResultingState.GetDisabledItemNames());

            // Initialize flags gained
            GameFlagsGained = GameFlagsGained.Concat(executionResult.ResultingState.GetActiveGameFlagsExceptWith(initialInGameState).Values);

            // Initialize locks opened
            LocksOpened = LocksOpened.Concat(executionResult.ResultingState.GetOpenedNodeLocksExceptWith(initialInGameState).Values);

            // Initialize item locations taken
            ItemLocationsTaken = ItemLocationsTaken.Concat(executionResult.ResultingState.GetTakenItemLocationsExceptWith(initialInGameState).Values);

            // Initialize resources before and after
            ResourcesBefore = initialInGameState.GetCurrentResources();
            ResourcesAfter  = executionResult.ResultingState.GetCurrentResources();

            // Initialize destroyed obstacles, but that's only relevant if we didn't change rooms
            if (executionResult.ResultingState.GetCurrentRoom() == initialInGameState.GetCurrentRoom())
            {
                ObstaclesDestroyed = ObstaclesDestroyed.Concat(
                    executionResult.ResultingState.GetDestroyedObstacleIds()
                    .Except(initialInGameState.GetDestroyedObstacleIds())
                    .Select(obstacleId => executionResult.ResultingState.GetCurrentRoom().Obstacles[obstacleId])
                    );
            }

            // Transfer information data from the ExecutionResult.
            // No need to copy since they are IEnumerable and not supposed to be mutated.
            RunwaysUsed             = executionResult.RunwaysUsed;
            CanLeaveChargedExecuted = executionResult.CanLeaveChargedExecuted;
            OpenedLocks             = executionResult.OpenedLocks;
            BypassedLocks           = executionResult.BypassedLocks;
            KilledEnemies           = executionResult.KilledEnemies;

            // Since the set of items is mutable, do not transfer the instance
            ItemsInvolved.UnionWith(executionResult.ItemsInvolved);
            DamageReducingItemsInvolved.UnionWith(executionResult.DamageReducingItemsInvolved);
        }
コード例 #3
0
        public ExecutionResult Execute(SuperMetroidModel model, InGameState inGameState, int times = 1, bool usePreviousRoom = false)
        {
            times = times * model.LogicalOptions.NumberOfTries(this);

            ExecutionResult result = Requires.Execute(model, inGameState, times: times, usePreviousRoom: usePreviousRoom);

            if (result == null)
            {
                return(null);
            }

            // Iterate over intact obstacles that need to be dealt with
            foreach (StratObstacle obstacle in Obstacles.Where(o => !inGameState.GetDestroyedObstacleIds(usePreviousRoom).Contains(o.ObstacleId)))
            {
                // Try destroying the obstacle first
                ExecutionResult destroyResult = result.AndThen(obstacle.DestroyExecution, model, times: times, usePreviousRoom: usePreviousRoom);

                // If destruction fails, try to bypass instead
                if (destroyResult == null)
                {
                    result = result.AndThen(obstacle.BypassExecution, model, times: times, usePreviousRoom: usePreviousRoom);
                    // If bypass also fails, we cannot get past this obstacle. Give up.
                    if (result == null)
                    {
                        return(null);
                    }
                }
                // If destruction succeeded, carry on with the result of that
                else
                {
                    result = destroyResult;
                }
            }

            return(result);
        }