private static Point?GetClosestUnexploredLocation(TerrainMap terrainMap, VisibilityMap visibilityMap, IMovementProfile movementProfile, Point location)
        {
            int   closestDistance = int.MaxValue;
            Point?closestLocation = null;

            // We want to explore rooms before we explore corridors
            DungeonPrefab currentRoom = terrainMap.GetPrefabAtLocation(location);

            // If we are in a room then get the closest unseen location in the room
            foreach (
                Point unseenLocation in
                currentRoom == null
                        ? GetWalkableUnseenLocations(terrainMap, visibilityMap, movementProfile)
                        : GetWalkableUnseenLocationsWithinPrefab(currentRoom, terrainMap, visibilityMap, movementProfile))
            {
                int currentDistance = location.DistanceTo(unseenLocation);
                if (currentDistance >= closestDistance)
                {
                    continue;
                }

                closestDistance = currentDistance;
                closestLocation = unseenLocation;
            }

            return(closestLocation);
        }
        private static Point?GetClosestExploredLocation(TerrainMap terrainMap, VisibilityMap visibilityMap, IMovementProfile movementProfile, Point location)
        {
            int   distance        = int.MaxValue;
            Point?closestLocation = null;

            foreach (var visibleLocation in GetWalkableSeenLocations(terrainMap, visibilityMap, movementProfile))
            {
                int currentDistance = location.DistanceTo(visibleLocation);
                if (currentDistance >= distance)
                {
                    continue;
                }

                distance        = currentDistance;
                closestLocation = visibleLocation;
            }

            return(closestLocation);
        }
 private static IEnumerable <Point> GetWalkableSeenLocations(TerrainMap terrainMap, VisibilityMap visibilityMap, IMovementProfile movementProfile)
 {
     return(from location in visibilityMap.GetSeenLocations()
            where movementProfile.TerrainIsTraversable(terrainMap[location])
            select location);
 }
        private static IEnumerable <Point> GetWalkableUnseenLocationsWithinPrefab(Map <ITerrain> prefab, TerrainMap terrainMap, VisibilityMap visibilityMap, IMovementProfile movementProfile)
        {
            IEnumerable <Point> unseenLocationsInPrefab = from location in prefab.Locations
                                                          where
                                                          movementProfile.TerrainIsTraversable(
                terrainMap[location]) &&
                                                          !visibilityMap[location].WasSeen
                                                          select location;

            // Return any unseen locations within the prefab else return the closest unseen location on the map
            return(unseenLocationsInPrefab.Count() > 0 ? unseenLocationsInPrefab : GetWalkableUnseenLocations(terrainMap, visibilityMap, movementProfile));
        }