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();
            }
        }
Exemple #2
0
 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);
     }
 }
Exemple #9
0
 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;
 }
Exemple #12
0
 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;
 }
Exemple #14
0
 public void Initialize(Level level, PathFinder pathFinder)
 {
     Level = level;
     PathFinder = pathFinder;
     SokobanRow = level.SokobanRow;
     SokobanColumn = level.SokobanColumn;
     level.RemoveSokoban();
     HashKey = level.GetOccupantsHashKey();
 }
Exemple #15
0
 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;
 }
Exemple #16
0
        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();
        }
Exemple #17
0
 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];
        }
Exemple #19
0
 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;
 }
Exemple #20
0
        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;
 }
Exemple #30
0
        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();
        }