コード例 #1
0
        public void TestDirectionality()
        {
            var model = new AdjacentModel(DirectionSet.Cartesian2d);

            model.AddAdjacency(new Tile(1), new Tile(2), 1, 0, 0);
            model.SetUniformFrequency();

            var topology = new Topology(2, 1, false);

            var up   = Direction.YPlus;
            var down = Direction.YMinus;

            var edgedPathConstraint = new EdgedPathConstraint(
                new Dictionary <Tile, ISet <Direction> >()
            {
                { new Tile(1), new[] { up, down }.ToHashSet() },
                { new Tile(2), new[] { up, down }.ToHashSet() },
            }
                );

            var propagator = new TilePropagator(model, topology, constraints: new[] { edgedPathConstraint });

            propagator.Run();

            Assert.AreEqual(Resolution.Contradiction, propagator.Status);
        }
コード例 #2
0
        public void TestDirectionality2()
        {
            var model = new AdjacentModel(DirectionSet.Cartesian2d);

            model.AddAdjacency(new Tile(1), new Tile(2), 1, 0, 0);
            model.SetUniformFrequency();

            var topology = new GridTopology(2, 1, false);

            var left  = Direction.XMinus;
            var right = Direction.XPlus;

#pragma warning disable CS0618 // Type or member is obsolete
            var edgedPathConstraint = new EdgedPathConstraint(
#pragma warning restore CS0618 // Type or member is obsolete
                new Dictionary <Tile, ISet <Direction> >()
            {
                { new Tile(1), new[] { left, right }.ToHashSet() },
                { new Tile(2), new[] { left, right }.ToHashSet() },
            }
                );

            var propagator = new TilePropagator(model, topology, constraints: new[] { edgedPathConstraint });

            propagator.Run();
        }
