示例#1
0
        public void TestPathConstraint()
        {
            var a = new int[, ] {
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 1, 1, 1, 1, 0, 0 },
                { 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0 }
            };

            var model      = OverlappingModel.Create(a, 3, false, 8);
            var propagator = new TilePropagator(model, new Topology(10, 10, false), true, constraints: new[] {
                new PathConstraint(new HashSet <Tile> {
                    new Tile(1)
                }, new [] { new Point(0, 0), new Point(9, 9) })
            });
            var status = propagator.Run();

            Assert.AreEqual(Resolution.Decided, status);
            var result = propagator.ToValueArray <int>().ToArray2d();

            // Write out result for debugging
            for (var y = 0; y < 10; y++)
            {
                for (var x = 0; x < 10; x++)
                {
                    Console.Write(result[x, y]);
                }
                Console.WriteLine();
            }
            // Simple flood fill algorithm to determine we have in fact got a path
            var stack   = new Stack <ValueTuple <int, int> >();
            var visited = new bool[10, 10];

            stack.Push((0, 0));
            while (stack.TryPop(out var current))
            {
                var(x, y) = current;
                if (x < 0 || x >= 10 || y < 0 || y >= 10)
                {
                    continue;
                }
                if (visited[x, y])
                {
                    continue;
                }
                visited[x, y] = true;
                if (result[x, y] == 1)
                {
                    if (x == 9 && y == 9)
                    {
                        return;
                    }
                    stack.Push((x + 1, y));
                    stack.Push((x - 1, y));
                    stack.Push((x, y + 1));
                    stack.Push((x, y - 1));
                }
            }
            Assert.Fail();
        }
        public void TestConnectedConstraintWithEdged()
        {
            var a = new int[, ] {
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 1, 1, 1, 1, 0, 0 },
                { 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0 }
            };

            var allDirections = DirectionSet.Cartesian2d.ToHashSet();

            var exits = new Dictionary <Tile, ISet <Direction> >()
            {
                { new Tile(1), allDirections },
            };

            var seed = Environment.TickCount;
            var r    = new Random(seed);

            Console.WriteLine("Seed {0}", seed);

            var model = OverlappingModel.Create(a, 3, false, 8);

            var constraint = new ConnectedConstraint
            {
                PathSpec = new EdgedPathSpec
                {
                    Exits         = exits,
                    RelevantCells = new[] { new Point(0, 0), new Point(9, 9) },
                }
            };

            var propagator = new TilePropagator(model, new GridTopology(10, 10, false), new TilePropagatorOptions
            {
                BackTrackDepth = -1,
                Constraints    = new[] { constraint },
                RandomDouble   = r.NextDouble
            });
            var status = propagator.Run();

            Assert.AreEqual(Resolution.Decided, status);
            var result = propagator.ToValueArray <int>().ToArray2d();

            // Write out result for debugging
            for (var y = 0; y < 10; y++)
            {
                for (var x = 0; x < 10; x++)
                {
                    Console.Write(result[x, y]);
                }
                Console.WriteLine();
            }
            // Simple flood fill algorithm to determine we have in fact got a path
            var stack   = new Stack <ValueTuple <int, int> >();
            var visited = new bool[10, 10];

            stack.Push((0, 0));
            while (stack.TryPop(out var current))
            {
                var(x, y) = current;
                if (x < 0 || x >= 10 || y < 0 || y >= 10)
                {
                    continue;
                }
                if (visited[x, y])
                {
                    continue;
                }
                visited[x, y] = true;
                if (result[x, y] == 1)
                {
                    if (x == 9 && y == 9)
                    {
                        return;
                    }
                    stack.Push((x + 1, y));
                    stack.Push((x - 1, y));
                    stack.Push((x, y + 1));
                    stack.Push((x, y - 1));
                }
            }
            Assert.Fail();
        }
        public void TestPathConstraint()
        {
            var a = new int[, ] {
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 1, 1, 1, 1, 0, 0 },
                { 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0 }
            };

            var seed = Environment.TickCount;
            var r    = new Random(seed);

            Console.WriteLine("Seed {0}", seed);

            var model      = OverlappingModel.Create(a, 3, false, 8);
            var propagator = new TilePropagator(model, new GridTopology(10, 10, false), new TilePropagatorOptions
            {
                BackTrackDepth = -1,
                Constraints    = new[] {
#pragma warning disable CS0618 // Type or member is obsolete
                    new PathConstraint(new HashSet <Tile> {
                        new Tile(1)
                    }, new [] { new Point(0, 0), new Point(9, 9) })
#pragma warning restore CS0618 // Type or member is obsolete
                },
                RandomDouble = r.NextDouble
            });
            var status = propagator.Run();

            Assert.AreEqual(Resolution.Decided, status);
            var result = propagator.ToValueArray <int>().ToArray2d();

            // Write out result for debugging
            for (var y = 0; y < 10; y++)
            {
                for (var x = 0; x < 10; x++)
                {
                    Console.Write(result[x, y]);
                }
                Console.WriteLine();
            }
            // Simple flood fill algorithm to determine we have in fact got a path
            var stack   = new Stack <ValueTuple <int, int> >();
            var visited = new bool[10, 10];

            stack.Push((0, 0));
            while (stack.TryPop(out var current))
            {
                var(x, y) = current;
                if (x < 0 || x >= 10 || y < 0 || y >= 10)
                {
                    continue;
                }
                if (visited[x, y])
                {
                    continue;
                }
                visited[x, y] = true;
                if (result[x, y] == 1)
                {
                    if (x == 9 && y == 9)
                    {
                        return;
                    }
                    stack.Push((x + 1, y));
                    stack.Push((x - 1, y));
                    stack.Push((x, y + 1));
                    stack.Push((x, y - 1));
                }
            }
            Assert.Fail();
        }
        public void TestAcyclicConstraint()
        {
            var a = new int[, ] {
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 1, 1, 1, 1, 0, 0 },
                { 0, 1, 0, 0, 0, 0 },
                { 0, 1, 0, 0, 0, 0 }
            };

            var seed = Environment.TickCount;
            var r    = new Random(seed);

            Console.WriteLine("Seed {0}", seed);

            var model    = OverlappingModel.Create(a, 3, false, 8);
            var topology = new GridTopology(10, 10, false);

            /*
             * var pathSpec = new PathSpec
             * {
             *  Tiles = new HashSet<Tile> { new Tile(1) },
             * };
             */
            var pathSpec = new EdgedPathSpec
            {
                Exits = new Dictionary <Tile, ISet <Direction> > {
                    { new Tile(1), topology.Directions.ToHashSet() }
                },
            };
            var constraint = new AcyclicConstraint
            {
                PathSpec = pathSpec,
            };

            var propagator = new TilePropagator(model, topology, new TilePropagatorOptions
            {
                BackTrackDepth = -1,
                Constraints    = new[] { constraint },
                RandomDouble   = r.NextDouble
            });
            var status = propagator.Run();

            Assert.AreEqual(Resolution.Decided, status);
            var result = propagator.ToValueArray <int>().ToArray2d();

            // Write out result for debugging
            for (var y = 0; y < topology.Height; y++)
            {
                for (var x = 0; x < topology.Width; x++)
                {
                    Console.Write(result[x, y]);
                }
                Console.WriteLine();
            }
            var visited = new bool[topology.Width, topology.Height];

            for (var y = 0; y < topology.Height; y++)
            {
                for (var x = 0; x < topology.Width; x++)
                {
                    if (result[x, y] != 1)
                    {
                        continue;
                    }
                    if (visited[x, y])
                    {
                        continue;
                    }
                    void Visit(int x2, int y2, int dir)
                    {
                        if (x2 < 0 || x2 >= topology.Width || y2 < 0 || y2 >= topology.Height)
                        {
                            return;
                        }
                        if (result[x2, y2] != 1)
                        {
                            return;
                        }
                        if (visited[x2, y2])
                        {
                            Assert.Fail();
                        }
                        visited[x2, y2] = true;
                        if (dir != 0)
                        {
                            Visit(x2 - 1, y2, 2);
                        }
                        if (dir != 2)
                        {
                            Visit(x2 + 1, y2, 0);
                        }
                        if (dir != 1)
                        {
                            Visit(x2, y2 - 1, 3);
                        }
                        if (dir != 3)
                        {
                            Visit(x2, y2 + 1, 1);
                        }
                    }

                    Visit(x, y, -1);
                }
            }
        }
