public DijkstraPathFinder(Level level) : base(level) { data = level.Data; rowLimit = level.Height - 1; insideCoordinates = level.InsideCoordinates; int m = level.Height * level.Width; q = new FixedQueue<Vertex>(m); // Initialize the vertex map. vertexMap = new Array2D<Vertex>(level.Height, level.Width); foreach (Coordinate2D coord in level.Coordinates) { Vertex vertex = new Vertex(coord.Row, coord.Column); vertex.Distance = DefaultInaccessible; vertex.Visited = true; vertexMap[coord.Row, coord.Column] = vertex; } // Calculate the neighbors of each coordinate. foreach (Coordinate2D coord in level.InsideCoordinates) { Vertex vertex = vertexMap[coord]; List<Vertex> neighbors = new List<Vertex>(); foreach (Coordinate2D neighbor in coord.FourNeighbors) { if (level.IsFloor(neighbor)) { neighbors.Add(vertexMap[neighbor]); } } vertex.Neighbors = neighbors.ToArray(); } }
public RegionFinder(Level level) { this.level = level; this.insideCoordinates = level.InsideCoordinates; this.boxCoordinates = level.BoxCoordinates; this.boxes = boxCoordinates.Length; }
protected ArrayPathFinder(Level level) : base(level) { data = level.Data; boxCoordinates = level.BoxCoordinates; boxCount = boxCoordinates.Length; n = level.Width; m = level.Height * level.Width; q = new FixedQueue<int>(m); firstInside = -1; lastInside = -1; neighborMap = new int[m][]; foreach (Coordinate2D coord in level.InsideCoordinates) { lastInside = coord.Row * n + coord.Column; if (firstInside == -1) { firstInside = lastInside; } List<int> neighbors = new List<int>(); foreach (Coordinate2D neighbor in coord.FourNeighbors) { if (level.IsFloor(neighbor)) { neighbors.Add(neighbor.Row * n + neighbor.Column); } } neighborMap[coord.Row * n + coord.Column] = neighbors.ToArray(); } insideCount = lastInside - firstInside + 1; }
public DeadlockFinder(Level level) { this.level = level; CalculateSimpleDeadlockMap(); Initialize(); }
protected DeadlockFinder(Level level, Array2D<bool> simpleDeadlockMap) { this.level = level; this.simpleDeadlockMap = simpleDeadlockMap; Initialize(); }
public IncrementalAnyPathFinder(Level level) : base(level) { this.isDirty = true; this.insideCoordinates = level.InsideCoordinates; this.visited = new bool[m]; }
public BackwardsSubsetSolver(Level originalLevel, Level level, int capacity, bool assessPossibility) : base(level, incremental) { this.originalLevel = originalLevel; this.boxCoordinates = level.BoxCoordinates; this.boxes = boxCoordinates.Length; this.assessPossibility = assessPossibility; this.capacity = capacity; useReliablePositionSet = true; // Create a set of visited positions, // assuming three sokoban squares per position. if (useReliablePositionSet) { // A useReliablePositionSet position set does not need to be validated. visited = ReliablePositionSet.CreateInstance(level, 3 * capacity); } else { // An unreliable position set might miss some achievable // positions and as a result deadlocks calculated using // it need to be validated as truly unsolvable. visited = new UnreliablePositionSet(level, 3 * capacity); } // Create scratch arrays for solving. regions = new Coordinate2D[level.InsideSquares]; solvedArray = new bool[level.InsideSquares]; }
public int this[Level level] { get { return Lookup(level); } }
public static RegionFinder CreateInstance(Level level) { #if false return new BruteForceRegionFinder(level); #else return new IncrementalRegionFinder(level); #endif }
public BruteForceRegionFinder(Level level) : base(level) { this.pathFinder = PathFinder.CreateInstance(level); // Initialize map of coordinates already tried. tried = new Array2D<bool>(level.Height, level.Width); }
public IncrementalRegionFinder(Level level) : base(level) { this.data = level.Data; this.pathFinder = new IncrementalAnyPathFinder(level); this.rowLimit = level.Height - 1; this.accessibleSquaresLimit = level.InsideSquares - level.Boxes; }
public static Coordinate2D FindFirstTarget(Level level) { foreach (Coordinate2D coord in level.TargetCoordinates) { return coord; } return Coordinate2D.Undefined; }
public ComparisonDeadlockFinder(Level level, DeadlockFinder finder1, DeadlockFinder finder2, bool detectMisses1, bool detectMisses2) : base(level) { this.finder1 = finder1; this.finder2 = finder2; this.detectMisses1 = detectMisses1; this.detectMisses2 = detectMisses2; }
public void Initialize(Level level, PathFinder pathFinder) { Level = level; PathFinder = pathFinder; SokobanRow = level.SokobanRow; SokobanColumn = level.SokobanColumn; level.RemoveSokoban(); HashKey = level.GetOccupantsHashKey(); }
public static DeadlockFinder LoadDeadlocks(Level level, string deadlocksDirectory) { string deadlockFilename = GetDeadlockFilename(level, deadlocksDirectory); if (File.Exists(deadlockFilename)) { return DeadlockFinder.CreateInstance(level, DeadlockUtils.GetDeadlocks(new LevelSet(deadlockFilename))); } return null; }
protected SubsetSolver(Level level, bool incremental) { this.level = level; pathFinder = PathFinder.CreateInstance(level,false, incremental); regionFinder = RegionFinder.CreateInstance(level); sokobanMap = new Array2D<bool>(level.Height, level.Width); cancelInfo = new CancelInfo(); }
public static Coordinate2D FindFirstEmpty(Level level) { foreach (Coordinate2D coord in level.InsideCoordinates) { if (level.IsEmpty(coord)) { return coord; } } return Coordinate2D.Undefined; }
public SmallLevelShortestPathFinder(Level level) : base(level) { // The longest possible distance for a level is a serpentine // path connecting all the inside squares. if (level.InsideSquares > MaximumInsideSquares) { throw new InvalidOperationException("level contains too many inside squares for this path finder"); } DerivedInaccessible = DistanceType.MaxValue - 1; distance = new DistanceType[m]; }
public static bool AllBoxesAndTargetsAreAccessible(Level level) { Level emptyLevel = GetEmptyLevel(level); PathFinder finder = PathFinder.CreateInstance(emptyLevel); finder.Find(level.SokobanCoordinate); foreach (Coordinate2D coord in level.InsideCoordinates) { if (level.IsBoxOrTarget(coord) && !finder.IsAccessible(coord)) { return false; } } return true; }
public static void ShowDeadlocks(TextWriter writer, bool verbose, Level level, IEnumerable<Deadlock> deadlocks) { if (verbose) { // Enumerate deadlocked sets. foreach (Deadlock deadlock in deadlocks) { ShowDeadlock(writer, level, deadlock); } } // Collect statistics about the deadlocks. int maxSetSize = 100; int total = 0; int[] totalSized = new int[maxSetSize + 1]; int conditional = 0; int[] conditionalSized = new int[maxSetSize + 1]; foreach (Deadlock deadlock in deadlocks) { if (deadlock.Coordinates.Length < totalSized.Length) { totalSized[deadlock.Coordinates.Length]++; if (deadlock.SokobanMap != null) { conditionalSized[deadlock.Coordinates.Length]++; } } total++; if (deadlock.SokobanMap != null) { conditional++; } } // Print out the statistics. for (int size = 0; size < totalSized.Length; size++) { if (totalSized[size] == 0) { continue; } writer.WriteLine("{0} deadlocks with set size {1}, conditional: {2}", totalSized[size], size, conditionalSized[size]); } // Print out the summary. writer.WriteLine("------"); writer.WriteLine("{0} deadlocks total, conditional: {1}", total, conditional); }
public TableBasedDeadlockFinder(Level level, IEnumerable<Deadlock> deadlocks) : base(level) { Initialize(); // Iterate over all the deadlocks. foreach (Deadlock deadlock in deadlocks) { // Add the entry. AddDeadlock(deadlock); } // Finish adding deadlocks. PromoteDeadlocks(); }
public ForewardsSubsetSolver(Level level) : base(level) { // Create a solver that won't try to create us recursively. #if DEBUG_LOWer_BOUND solver = Solver.CreateInstance(SolverAlgorithm.BruteForce); #else solver = Solver.CreateInstance(SolverAlgorithm.LowerBound); #endif solver.Level = level; solver.CollectSolutions = false; solver.OptimizeMoves = false; solver.OptimizePushes = true; solver.CalculateDeadlocks = false; solver.Verbose = false; solver.Validate = false; }
public SmallLevelAnyPathFinder(Level level) : base(level) { if (level.InsideSquares > MaximumInsideSquares) { throw new InvalidOperationException("level contains too many inside squares for this path finder"); } visitedBit = new BitStringType[m]; int index = 0; foreach (Coordinate2D coord in level.InsideCoordinates) { int u = coord.Row * n + coord.Column; BitStringType bit = (BitStringType)1u << index; visitedBit[u] = bit; index++; } }
protected override void PrepareToSolve() { base.PrepareToSolve(); if (scoreCounts == null) { scoreCounts = new int[Node.MaxScore + 1]; } else { Array.Clear(scoreCounts, 0, scoreCounts.Length); } scoreTotal = 0; // Avoid work when operating quietly. if (verbose) { bestLowerBound = int.MaxValue; bestLevel = new Level(originalLevel); } }
private int GetLowerBound(Node child) { int lowerBound = GetSimpleLowerBound(); #if false int lowerBound = GetSimpleLowerBound(); int lowerBound = GetTakenLowerBound(); int lowerBound = GetMatchingLowerBound(); int lowerBound = 0; #endif #if DEBUG child.LowerBound = lowerBound; #endif if (verbose && lowerBound < bestLowerBound) { bestLowerBound = lowerBound; bestLevel = new Level(level); bestLevel.AddSokoban(current.SokobanRow, current.SokobanColumn); } return lowerBound; }
private void PrintTreeWithLevels(Node node, Level level, PathFinder pathFinder) { Print(node); HashKey hashKey = GetPrintHashKey(level, pathFinder); if (transpositionTable.ContainsKey(hashKey)) { Node other = transpositionTable[hashKey]; Log.DebugPrint("table node: {0}", Node.IsEmpty(other) ? -1 : other.ID); } else { Log.DebugPrint("not in table"); } Print(level); MoveState state = new MoveState(); state.PrepareToMove(node, ref current); foreach (Node child in node.Children) { state.DoMove(child, ref current); PrintTreeWithLevels(child, level, pathFinder); state.UndoMove(ref current); } state.FinishMoving(ref current); }
private void PrintTreeWithLevels(Node node) { Level level = new Level(solver.Level); current.Initialize(level, PathFinder.CreateInstance(level, false, true)); PathFinder pathFinder = PathFinder.CreateInstance(level); PrintTreeWithLevels(node, level, pathFinder); }
private void Print(Level level) { level.AddSokoban(current.SokobanCoordinate); Log.DebugPrint(level.AsText); level.RemoveSokoban(); }
private HashKey GetPrintHashKey(Level level, PathFinder pathFinder) { if (solver.OptimizeMoves) { return level.GetOccupantsHashKey(); } Coordinate2D sokobanCoord = level.SokobanCoordinate; pathFinder.Find(); Coordinate2D proxySokobanCoord = pathFinder.GetFirstAccessibleCoordinate(); level.MoveSokoban(proxySokobanCoord); HashKey hashKey = level.GetOccupantsHashKey(); level.MoveSokoban(sokobanCoord); return hashKey; }
public Level(Level other) : base(new Array2D<Cell>(other.Data)) { // Copy state information. name = other.name; sokobanAssessed = other.sokobanAssessed; boxesAssessed = other.boxesAssessed; outsideAssessed = other.outsideAssessed; sokobanRow = other.sokobanRow; sokobanColumn = other.sokobanColumn; sokobans = other.sokobans; boxes = other.boxes; targets = other.targets; insideSquares = other.insideSquares; isClosed = other.isClosed; unfinishedBoxes = other.unfinishedBoxes; markAccessible = other.markAccessible; validate = other.validate; boxMap = new Array2D<int>(other.boxMap); boxCoordinates = (Coordinate2D[])other.BoxCoordinates.Clone(); insideCoordinates = other.insideCoordinates; Initialize(); }