Example #1
0
        public void FloodFill()
        {
            Bitmap map = new Bitmap(new string[]
                                        {
                                            "111111111111111111",
                                            "100000000000001001",
                                            "100000000000001001",
                                            "100001111111001001",
                                            "100001010001001001",
                                            "100001000101001001",
                                            "100001111111000001",
                                            "111011000000001111",
                                            "100000001000010001",
                                            "100000001000010001",
                                            "111111111111111111"
                                        });

            Debug.WriteLine(map.ToString());

            Evaluator<LocationNode> eval = new Evaluator<LocationNode>();
            FloodFillStrategy strategy = new FloodFillStrategy(map, new VectorInt(2, 2));
            eval.Evaluate(strategy);

            Debug.WriteLine(strategy.Result.ToString());

            List<LocationNode> path = strategy.GetShortestPath(new VectorInt(9, 9));
            Assert.IsNotNull(path);

            Debug.WriteLine(StringHelper.Join(path, delegate(LocationNode node) { return node.Location.ToString(); }, ", "));

            Debug.WriteLine(map.ToString());

            // Expected value
            Assert.AreEqual(new VectorInt(9, 9), path[path.Count - 1].Location);
        }
Example #2
0
        /// <summary>
        /// Generate a static move map, ie. all positions for which a player could move to in the course of a puzzle
        /// </summary>
        /// <param name="Map"></param>
        /// <returns></returns>
        public static Bitmap GenerateStaticMoveMap(SokobanMap Map)
        {
            Bitmap boundry = GenerateBoundryMap(Map);

            // Flood fill from player position to remove any unreachable positions
            FloodFillStrategy floodFill = new FloodFillStrategy(boundry, Map.Player);
            Evaluator<LocationNode> eval = new Evaluator<LocationNode>();
            eval.Evaluate(floodFill);

            return floodFill.Result;
        }
Example #3
0
        /// <summary>
        /// Generate the move map for a current position
        /// </summary>
        /// <param name="boundryMap"></param>
        /// <param name="crateMap">May be null, assumes boundryMap is constraintmap</param>
        /// <param name="playerPosition"></param>
        /// <returns></returns>
        public static Bitmap GenerateMoveMap(Bitmap boundryMap, Bitmap crateMap, VectorInt playerPosition)
        {
            Bitmap constraints = boundryMap;
            if (crateMap != null) constraints = boundryMap.BitwiseOR(crateMap);

            // Flood fill from player position to remove any unreachable positions
            FloodFillStrategy floodFill = new FloodFillStrategy(constraints, playerPosition);
            Evaluator<LocationNode> eval = new Evaluator<LocationNode>();
            eval.Evaluate(floodFill);

            return floodFill.Result;
        }
Example #4
0
        /// <summary>
        /// Find the shortest path from the player position to a destination position
        /// </summary>
        /// <param name="Map">Map</param>
        /// <param name="Destination">Destination goal position</param>
        /// <returns>NULL if no path is found</returns>
        public static List<VectorInt> FindPlayerPath(SokobanMap Map, VectorInt Destination)
        {
            Bitmap boundry = MapAnalysis.GenerateBoundryMap(Map);
            boundry = boundry.BitwiseOR(MapAnalysis.GenerateCrateMap(Map));

            // Find all positble moves for the player
            FloodFillStrategy floodFill = new FloodFillStrategy(boundry, Map.Player);
            Evaluator<LocationNode> eval = new Evaluator<LocationNode>();
            eval.Evaluate(floodFill);

            List<LocationNode> result = floodFill.GetShortestPath(Destination);
            if (result == null) return null;

            // Path found, convert to VectoInt
            return result.ConvertAll<VectorInt>(delegate(LocationNode item) { return item.Location; });
        }
Example #5
0
        /// <summary>
        /// Find Rooms based on door positions
        /// </summary>
        private void AnalyseRooms()
        {
            int roomID = 0;
            foreach (Door door in doors)
            {
                foreach (VectorInt exit in door.Exits)
                {
                    // Does this belong to a room already?
                    if (FindRooms(exit.X, exit.Y) == null)
                    {
                        roomID++;
                        Room newRoom = new Room("R" + roomID.ToString(), controller.Map.Size);
                        newRoom.Doors.Add(door);

                        // Set Room region
                        Bitmap boundry = controller.StaticAnalysis.BoundryMap.BitwiseOR(doorBitmap);
                        FloodFillStrategy floodfill = new FloodFillStrategy(boundry, exit);

                        Evaluator<LocationNode> eval = new Evaluator<LocationNode>();
                        eval.Evaluate(floodfill);

                        // Set region from floodfill
                        newRoom.Set(floodfill.Result);
                        newRoom[exit] = true; // Make sure the exit is also in the room

                        newRoom.Goals = newRoom.BitwiseAND(controller.StaticAnalysis.GoalMap).Count;
                        if (newRoom.Goals == 0)
                        {
                            newRoom.Roomtype = Room.RoomTypes.StorageRoom;
                        }
                        else
                        {
                            newRoom.Roomtype = Room.RoomTypes.GoalRoom;
                        }

                        // Human Readable name
                        newRoom.Name = newRoom.Description;

                        // Link to other doors
                        LinkDoors(newRoom);

                        // Add it the size if more than one floor space
                        if (newRoom.Count > 1)
                        {
                            rooms.Add(newRoom);

                            controller.DebugReport.AppendHeading(3,"{0} Room ({1}) found with {2} goals:", newRoom.Roomtype, newRoom.Name, newRoom.Goals);
                            controller.DebugReport.Append("Doors: {0}",  StringHelper.Join(newRoom.Doors,
                                delegate(Door item)
                                    {
                                        return string.Format("{0}({2})@{1}", item.Type, item.Position, item.DoorID);
                                    }, ", "));
                            controller.DebugReport.Append(newRoom.ToString());
                            controller.DebugReport.CompleteSection();
                        }
                    }
                }
            }
            controller.DebugReport.CompleteSection();
        }