Esempio n. 1
0
 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;
 }
Esempio n. 2
0
 public bool Move(OperationDirectionPair pair)
 {
     return Move(pair.Operation, pair.Direction);
 }
Esempio n. 3
0
        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
        }