public SolverValidator(Solver solver, NodeCollection nodes, Node root, IPositionLookupTable<Node> transpositionTable) { this.solver = solver; this.nodes = nodes; this.root = root; this.transpositionTable = transpositionTable; }
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; }