/// <summary> /// Generates a cave-like map using the cellular automata algorithm here: /// http://www.roguebasin.com/index.php?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels. /// See <see cref="Generators.CellularAutomataAreaGenerator"/> for details. This algorithm is identical, except that /// it connects the areas automatically afterward. /// </summary> /// <param name="map"></param> /// <param name="rng"></param> /// <param name="fillProbability"></param> /// <param name="totalIterations"></param> /// <param name="cutoffBigAreaFill"></param> /// <returns>Collection of areas representing the areas of the map before they were connected.</returns> public static IEnumerable <MapArea> GenerateCellularAutomataMap(ISettableMapView <bool> map, IGenerator rng = null, int fillProbability = 40, int totalIterations = 7, int cutoffBigAreaFill = 4) { if (rng == null) { rng = SingletonRandom.DefaultRNG; } // Optimization to allow us to use the existing map if the existing map is an ArrayMap. // otherwise we allocate a temporary ArrayMap and copy it onto the original at the end, // to make sure that we set each value in the final array map only once in the case that // it is something less "quick" than an ArrayMap. (ArrayMap <bool> tempMap, bool wasArrayMap) = getStartingArray(map); // TODO: The above optimization causes an extra arraymap copy in the case of CellularAutomata -- it may be useful to // attempt to eliminate this copy for performance reasons // Generate map Generators.CellularAutomataAreaGenerator.Generate(tempMap, rng, fillProbability, totalIterations, cutoffBigAreaFill); // Calculate connected areas and store before we connect different rooms var areas = MapAreaFinder.MapAreasFor(tempMap, AdjacencyRule.CARDINALS).ToList(); // Connect randomly Connectors.ClosestMapAreaConnector.Connect(tempMap, Distance.MANHATTAN, new Connectors.RandomConnectionPointSelector(rng)); if (!wasArrayMap) { map.ApplyOverlay(tempMap); } return(areas); }
/// <summary> /// Generates a cave-like map using the cellular automata algorithm here: /// http://www.roguebasin.com/index.php?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels. /// See CellularAutomataAreaGenerator for details. This algorithm is identical, except that /// it connects the areas automatically afterward. /// </summary> /// <param name="map"></param> /// <param name="rng"></param> /// <param name="fillProbability"></param> /// <param name="totalIterations"></param> /// <param name="cutoffBigAreaFill"></param> /// <returns></returns> public static IEnumerable <MapArea> GenerateCellularAutomataMap(ISettableMapView <bool> map, IGenerator rng = null, int fillProbability = 40, int totalIterations = 7, int cutoffBigAreaFill = 4) { if (rng == null) { rng = SingletonRandom.DefaultRNG; } // Generate map Generators.CellularAutomataAreaGenerator.Generate(map, rng, fillProbability, totalIterations, cutoffBigAreaFill); // Calculate connected areas and store before we connect different rooms var areas = MapAreaFinder.MapAreasFor(map, AdjacencyRule.CARDINALS).ToList(); // Connect randomly Connectors.ClosestMapAreaConnector.Connect(map, Distance.MANHATTAN, new Connectors.RandomConnectionPointSelector(rng)); return(areas); }
/// <summary> /// Convenience function that creates a MapAreaFinder and returns the result of that /// instances <see cref="MapAreas"/> function. Intended to be used for cases in which the area finder /// will never be re-used. /// </summary> /// <param name="map"> /// Map view indicating which cells should be considered part of a map area and which should not. /// </param> /// <param name="adjacencyMethod">The method used for determining connectivity of the grid.</param> /// <returns>An IEnumerable of each (unique) map area.</returns> static public IEnumerable <MapArea> MapAreasFor(IMapView <bool> map, AdjacencyRule adjacencyMethod) { var areaFinder = new MapAreaFinder(map, adjacencyMethod); return(areaFinder.MapAreas()); }