private static string EncodeMove(OperationDirectionPair pair) { string result; if (pair.Direction == Direction.Up) { result = "u"; } else if (pair.Direction == Direction.Down) { result = "d"; } else if (pair.Direction == Direction.Left) { result = "l"; } else if (pair.Direction == Direction.Right) { result = "r"; } else { throw new InvalidOperationException("Invalid direction"); } if (pair.Operation != Operation.Move) { result = result.ToUpper(); } if (pair.Operation == Operation.Pull) { result = "-" + result; } return result; }
public bool Move(OperationDirectionPair pair) { return Move(pair.Operation, pair.Direction); }
protected void CollectSolution(Node leaf) { foundSolution = true; // Don't bother if we're not collection solutions. if (!collectSolutions) { return; } // Prepare to construct the solution. MoveList solution = new MoveList(); Level tempLevel = new Level(originalLevel); tempLevel.Validate = validate; PathFinder tempFinder = PathFinder.CreateInstance(tempLevel, true); // Iterate over the nodes from the root to the leaf. int previousPushes = 0; #if false List<Node> nodeList = FindParents(root, leaf); #else List<Node> nodeList = new List<Node>(); for (int i = 0; i < current.ParentIndex; i++) { nodeList.Add(current.Parents[i]); } nodeList.Add(leaf); #endif foreach (Node node in nodeList) { // Check whether we need to move the sokoban. if (node.Coordinate != tempLevel.SokobanCoordinate) { // Move the sokoban to the box. solution.AddRange(tempFinder.FindAndGetPath(node.Coordinate)); tempLevel.MoveSokoban(node.Coordinate); } // Check whether we need to push a box. int consecutivePushes = node.Pushes - previousPushes; if (consecutivePushes != 0) { // Push the box one or more times. OperationDirectionPair push = new OperationDirectionPair(Levels.Operation.Push, node.Direction); for (int j = 0; j < consecutivePushes; j++) { solution.Add(push); tempLevel.Move(push); } previousPushes = node.Pushes; } } // Validate the solution. if (!tempLevel.IsComplete) { throw Abort("constructed move list does not solve level"); } if (optimizeMoves && solution.Count != leaf.Moves) { throw Abort("constructed move list does not match leaf tree in moves"); } if (LevelUtils.SolutionPushes(solution) != leaf.Pushes) { throw Abort("constructed move list does not match leaf tree in pushes"); } // Add the solution. solutions.Add(solution); int moves = solution.Count; int pushes = LevelUtils.SolutionPushes(solution); moveLimit = Math.Min(moveLimit, moves); pushLimit = Math.Min(pushLimit, pushes); #if DEBUG if (verbose) { Log.DebugPrint(" found solution: {0}/{1}", moves, pushes); } #endif }