Exemplo n.º 1
0
        protected virtual void PrepareToSolve()
        {
            // Give some feedback because calculating deadlocks can take some time.
            SetInfo("Preparing to solve level...");

            // Start the clock.
            startSnapshot = TimeSnapshot.Now;

            // Put solver in a sane state in case there are any exceptions.
            solutions.Clear();

            // Validate parameter combinations.
            ValidateParameters();

            // Avoid recalculating as much as possible if the level hasn't changed.
            if (!precalculatedLevel)
            {
                PrecalculateLevel();

                // Check for cancellation during pre-calculation.
                if (cancelInfo.Cancel)
                {
                    return;
                }

                precalculatedLevel = true;
            }

            // Avoid reallocating these big data structures for multiple solver runs.
            if (!allocated)
            {
                nodes = new NodeCollection(initialCapacity, validate);
                transpositionTable = new TranspositionTable(nodes, initialCapacity);
                current.Parents = new Node[maxParents];

                allocated = true;
            }
            else
            {
                nodes.Clear();
                transpositionTable.Clear();
            }

            // However, the positions of the occupants might have changed.
            // This gives a performance boost when calculating deadlocks.
            level.CopyOccupantsFrom(originalLevel);
            CheckLevel();

            // The push map depends on the actual starting box positions.
            // This could be avoided if we didn't use the no-box map.
            CalculatePushMap();

            // Initialize solver variables.
            current.ParentIndex = 0;
            level.Validate = validate;
            transpositionTable.Validate = validate;
            foundSolution = false;
            moveLimit = int.MaxValue;
            pushLimit = int.MaxValue;
            duplicates = 0;
            boxStart = 0;

            // Prime the "current" values.
            current.Initialize(level, pathFinder);

            // Create the root of the search tree.
            root = new Node(nodes, current.SokobanRow, current.SokobanColumn, Direction.None, 0, 0);

            // Record the clock.
            donePreparingSnapshot = TimeSnapshot.Now;
        }
Exemplo n.º 2
0
        public bool Solve()
        {
            PrepareToSolve();

            // Check for cancel.
            if (cancelInfo.Cancel)
            {
                SetError("Solver canceled.");
                return false;
            }

            if (!verbose)
            {
                SetInfo("Verbose information not enabled.");
            }
            error = "";

            int depth = 0;
            while (true)
            {
                if (foundSolution && !collectSolutions)
                {
                    break;
                }
                if (Finished())
                {
                    break;
                }
                int lastNodeCount = nodes.Visited;
                SearchTree(root, ++depth);
                if (cancelInfo.Cancel)
                {
                    SetError("Solver canceled.");
                    break;
                }
                if (nodes.Count >= maximumNodes)
                {
                    SetError("Maximum nodes exceeded.");
                    break;
                }
                if (nodes.Visited == lastNodeCount)
                {
                    if (solutions.Count == 0)
                    {
                        SetError("All positions examined lead to dead ends.");
                    }
                    break;
                }
            }

            stopSnapshot = TimeSnapshot.Now;

            SortSolutions();

            // Populate information property.
            if (verbose)
            {
                SetFinalInfo(depth);
            }

            if (validate)
            {
                SolverValidator validator = new SolverValidator(this, nodes, root, transpositionTable);
                validator.CheckDataStructures();
            }

            return foundSolution;
        }