/// <summary>
        /// Executes the move while updating environment.
        /// </summary>
        /// <param name="move">The move.</param>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="testMap">The test map.</param>
        private void ExecuteMoveUpdatingEnvironment(Move move, ref int x, ref int y, char[,] map, ref char[,] testMap)
        {
            // Move cursor to the new location
            TreeHelpers.CalculateMove(move, ref x, ref y, this.mapDims[0], this.mapDims[1]);

            // Determine if our movement would have pushed a crate
            bool pushCrate = testMap[x, y] == AlgorithmConstants.crate || testMap[x, y] == AlgorithmConstants.filledGoal;

            // Figure out what the spot I just move from was before we ever started
            char previous = map[x, y];

            // If it was a crate, make it a tile (cuz it was obviously moved) and put a target there if we moved off the 't'
            char replacement = (previous == AlgorithmConstants.target || previous == AlgorithmConstants.filledGoal) ? AlgorithmConstants.target : AlgorithmConstants.tile;

            // Put whatever should replace where the crate was
            testMap[x, y] = replacement;

            // Move the crate to its new home
            if (pushCrate)
            {
                int x2 = x;
                int y2 = y;
                TreeHelpers.CalculateMove(move, ref x2, ref y2, this.mapDims[0], this.mapDims[1]);
                testMap[x2, y2] = testMap[x2, y2] == AlgorithmConstants.target ? AlgorithmConstants.filledGoal : AlgorithmConstants.crate;
            }
        }
Example #2
0
        /// <summary>
        /// Executes the move while updating environment.
        /// </summary>
        /// <param name="move">The move.</param>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="testMap">The test map.</param>
        public virtual void ExecuteMoveUpdatingEnvironment(Move move, ref int x, ref int y, ref List <int[]> crateLocations)
        {
            // Move cursor to the new location
            TreeHelpers.CalculateMove(move, ref x, ref y, this.mapDims[0], this.mapDims[1]);

            int childX = x;
            int childY = y;

            // Determine if we walked into a crate
            if (crateLocations.Exists(crate => crate[0] == childX && crate[1] == childY))
            {
                // If so, push the crate.
                this.PushCrate(move, childX, childY, ref crateLocations);
            }
        }
        /// <summary>
        /// Evaluates the move.
        /// </summary>
        /// <param name="move">The move.</param>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="testMap">The test map.</param>
        /// <returns>The state of the next node after a move</returns>
        private State EvaluateMove(Move move, int x, int y, char[,] testMap)
        {
            // Given a current location and action or "Move", determine our new x & y and return if we are inbounds or not
            bool inbounds = TreeHelpers.CalculateMove(move, ref x, ref y, this.mapDims[0], this.mapDims[1]);

            // If out of bounds return that this is an invalid movement
            if (!inbounds)
            {
                return(State.Invalid);
            }

            // If in bounds, return the validity of the move based on if you walking into walks, crates, crates in-front of walls, etc.
            switch (testMap[x, y])
            {
            case AlgorithmConstants.tile:
                return(State.Queued);

            case AlgorithmConstants.filledGoal:
            case AlgorithmConstants.crate:
                inbounds = TreeHelpers.CalculateMove(move, ref x, ref y, this.mapDims[0], this.mapDims[1]);
                if (!inbounds)
                {
                    return(State.Invalid);
                }

                switch (testMap[x, y])
                {
                case AlgorithmConstants.tile:
                case AlgorithmConstants.target:
                    return(State.Queued);

                default:
                    return(State.Invalid);
                }

            case AlgorithmConstants.wall:
                return(State.Invalid);

            case AlgorithmConstants.target:
                return(State.Goal);

            default:
                return(State.Invalid);
            }
        }
Example #4
0
        /// <summary>
        /// Evaluates the move.
        /// </summary>
        /// <param name="move">The move.</param>
        /// <param name="node">The node.</param>
        /// <param name="crateMoved">if set to <c>true</c> [crate moved].</param>
        /// <returns>
        /// If the move is valid and if a crate was moved
        /// </returns>
        public bool MoveIsValid(Move move, BaseNode node, out bool crateMoved)
        {
            crateMoved = false;
            int          x = node.X;
            int          y = node.Y;
            List <int[]> crateLocations = new List <int[]>();

            node.CrateLocations.ForEach(crate => crateLocations.Add(new int[] { crate[0], crate[1] }));

            // Given a current location and action or "Move", determine our new x & y and return if we are inbounds or not
            bool inbounds = TreeHelpers.CalculateMove(move, ref x, ref y, this.mapDims[0], this.mapDims[1]);

            // If out of bounds return that this is an invalid movement
            if (!inbounds)
            {
                return(false);
            }

            // If we walked into a crate
            if (node.CrateLocations.Exists(crate => crate[0] == x && crate[1] == y))
            {
                // Push the crate and see if it moved
                crateMoved = this.PushCrate(move, x, y, ref crateLocations);

                // If the crate moved, this is a valid move, if it didn't this isn't valid
                if (crateMoved)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            // We know our movement is in bounds and not into a crate; make sure it isn't into a wall
            if (this.map[x, y] == wall)
            {
                return(false);
            }

            // We didn't walk into a crate, a wall, or out of bounds so this move must be valid.
            return(true);
        }
Example #5
0
        /// <summary>
        /// Pushes the crate.
        /// </summary>
        /// <param name="move">The move.</param>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="crates">The crates.</param>
        /// <returns>True if the crate successfully moved; else false.</returns>
        public bool PushCrate(Move move, int x, int y, ref List <int[]> crates)
        {
            // If we walked into a crate, determine if we can push it
            int[] pushedCrate = crates.Find(crate => crate[0] == x && crate[1] == y);

            // Calculate where the crate would need to move to
            bool inbounds = TreeHelpers.CalculateMove(move, ref x, ref y, this.mapDims[0], this.mapDims[1]);

            // Make sure crate movement is allowed (i.e. within bounds and not into a wall or crate).
            bool crateMoved = inbounds && !crates.Exists(crate => crate[0] == x && crate[1] == y) && this.map[x, y] != AlgorithmConstants.wall && !OptimizationService.Instance.Optimizer.IsCrateMoveSubOptimal(x, y);

            if (crateMoved)
            {
                pushedCrate[0] = x;
                pushedCrate[1] = y;
            }

            return(crateMoved);
        }
        /// <summary>
        /// Moves the is valid.
        /// </summary>
        /// <param name="move">The move.</param>
        /// <param name="node"></param>
        /// <returns>
        /// If the move is valid with no regard for if the crate moved
        /// </returns>
        public override bool MoveIsValid(AlgorithmConstants.Move move, BaseNode node)
        {
            if (!this.reversed)
            {
                return(base.MoveIsValid(move, node));
            }
            else
            {
                int x = node.X;
                int y = node.Y;

                bool inbounds = TreeHelpers.CalculateMove(move, ref x, ref y, this.mapDims[0], this.mapDims[1]);

                if (inbounds && this.map[x, y] != AlgorithmConstants.wall && !node.CrateLocations.Exists(crate => crate[0] == x && crate[1] == y))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }