static IFastImage Visualize(CellBoard board, bool showOnlyLargestArea, int scale = 1) { if (showOnlyLargestArea) { var(area, size) = ConnectedAreaAnalyzer .FindForegroundAreas(board.Dimensions, p => board[p] == CellType.Dead) .MaxBy(component => component.Area) ?.TrimExcess(1) ?? throw new InvalidOperationException("This can't happen"); return(GenericVisualizer.RenderBinary(size, isTrue: area.Contains, trueColor: SKColors.White, falseColor: SKColors.Black, scale: scale)); } else { return(GenericVisualizer.RenderBinary(board.Dimensions, isTrue: p => board[p] == CellType.Dead, trueColor: SKColors.White, falseColor: SKColors.Black, scale: scale)); } }
public static CellBoard RemoveNoise(this CellBoard board) { var aliveAreas = ConnectedAreaAnalyzer .FindForegroundAreas(board.Dimensions, p => board[p] == CellType.Alive) .Where(area => area.Area > 64) .ToArray(); return(new CellBoard(board.Dimensions, pos => aliveAreas.Any(a => a.Contains(pos)) ? CellType.Alive : CellType.Dead)); }
public void Setup() { var random = new Random(3); var board = new CellBoard(new Size(256, 256)) .Fill(random, probabilityAlive: 0.5) .MakeBorderAlive(thickness: 1) .GenerateStandardCave() .ScaleAndSmooth(times: 3) .TrimToLargestDeadArea(); _area = ConnectedAreaAnalyzer .FindForegroundAreas(board.Dimensions, p => board[p] == CellType.Dead) .MaxBy(a => a.Area); }
public void ShowFloorVsCeilingLighting() { void SaveImage(IFastImage image, string description) => image.Save(Path.Combine(_dirInfo.FullName, $"{description}.png")); var random = new Random(Seed); var board = new CellBoard(new(128, 128)) .Fill(random, probabilityAlive: 0.5) .MakeBorderAlive(thickness: 3) .GenerateStandardCave(); var(largestComponent, dimensions) = ConnectedAreaAnalyzer .FindForegroundAreas(board.Dimensions, p => board[p] == CellType.Dead) .OrderByDescending(component => component.Area) .First() .TrimExcess(border: 1); var interior = largestComponent.DetermineInteriorEdgeDistance(Neighborhood.VonNeumann); // Place some lights var lightRange = new LightRange(DarkLevels: 15, LightLevels: 5); var lights = CaveThingPlacement.RandomlyPlaceLights( interior.Where(pair => pair.Value == 2).Select(pair => pair.Key).ToList(), random, lightRange, percentAreaToCover: 0.05, varyHeight: true) .ToArray(); var(floorLighting, ceilingLight) = LightTracer.Trace(dimensions, p => !largestComponent.Contains(p), lightRange, lights); using var floorImg = LightMapVisualizer.Render(floorLighting, lights, largestComponent, scale: 5); using var ceilingImg = LightMapVisualizer.Render(ceilingLight, lights, largestComponent, scale: 5); SaveImage(floorImg, "Floor"); SaveImage(ceilingImg, "Ceiling"); }
public static MapData Create(int seed, string texturePrefix, TextureQueue textureQueue) { var random = new Random(seed); var caveBoard = new CellBoard(new Size(128, 128)) .Fill(random, probabilityAlive: 0.5) .MakeBorderAlive(thickness: 3) .GenerateStandardCave(); var(caveArea, size) = ConnectedAreaAnalyzer .FindForegroundAreas(caveBoard.Dimensions, p => caveBoard[p] == CellType.Dead) .OrderByDescending(a => a.Area) .First() .TrimExcess(border: 1); var interior = caveArea.DetermineInteriorEdgeDistance(Neighborhood.VonNeumann); var alternateFloor = new CellBoard(new Size(size.Width + 1, size.Height + 1)) .Fill(random, probabilityAlive: 0.5) .RunGenerations(6); var alternateCeiling = new CellBoard(new Size(size.Width + 1, size.Height + 1)) .Fill(random, probabilityAlive: 0.5) .RunGenerations(6); var lightRange = new LightRange(DarkLevels: 15, LightLevels: 5); var lights = CaveThingPlacement.RandomlyPlaceLights( interior.Where(pair => pair.Value == 2).Select(pair => pair.Key).ToList(), random, lightRange, percentAreaToCover: 0.05, varyHeight: true) .ToArray(); var(floorLighting, ceilingLighting) = LightTracer.Trace(size, p => !caveArea.Contains(p), lightRange, lights); var(planeMap, sectors, tiles) = CreateGeometry( size, caveArea, alternateFloor, alternateCeiling, floorLighting, ceilingLighting, textureQueue, texturePrefix); var playerPosition = caveArea.First(); var things = lights.Select(light => new Thing( Type: light.Height == LightHeight.Ceiling ? "CeilingCrystal" : "FloorCrystal", X: light.Center.X + 0.5, Y: light.Center.Y + 0.5, Z: 0, Angle: 0, Ambush: false, Skill1: true, Skill2: true, Skill3: true, Skill4: true)).ToList(); things.Add(new Thing( Type: Actor.Player1Start.ClassName, X: playerPosition.X + 0.5, Y: playerPosition.Y + 0.5, Z: 0, Angle: 0, Ambush: false, Skill1: true, Skill2: true, Skill3: true, Skill4: true)); return(new MapData( NameSpace: "Wolf3D", TileSize: 64, Name: "Procedural Cave", Width: size.Width, Height: size.Height, Tiles: tiles, Sectors: sectors, Zones: ImmutableArray.Create(new Zone()), Planes: ImmutableArray.Create(new Plane(Depth: 64)), PlaneMaps: ImmutableArray.Create(planeMap), Things: things.ToImmutableArray(), Triggers: ImmutableArray <Trigger> .Empty)); }