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));
        }
Пример #3
0
    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);
    }
Пример #4
0
        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");
        }
Пример #5
0
    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));
    }