コード例 #3
0
        public List <ITileConstraint> GetConstraints(DirectionSet directions, TileRotation tileRotation)
        {
            var is3d = directions.Type == DirectionSetType.Cartesian3d;

            var constraints = new List <ITileConstraint>();

            if (Config.Ground != null)
            {
                var groundTile = Parse(Config.Ground);
                constraints.Add(new BorderConstraint
                {
                    Sides = is3d ? BorderSides.ZMin : BorderSides.YMax,
                    Tiles = new[] { groundTile },
                });
                constraints.Add(new BorderConstraint
                {
                    Sides      = is3d ? BorderSides.ZMin : BorderSides.YMax,
                    Tiles      = new[] { groundTile },
                    InvertArea = true,
                    Ban        = true,
                });
            }

            if (Config.Constraints != null)
            {
                foreach (var constraint in Config.Constraints)
                {
                    if (constraint is PathConfig pathData)
                    {
                        var tiles = new HashSet <Tile>(pathData.Tiles.Select(Parse));
#pragma warning disable CS0618 // Type or member is obsolete
                        var p = new PathConstraint(tiles, pathData.EndPoints, tileRotation)
#pragma warning restore CS0618 // Type or member is obsolete
                        {
                            EndPointTiles = pathData.EndPointTiles == null ? null : new HashSet <Tile>(pathData.EndPointTiles.Select(Parse))
                        };
                        constraints.Add(p);
                    }
                    else if (constraint is EdgedPathConfig edgedPathData)
                    {
                        var exits = edgedPathData.Exits.ToDictionary(
                            kv => Parse(kv.Key), x => (ISet <Direction>) new HashSet <Direction>(x.Value.Select(ParseDirection)));
#pragma warning disable CS0618 // Type or member is obsolete
                        var p = new EdgedPathConstraint(exits, edgedPathData.EndPoints, tileRotation)
#pragma warning restore CS0618 // Type or member is obsolete
                        {
                            EndPointTiles = edgedPathData.EndPointTiles == null ? null : new HashSet <Tile>(edgedPathData.EndPointTiles.Select(Parse))
                        };
                        constraints.Add(p);
                    }
                    else if (constraint is BorderConfig borderData)
                    {
                        var tiles        = borderData.Tiles.Select(Parse).ToArray();
                        var sides        = borderData.Sides == null ? BorderSides.All : (BorderSides)Enum.Parse(typeof(BorderSides), borderData.Sides, true);
                        var excludeSides = borderData.ExcludeSides == null ? BorderSides.None : (BorderSides)Enum.Parse(typeof(BorderSides), borderData.ExcludeSides, true);
                        if (!is3d)
                        {
                            sides        = sides & ~BorderSides.ZMin & ~BorderSides.ZMax;
                            excludeSides = excludeSides & ~BorderSides.ZMin & ~BorderSides.ZMax;
                        }
                        constraints.Add(new BorderConstraint
                        {
                            Tiles        = tiles,
                            Sides        = sides,
                            ExcludeSides = excludeSides,
                            InvertArea   = borderData.InvertArea,
                            Ban          = borderData.Ban,
                        });
                    }
                    else if (constraint is FixedTileConfig fixedTileConfig)
                    {
                        constraints.Add(new FixedTileConstraint
                        {
                            Tiles = fixedTileConfig.Tiles.Select(Parse).ToArray(),
                            Point = fixedTileConfig.Point,
                        });
                    }
                    else if (constraint is MaxConsecutiveConfig maxConsecutiveConfig)
                    {
                        var axes = maxConsecutiveConfig.Axes?.Select(ParseAxis);
                        constraints.Add(new MaxConsecutiveConstraint
                        {
                            Tiles    = new HashSet <Tile>(maxConsecutiveConfig.Tiles.Select(Parse)),
                            MaxCount = maxConsecutiveConfig.MaxCount,
                            Axes     = axes == null ? null : new HashSet <Axis>(axes),
                        });
                    }
                    else if (constraint is MirrorXConfig mirrorYConfig)
                    {
                        constraints.Add(new MirrorXConstraint
                        {
                            TileRotation = tileRotation,
                        });
                    }
                    else if (constraint is MirrorYConfig mirrorXConfig)
                    {
                        constraints.Add(new MirrorYConstraint
                        {
                            TileRotation = tileRotation,
                        });
                    }
                    else if (constraint is CountConfig countConfig)
                    {
                        constraints.Add(new CountConstraint
                        {
                            Tiles      = new HashSet <Tile>(countConfig.Tiles.Select(Parse)),
                            Comparison = countConfig.Comparison,
                            Count      = countConfig.Count,
                            Eager      = countConfig.Eager,
                        });
                    }
                    else if (constraint is SeparationConfig separationConfig)
                    {
                        constraints.Add(new SeparationConstraint
                        {
                            Tiles       = new HashSet <Tile>(separationConfig.Tiles.Select(Parse)),
                            MinDistance = separationConfig.MinDistance,
                        });
                    }
                    else if (constraint is ConnectedConfig connectedConfig)
                    {
                        constraints.Add(new ConnectedConstraint
                        {
                            PathSpec = GetPathSpec(connectedConfig.PathSpec),
                        });
                    }
                    else if (constraint is LoopConfig loopConfig)
                    {
                        constraints.Add(new LoopConstraint
                        {
                            PathSpec = GetPathSpec(loopConfig.PathSpec),
                        });
                    }
                    else if (constraint is AcyclicConfig acyclicConfig)
                    {
                        constraints.Add(new AcyclicConstraint
                        {
                            PathSpec = GetPathSpec(acyclicConfig.PathSpec),
                        });
                    }
                    else
                    {
                        throw new NotImplementedException($"Unknown constraint type {constraint.GetType()}");
                    }
                }
            }

            return(constraints);
        }
