/// <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; } }
/// <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); } }
/// <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); }
/// <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); } } }