示例#5
0
        public void TestLoopConstraint()
        {
            var a = new int[, ] {
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 0, 0, 0, 1, 0, 0 },
                { 1, 1, 1, 1, 0, 0 },
                { 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0 }
            };

            var seed = Environment.TickCount;
            // TODO: This seed shows that this constraint can fail occasionally
            //seed = -1847040250;
            var r = new Random(seed);

            Console.WriteLine("Seed {0}", seed);

            var model = OverlappingModel.Create(a, 3, false, 8);

            var constraint = new LoopConstraint
            {
                PathSpec = new PathSpec
                {
                    Tiles = new HashSet <Tile> {
                        new Tile(1)
                    },
                }
            };

            var topology   = new GridTopology(10, 10, false);
            var propagator = new TilePropagator(model, topology, new TilePropagatorOptions
            {
                BackTrackDepth = -1,
                Constraints    = new[] { constraint },
                RandomDouble   = r.NextDouble
            });
            var status = propagator.Run();

            Assert.AreEqual(Resolution.Decided, status);
            var result = propagator.ToValueArray <int>().ToArray2d();

            // Write out result for debugging
            for (var y = 0; y < topology.Height; y++)
            {
                for (var x = 0; x < topology.Width; x++)
                {
                    Console.Write(result[x, y]);
                }
                Console.WriteLine();
            }
            // Every cell should have exactly 2 neighbours
            for (var y = 0; y < topology.Height; y++)
            {
                for (var x = 0; x < topology.Width; x++)
                {
                    if (result[x, y] == 1)
                    {
                        var n = 0;
                        if (x > 0)
                        {
                            n += result[x - 1, y];
                        }
                        if (x < topology.Width - 1)
                        {
                            n += result[x + 1, y];
                        }
                        if (y > 0)
                        {
                            n += result[x, y - 1];
                        }
                        if (y < topology.Height - 1)
                        {
                            n += result[x, y + 1];
                        }
                        Assert.AreEqual(2, n, $"At {x},{y}");
                    }
                }
            }
        }