コード例 #4
0
ファイル: Factory.cs プロジェクト: colrich/DeBroglie
        public List <ITileConstraint> GetConstraints(DirectionSet directions, TileRotation tileRotation)
        {
            var is3d = directions.Type == DirectionSetType.Cartesian3d;

            var constraints = new List <ITileConstraint>();

            if (Config.Ground != null)
            {
                var groundTile = Parse(Config.Ground);
                constraints.Add(new BorderConstraint
                {
                    Sides = is3d ? BorderSides.ZMin : BorderSides.YMax,
                    Tiles = new[] { groundTile },
                });
                constraints.Add(new BorderConstraint
                {
                    Sides      = is3d ? BorderSides.ZMin : BorderSides.YMax,
                    Tiles      = new[] { groundTile },
                    InvertArea = true,
                    Ban        = true,
                });
            }

            if (Config.Constraints != null)
            {
                foreach (var constraint in Config.Constraints)
                {
                    if (constraint is PathConfig pathData)
                    {
                        var tiles = new HashSet <Tile>(pathData.Tiles.Select(Parse));
                        var p     = new PathConstraint(tiles, pathData.EndPoints);
                        constraints.Add(p);
                    }
                    else if (constraint is EdgedPathConfig edgedPathData)
                    {
                        var exits = edgedPathData.Exits.ToDictionary(
                            kv => Parse(kv.Key), x => (ISet <Direction>) new HashSet <Direction>(x.Value.Select(ParseDirection)));
                        var p = new EdgedPathConstraint(exits, edgedPathData.EndPoints, tileRotation);
                        constraints.Add(p);
                    }
                    else if (constraint is BorderConfig borderData)
                    {
                        var tiles        = borderData.Tiles.Select(Parse).ToArray();
                        var sides        = borderData.Sides == null ? BorderSides.All : (BorderSides)Enum.Parse(typeof(BorderSides), borderData.Sides, true);
                        var excludeSides = borderData.ExcludeSides == null ? BorderSides.None : (BorderSides)Enum.Parse(typeof(BorderSides), borderData.ExcludeSides, true);
                        if (!is3d)
                        {
                            sides        = sides & ~BorderSides.ZMin & ~BorderSides.ZMax;
                            excludeSides = excludeSides & ~BorderSides.ZMin & ~BorderSides.ZMax;
                        }
                        constraints.Add(new BorderConstraint
                        {
                            Tiles        = tiles,
                            Sides        = sides,
                            ExcludeSides = excludeSides,
                            InvertArea   = borderData.InvertArea,
                            Ban          = borderData.Ban,
                        });
                    }
                    else if (constraint is FixedTileConfig fixedTileConfig)
                    {
                        constraints.Add(new FixedTileConstraint
                        {
                            Tiles = fixedTileConfig.Tiles.Select(Parse).ToArray(),
                            Point = fixedTileConfig.Point,
                        });
                    }
                    else if (constraint is MaxConsecutiveConfig maxConsecutiveConfig)
                    {
                        var axes = maxConsecutiveConfig.Axes?.Select(ParseAxis);
                        constraints.Add(new MaxConsecutiveConstraint
                        {
                            Tiles    = new HashSet <Tile>(maxConsecutiveConfig.Tiles.Select(Parse)),
                            MaxCount = maxConsecutiveConfig.MaxCount,
                            Axes     = axes == null ? null : new HashSet <Axis>(axes),
                        });
                    }
                    else if (constraint is MirrorConfig mirrorConfig)
                    {
                        constraints.Add(new MirrorConstraint
                        {
                            TileRotation = tileRotation,
                        });
                    }
                    else
                    {
                        throw new NotImplementedException($"Unknown constraint type {constraint.GetType()}");
                    }
                }
            }

            return(constraints);
        }
コード例 #5
0
        public void EdgedPathSetup()
        {
            var topology = new GridTopology(15, 15, false);

            var model = new AdjacentModel(DirectionSet.Cartesian2d);

            var empty     = new Tile(" ");
            var straight1 = new Tile("║");
            var straight2 = new Tile("═");
            var corner1   = new Tile("╚");
            var corner2   = new Tile("╔");
            var corner3   = new Tile("╗");
            var corner4   = new Tile("╝");
            var fork1     = new Tile("╠");
            var fork2     = new Tile("╦");
            var fork3     = new Tile("╣");
            var fork4     = new Tile("╩");

            model.AddAdjacency(
                new[] { empty, straight1, corner3, corner4, fork3 },
                new[] { empty, straight1, corner1, corner2, fork1 },
                Direction.XPlus);

            model.AddAdjacency(
                new[] { straight2, corner1, corner2, fork1, fork2, fork4 },
                new[] { straight2, corner3, corner4, fork2, fork3, fork4 },
                Direction.XPlus);

            model.AddAdjacency(
                new[] { empty, straight2, corner1, corner4, fork4 },
                new[] { empty, straight2, corner2, corner3, fork2 },
                Direction.YPlus);

            model.AddAdjacency(
                new[] { straight1, corner2, corner3, fork1, fork2, fork3 },
                new[] { straight1, corner1, corner4, fork1, fork3, fork4 },
                Direction.YPlus);

            model.SetUniformFrequency();

            var exits = new Dictionary <Tile, ISet <Direction> >
            {
                { straight1, new [] { Direction.YMinus, Direction.YPlus }.ToHashSet() },
                { straight2, new [] { Direction.XMinus, Direction.XPlus }.ToHashSet() },
                { corner1, new [] { Direction.YMinus, Direction.XPlus }.ToHashSet() },
                { corner2, new [] { Direction.YPlus, Direction.XPlus }.ToHashSet() },
                { corner3, new [] { Direction.YPlus, Direction.XMinus }.ToHashSet() },
                { corner4, new [] { Direction.YMinus, Direction.XMinus }.ToHashSet() },
                { fork1, new [] { Direction.YMinus, Direction.XPlus, Direction.YPlus }.ToHashSet() },
                { fork2, new [] { Direction.XPlus, Direction.YPlus, Direction.XMinus }.ToHashSet() },
                { fork3, new [] { Direction.YPlus, Direction.XMinus, Direction.YMinus }.ToHashSet() },
                { fork4, new [] { Direction.XMinus, Direction.YMinus, Direction.XPlus }.ToHashSet() },
            };

            var pathConstraint = new EdgedPathConstraint(exits);

            propagator4 = new TilePropagator(model, topology, new TilePropagatorOptions
            {
                BackTrackDepth = -1,
                Constraints    = new[] { pathConstraint },
            });
        }
コード例 #6
0
        public void TestPathPickHeuristic()
        {
            var topology = new GridTopology(15, 15, false);

            var model = new AdjacentModel(DirectionSet.Cartesian2d);

            var empty     = new Tile(" ");
            var straight1 = new Tile("║");
            var straight2 = new Tile("═");
            var corner1   = new Tile("╚");
            var corner2   = new Tile("╔");
            var corner3   = new Tile("╗");
            var corner4   = new Tile("╝");
            var fork1     = new Tile("╠");
            var fork2     = new Tile("╦");
            var fork3     = new Tile("╣");
            var fork4     = new Tile("╩");

            model.AddAdjacency(
                new[] { empty, straight1, corner3, corner4, fork3 },
                new[] { empty, straight1, corner1, corner2, fork1 },
                Direction.XPlus);

            model.AddAdjacency(
                new[] { straight2, corner1, corner2, fork1, fork2, fork4 },
                new[] { straight2, corner3, corner4, fork2, fork3, fork4 },
                Direction.XPlus);

            model.AddAdjacency(
                new[] { empty, straight2, corner1, corner4, fork4 },
                new[] { empty, straight2, corner2, corner3, fork2 },
                Direction.YPlus);

            model.AddAdjacency(
                new[] { straight1, corner2, corner3, fork1, fork2, fork3 },
                new[] { straight1, corner1, corner4, fork1, fork3, fork4 },
                Direction.YPlus);

            model.SetUniformFrequency();

            var exits = new Dictionary <Tile, ISet <Direction> >
            {
                { straight1, new [] { Direction.YMinus, Direction.YPlus }.ToHashSet() },
                { straight2, new [] { Direction.XMinus, Direction.XPlus }.ToHashSet() },
                { corner1, new [] { Direction.YMinus, Direction.XPlus }.ToHashSet() },
                { corner2, new [] { Direction.YPlus, Direction.XPlus }.ToHashSet() },
                { corner3, new [] { Direction.YPlus, Direction.XMinus }.ToHashSet() },
                { corner4, new [] { Direction.YMinus, Direction.XMinus }.ToHashSet() },
                { fork1, new [] { Direction.YMinus, Direction.XPlus, Direction.YPlus }.ToHashSet() },
                { fork2, new [] { Direction.XPlus, Direction.YPlus, Direction.XMinus }.ToHashSet() },
                { fork3, new [] { Direction.YPlus, Direction.XMinus, Direction.YMinus }.ToHashSet() },
                { fork4, new [] { Direction.XMinus, Direction.YMinus, Direction.XPlus }.ToHashSet() },
            };

#pragma warning disable CS0618 // Type or member is obsolete
            var pathConstraint = new EdgedPathConstraint(exits)
#pragma warning restore CS0618 // Type or member is obsolete
            {
                UsePickHeuristic = true
            };

            var propagator = new TilePropagator(model, topology, new TilePropagatorOptions
            {
                BackTrackDepth = -1,
                Constraints    = new[] { pathConstraint },
            });

            propagator.Run();

            Assert.AreEqual(propagator.Status, Resolution.Decided);
        }