Beispiel #1
0
        public void MirrorSetup()
        {
            var trb = new TileRotationBuilder(4, true, TileRotationTreatment.Missing);

            var tile1 = new Tile(1);
            var tile2 = new Tile(2);
            var tile3 = new Tile(3);
            var tile4 = new Tile(4);
            var tile5 = new Tile(5);

            var tiles = new[] { tile1, tile2, tile3, tile4 };

            var reflectX = new Rotation(0, true);

            trb.Add(tile1, reflectX, tile2);
            trb.Add(tile3, reflectX, tile3);
            trb.Add(tile5, reflectX, tile5);

            var model = new AdjacentModel(DirectionSet.Cartesian2d);

            model.AddAdjacency(tiles, tiles, Direction.XPlus);
            model.AddAdjacency(new[] { tile5 }, tiles, Direction.XPlus);
            model.AddAdjacency(new[] { tile5 }, tiles, Direction.XMinus);
            model.AddAdjacency(tiles, tiles, Direction.YPlus);


            model.SetUniformFrequency();
            model.SetFrequency(tile5, 0.0);

            var tr = trb.Build();

            var constraints = new[] { new MirrorXConstraint {
                                          TileRotation = tr
                                      } };


            // NB: It's important that width is an odd number
            var topology = new GridTopology(31, 31, false);

            var options = new TilePropagatorOptions
            {
                Constraints = constraints,
            };

            propagatorMirror = new TilePropagator(model, topology, options);
        }
Beispiel #2
0
        public void Export(TileModel model, TilePropagator tilePropagator, string filename, DeBroglieConfig config, ExportOptions exportOptions)
        {
            var tiledExportOptions = exportOptions as TiledExportOptions;

            if (tiledExportOptions == null)
            {
                throw new System.Exception($"Cannot export from {exportOptions.TypeDescription} to .tmx");
            }

            var map         = tiledExportOptions.Template;
            var srcFilename = tiledExportOptions.SrcFileName;

            var layerArray = tilePropagator.ToArray();

            map.Layers = new BaseLayer[layerArray.Topology.Depth];
            for (var z = 0; z < layerArray.Topology.Depth; z++)
            {
                map.Layers[z] = TiledUtil.MakeTileLayer(map, layerArray, z);
            }
            map.Width  = map.Layers[0].Width;
            map.Height = map.Layers[0].Height;
            TiledUtil.Save(filename, map);

            // Check for any external files that may also need copying
            foreach (var tileset in map.Tilesets)
            {
                if (tileset is ExternalTileset e)
                {
                    var srcPath  = Path.Combine(Path.GetDirectoryName(srcFilename), e.source);
                    var destPath = Path.Combine(Path.GetDirectoryName(filename), e.source);
                    if (File.Exists(srcPath) && !File.Exists(destPath))
                    {
                        File.Copy(srcPath, destPath);
                    }
                }
                if (tileset.ImagePath != null)
                {
                    var srcImagePath  = Path.Combine(Path.GetDirectoryName(srcFilename), tileset.ImagePath);
                    var destImagePath = Path.Combine(Path.GetDirectoryName(filename), tileset.ImagePath);
                    if (File.Exists(srcImagePath) && !File.Exists(destImagePath))
                    {
                        File.Copy(srcImagePath, destImagePath);
                    }
                }
            }
        }
        public void Check(TilePropagator propagator)
        {
            if (nearbyTracker.NewlyVisited.Count == 0)
            {
                return;
            }

            var newlyVisited = nearbyTracker.NewlyVisited;

            nearbyTracker.NewlyVisited = new HashSet <int>();

            foreach (var index in newlyVisited)
            {
                propagator.Topology.GetCoord(index, out var x, out var y, out var z);
                propagator.Ban(x, y, z, tileset);
            }
        }
Beispiel #4
0
        public static void Export(TileModel model, TilePropagator tilePropagator, string filename, DeBroglieConfig config, ExportOptions exportOptions)
        {
            var exporter = GetExporter(filename);

            // Handle conversions
            if (exporter is BitmapExporter && exportOptions is TiledExportOptions)
            {
                if (tilePropagator.Topology.Directions.Type != Topo.DirectionsType.Cartesian2d)
                {
                    throw new NotSupportedException("Converting from Tiled format to bitmaps only supported for square grids.");
                }

                exportOptions = ConvertToBitmaps(exportOptions as TiledExportOptions);
            }

            exporter.Export(model, tilePropagator, filename, config, exportOptions);
        }
Beispiel #5
0
        public void TestSeparationConstraint()
        {
            var model = new AdjacentModel(DirectionSet.Cartesian2d);
            var tile1 = new Tile(1);
            var tile2 = new Tile(2);
            var tiles = new[] { tile1, tile2 };

            model.AddAdjacency(tiles, tiles, Direction.XPlus);
            model.AddAdjacency(tiles, tiles, Direction.YPlus);
            model.SetUniformFrequency();

            var separationConstraint = new SeparationConstraint
            {
                Tiles = new[] { tile1 }.ToHashSet(),
                MinDistance = 3,
            };

            var countConstraint = new CountConstraint
            {
                Tiles = new[] { tile1 }.ToHashSet(),
                Count      = 2,
                Comparison = CountComparison.Exactly,
            };

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

            var options = new TilePropagatorOptions
            {
                Constraints   = new ITileConstraint[] { separationConstraint, countConstraint },
                BacktrackType = BacktrackType.Backtrack,
            };
            var propagator = new TilePropagator(model, topology, options);

            propagator.Run();

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

            var r = propagator.ToArray();

            // Only possible solution given the constraints
            Assert.AreEqual(tile1, r.Get(0));
            Assert.AreEqual(tile2, r.Get(1));
            Assert.AreEqual(tile2, r.Get(2));
            Assert.AreEqual(tile1, r.Get(3));
        }
Beispiel #6
0
        public void TestParityConstraint()
        {
            var w        = 10;
            var h        = 10;
            var topology = new GridTopology(10, 10, false);

            var pathModel = new PathModel(forks: false);

            var constraint = new ParityConstraint
            {
                PathSpec = new EdgedPathSpec {
                    Exits = pathModel.Exits
                },
            };

            var options = new TilePropagatorOptions
            {
                BackTrackDepth = -1,
                Constraints    = new[] { constraint },
            };

            var propagator = new TilePropagator(pathModel.Model, topology, options);

            for (var x = 0; x < w; x++)
            {
                for (var y = 0; y < h; y++)
                {
                    void Select(Tile t) => propagator.Select(x, y, 0, t);

                    if (x == 0 && y == 1)
                    {
                        Select(pathModel.Straight2);
                        continue;
                    }
                    if (x == 0 || y == 0 || x == w - 1 || y == h - 1)
                    {
                        Select(pathModel.Empty);
                    }
                }
            }

            propagator.Step();

            Assert.AreEqual(Resolution.Contradiction, propagator.Status);
        }
Beispiel #7
0
        public void FreeSetup()
        {
            var tileCount = 10;
            var topology  = new GridTopology(10, 10, 10, false);

            var model = new AdjacentModel(DirectionSet.Cartesian3d);

            var tiles = Enumerable.Range(0, tileCount).Select(x => new Tile(x)).ToList();;

            model.AddAdjacency(tiles, tiles, Direction.XPlus);
            model.AddAdjacency(tiles, tiles, Direction.YPlus);
            model.AddAdjacency(tiles, tiles, Direction.ZPlus);

            model.SetUniformFrequency();

            propagator1 = new TilePropagator(model, topology, new TilePropagatorOptions {
            });
        }
        public void Init(TilePropagator propagator)
        {
            pathTileSet         = propagator.CreateTileSet(Exits.Keys);
            pathSelectedTracker = propagator.CreateSelectedTracker(pathTileSet);
            endPointTileSet     = EndPointTiles != null?propagator.CreateTileSet(EndPointTiles) : null;

            endPointSelectedTracker = EndPointTiles != null?propagator.CreateSelectedTracker(endPointTileSet) : null;

            graph = CreateEdgedGraph(propagator.Topology);

            if (TileRotation != null)
            {
                actualExits = new Dictionary <Tile, ISet <Direction> >();
                foreach (var kv in Exits)
                {
                    foreach (var rot in TileRotation.RotationGroup)
                    {
                        if (TileRotation.Rotate(kv.Key, rot, out var rtile))
                        {
                            Direction Rotate(Direction d)
                            {
                                return(TopoArrayUtils.RotateDirection(propagator.Topology.AsGridTopology().Directions, d, rot));
                            }

                            var rexits = new HashSet <Direction>(kv.Value.Select(Rotate));
                            actualExits[rtile] = rexits;
                        }
                    }
                }
            }
            else
            {
                actualExits = Exits;
            }

            tilesByExit = actualExits
                          .SelectMany(kv => kv.Value.Select(e => Tuple.Create(kv.Key, e)))
                          .GroupBy(x => x.Item2, x => x.Item1)
                          .ToDictionary(g => g.Key, propagator.CreateTileSet);

            trackerByExit = tilesByExit
                            .ToDictionary(kv => kv.Key, kv => propagator.CreateSelectedTracker(kv.Value));
        }
 internal IPickHeuristic GetHeuristic(
     IRandomPicker randomPicker,
     Func <double> randomDouble,
     TilePropagator propagator,
     TileModelMapping tileModelMapping,
     IPickHeuristic fallbackHeuristic)
 {
     pathView        = PathSpec.MakeView(propagator);
     pathViewIsFresh = true;
     if (pathView is EdgedPathView epv)
     {
         return(new FollowPathHeuristic(
                    randomPicker, randomDouble, propagator, tileModelMapping, fallbackHeuristic, epv));
     }
     else
     {
         throw new NotImplementedException();
     }
 }
Beispiel #10
0
        public void Init(TilePropagator propagator)
        {
            tileset       = propagator.CreateTileSet(Tiles);
            nearbyTracker = new NearbyTracker {
                MinDistance = MinDistance, Topology = propagator.Topology
            };
            changeTracker = propagator.CreateSelectedChangeTracker(tileset, nearbyTracker);

            // Review the initial state
            foreach (var index in propagator.Topology.GetIndices())
            {
                if (changeTracker.GetTristate(index).IsYes())
                {
                    nearbyTracker.VisitNearby(index, false);
                }
            }

            Check(propagator);
        }
Beispiel #11
0
        public void TestDoubleCountConstraint()
        {
            var model = new AdjacentModel(DirectionSet.Cartesian2d);
            var tile1 = new Tile(1);
            var tile2 = new Tile(2);
            var tile3 = new Tile(3);
            var tiles = new[] { tile1, tile2, tile3 };

            model.AddAdjacency(new[] { tile2 }, new[] { tile1 }, Direction.XPlus);
            model.AddAdjacency(new[] { tile1 }, new[] { tile3 }, Direction.XPlus);
            model.AddAdjacency(new[] { tile3 }, new[] { tile3 }, Direction.XPlus);
            model.AddAdjacency(new[] { tile3 }, new[] { tile2 }, Direction.XPlus);
            model.AddAdjacency(tiles, tiles, Direction.YPlus);
            model.SetUniformFrequency();

            var topology = new GridTopology(10, 10, false);

            var count = 10;

            var options = new TilePropagatorOptions
            {
                Constraints = new[]
                {
                    new CountConstraint
                    {
                        Tiles = new[] { tile1, tile2 }.ToHashSet(),
                Count      = count,
                Comparison = CountComparison.Exactly,
                Eager      = true,
                    }
                }
            };
            var propagator = new TilePropagator(model, topology, options);

            propagator.Run();

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

            var actualCount = propagator.ToValueArray <int>().ToArray2d().OfType <int>().Count(x => x == 1 || x == 2);

            Assert.AreEqual(count, actualCount);
        }
        public Point GetRandomPoint(TilePropagator propagator, TilePropagatorTileSet tileSet)
        {
            var topology = propagator.Topology;

            var points = new List <Point>();

            for (var z = 0; z < topology.Depth; z++)
            {
                for (var y = 0; y < topology.Height; y++)
                {
                    for (var x = 0; x < topology.Width; x++)
                    {
                        if (topology.Mask != null)
                        {
                            var index = topology.GetIndex(x, y, z);
                            if (!topology.Mask[index])
                            {
                                continue;
                            }
                        }

                        propagator.GetBannedSelected(x, y, z, tileSet, out var isBanned, out var _);
                        if (isBanned)
                        {
                            continue;
                        }

                        points.Add(new Point(x, y, z));
                    }
                }
            }

            // Choose a random point to select
            if (points.Count == 0)
            {
                throw new System.Exception($"No legal placement of {tileSet}");
            }

            var i = (int)(propagator.RandomDouble() * points.Count);

            return(points[i]);
        }
Beispiel #13
0
        public void TestDirtyIndexPicker()
        {
            var t1    = new Tile(1);
            var t2    = new Tile(2);
            var t3    = new Tile(3);
            var model = new AdjacentModel(DirectionSet.Cartesian2d);

            model.AddAdjacency(t1, t1, Direction.XPlus);
            model.AddAdjacency(t1, t2, Direction.XPlus);
            model.AddAdjacency(t2, t2, Direction.XPlus);
            model.AddAdjacency(t2, t3, Direction.XPlus);
            model.AddAdjacency(t3, t3, Direction.XPlus);
            model.AddAdjacency(t3, t2, Direction.XPlus);
            model.AddAdjacency(t2, t1, Direction.XPlus);

            model.SetUniformFrequency();

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

            var options = new TilePropagatorOptions
            {
                IndexPickerType = IndexPickerType.Dirty,
                TilePickerType  = TilePickerType.Ordered,
                CleanTiles      = TopoArray.FromConstant(t1, topology),
            };

            var propagator = new TilePropagator(model, topology, options);

            propagator.Select(3, 0, 0, t3);

            propagator.Run();

            var a = propagator.ToValueArray <int?>();

            Assert.AreEqual(null, a.Get(0, 0));
            Assert.AreEqual(null, a.Get(1, 0));
            Assert.AreEqual(2, a.Get(2, 0));
            Assert.AreEqual(3, a.Get(3, 0));
            Assert.AreEqual(2, a.Get(4, 0));
            Assert.AreEqual(null, a.Get(5, 0));
        }
Beispiel #14
0
        public PathView(PathSpec spec, TilePropagator propagator)
        {
            if (spec.TileRotation != null)
            {
                tiles         = new HashSet <Tile>(spec.TileRotation.RotateAll(spec.Tiles));
                endPointTiles = spec.RelevantTiles == null ? null : new HashSet <Tile>(spec.TileRotation.RotateAll(spec.RelevantTiles));
            }
            else
            {
                tiles         = spec.Tiles;
                endPointTiles = spec.RelevantTiles;
            }

            tileSet         = propagator.CreateTileSet(tiles);
            selectedTracker = propagator.CreateSelectedTracker(tileSet);

            Graph           = PathConstraintUtils.CreateGraph(propagator.Topology);
            this.propagator = propagator;

            CouldBePath = new bool[propagator.Topology.IndexCount];
            MustBePath  = new bool[propagator.Topology.IndexCount];

            hasEndPoints = spec.RelevantCells != null || spec.RelevantTiles != null;

            if (hasEndPoints)
            {
                CouldBeRelevant = new bool[propagator.Topology.IndexCount];
                MustBeRelevant  = new bool[propagator.Topology.IndexCount];
                endPointIndices = spec.RelevantCells == null ? null :
                                  spec.RelevantCells.Select(p => propagator.Topology.GetIndex(p.X, p.Y, p.Z)).ToList();
                endPointTileSet = spec.RelevantTiles != null?propagator.CreateTileSet(endPointTiles) : null;

                endPointSelectedTracker = spec.RelevantTiles != null?propagator.CreateSelectedTracker(endPointTileSet) : null;
            }
            else
            {
                CouldBeRelevant = CouldBePath;
                MustBeRelevant  = MustBePath;
                endPointTileSet = tileSet;
            }
        }
        public void Init(TilePropagator propagator)
        {
            var tiles = propagator.CreateTileSet(Tiles);

            var width  = propagator.Topology.Width;
            var height = propagator.Topology.Height;
            var depth  = propagator.Topology.Depth;

            for (var x = 0; x < width; x++)
            {
                var xmin = x == 0;
                var xmax = x == width - 1;

                for (var y = 0; y < height; y++)
                {
                    var ymin = y == 0;
                    var ymax = y == height - 1;

                    for (var z = 0; z < depth; z++)
                    {
                        var zmin = z == 0;
                        var zmax = z == depth - 1;

                        var match = (Match(Sides, xmin, xmax, ymin, ymax, zmin, zmax) &&
                                     !Match(ExcludeSides, xmin, xmax, ymin, ymax, zmin, zmax)) != InvertArea;

                        if (match)
                        {
                            if (Ban)
                            {
                                propagator.Ban(x, y, z, tiles);
                            }
                            else
                            {
                                propagator.Select(x, y, z, tiles);
                            }
                        }
                    }
                }
            }
        }
Beispiel #16
0
        public void Check(TilePropagator propagator)
        {
            var topology = propagator.Topology;

            foreach (var i in topology.Indicies)
            {
                topology.GetCoord(i, out var x, out var y, out var z);
                var x2 = topology.Width - 1 - x;

                foreach (var tile in propagator.TileModel.Tiles)
                {
                    if (TileRotation.Rotate(tile, reflectX, out var tile2))
                    {
                        if (propagator.IsBanned(x, y, z, tile) && !propagator.IsBanned(x2, y, z, tile2))
                        {
                            propagator.Ban(x2, y, z, tile2);
                        }
                    }
                }
            }
        }
Beispiel #17
0
        public void PathSetup()
        {
            var tileCount = 10;
            var topology  = new GridTopology(20, 20, false);

            var model = new AdjacentModel(DirectionSet.Cartesian2d);

            var tiles = Enumerable.Range(0, tileCount).Select(x => new Tile(x)).ToList();;

            model.AddAdjacency(tiles, tiles, Direction.XPlus);
            model.AddAdjacency(tiles, tiles, Direction.YPlus);

            model.SetUniformFrequency();
            var pathConstraint = new PathConstraint(tiles.Skip(1).ToHashSet());

            propagator5 = new TilePropagator(model, topology, new TilePropagatorOptions
            {
                BackTrackDepth = -1,
                Constraints    = new[] { pathConstraint },
            });
        }
Beispiel #18
0
        public void ChessSetup()
        {
            var topology = new GridTopology(10, 10, 10, false);

            var model = new AdjacentModel(DirectionSet.Cartesian3d);

            var t1 = new Tile(1);
            var t2 = new Tile(2);

            model.AddAdjacency(t1, t2, Direction.XPlus);
            model.AddAdjacency(t2, t1, Direction.XPlus);
            model.AddAdjacency(t1, t2, Direction.YPlus);
            model.AddAdjacency(t2, t1, Direction.YPlus);
            model.AddAdjacency(t1, t2, Direction.ZPlus);
            model.AddAdjacency(t2, t1, Direction.ZPlus);

            model.SetUniformFrequency();

            propagator2 = new TilePropagator(model, topology, new TilePropagatorOptions {
            });
        }
Beispiel #19
0
        private Resolution Run(TilePropagator propagator)
        {
            var next = DateTime.Now + TimeSpan.FromMinutes(1);

            while (true)
            {
                for (var i = 0; i < 100; i++)
                {
                    var status = propagator.Step();
                    if (status != Resolution.Undecided)
                    {
                        return(status);
                    }
                }
                if (DateTime.Now > next)
                {
                    System.Console.WriteLine($"Progress {propagator.GetProgress():p2}");
                    next = DateTime.Now + TimeSpan.FromMinutes(1);
                }
            }
        }
        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 GridTopology(2, 1, false);

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

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

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

            var constraint = new ConnectedConstraint
            {
                PathSpec = new EdgedPathSpec
                {
                    Exits = 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, new TilePropagatorOptions
            {
                RandomDouble = r.NextDouble,
                Constraints  = new[] { constraint }
            });

            propagator.Run();

            Assert.AreEqual(Resolution.Contradiction, propagator.Status);
        }
Beispiel #21
0
        public void ProcessItem()
        {
            if (config.Dest == null)
            {
                throw new ConfigurationException("Dest attribute must be set");
            }

            var directory = config.BaseDirectory;

            Dest     = Path.Combine(directory, config.Dest);
            Contdest = Path.ChangeExtension(Dest, ".contradiction" + Path.GetExtension(Dest));

            // TODO: Neat way to do this without mutability?
            factory.TilesByName = new Dictionary <string, Tile>();

            if (config.SrcType == SrcType.Sample)
            {
                SampleSet           = LoadSample();
                factory.TilesByName = SampleSet.TilesByName ?? factory.TilesByName;
            }
            else
            {
                SampleSet = LoadFileSet();
            }
            var directions = SampleSet.Directions;

            Topology = factory.GetOutputTopology(directions);

            TileRotation = factory.GetTileRotation(config.RotationTreatment, Topology);

            Model = factory.GetModel(directions, SampleSet, TileRotation);

            Constraints = factory.GetConstraints(directions, TileRotation);

            System.Console.WriteLine($"Processing {Dest}");
            Propagator = new TilePropagator(Model, Topology, config.Backtrack, constraints: Constraints.ToArray());

            //NewMethod(dest, contdest, sampleSet, model, propagator);
        }
Beispiel #22
0
        public void PathSetup()
        {
            var tileCount = 10;
            var topology  = new GridTopology(20, 20, false);

            var model = new AdjacentModel(DirectionSet.Cartesian2d);

            var tiles = Enumerable.Range(0, tileCount).Select(x => new Tile(x)).ToList();;

            model.AddAdjacency(tiles, tiles, Direction.XPlus);
            model.AddAdjacency(tiles, tiles, Direction.YPlus);

            model.SetUniformFrequency();
#pragma warning disable CS0618 // Type or member is obsolete
            var pathConstraint = new PathConstraint(tiles.Skip(1).ToHashSet());
#pragma warning restore CS0618 // Type or member is obsolete

            propagatorPath = new TilePropagator(model, topology, new TilePropagatorOptions
            {
                BacktrackType = BacktrackType.Backtrack,
                Constraints   = new[] { pathConstraint },
            });
        }
Beispiel #23
0
        public static void WriteSteps(TilePropagator propagator)
        {
            Write(propagator);
            System.Console.WriteLine();

            while (true)
            {
                var prevBacktrackCount = propagator.BacktrackCount;
                var status             = propagator.Step();
                Write(propagator);
                if (propagator.BacktrackCount != prevBacktrackCount)
                {
                    System.Console.WriteLine("Backtracked!");
                }
                System.Console.WriteLine();

                if (status != Resolution.Undecided)
                {
                    System.Console.WriteLine(status);
                    break;
                }
            }
        }
 public void Init(TilePropagator propagator)
 {
     if (PathSpec is PathSpec pathSpec)
     {
         // Convert PathSpec to EdgedPathSpec
         // As we have a bug with PathSpec ignoring paths of length 2.
         // (probably should use bridge edges instead of articulation points)
         ISet <Direction> allDirections = new HashSet <Direction>(Enumerable.Range(0, propagator.Topology.DirectionsCount).Cast <Direction>());
         var edgedPathSpec = new EdgedPathSpec
         {
             Exits         = pathSpec.Tiles.ToDictionary(x => x, _ => allDirections),
             RelevantCells = pathSpec.RelevantCells,
             RelevantTiles = pathSpec.RelevantTiles,
             TileRotation  = pathSpec.TileRotation,
         };
         pathView = edgedPathSpec.MakeView(propagator);
     }
     else
     {
         pathView = PathSpec.MakeView(propagator);
     }
     pathView.Init();
 }
        public void TestToTopArray()
        {
            var a = new int[, ] {
                { 1, 0 },
                { 0, 1 },
            };
            var model = OverlappingModel.Create(a, 2, false, 8);

            var propagator = new TilePropagator(model, new GridTopology(4, 4, false));

            propagator.Select(0, 0, 0, new Tile(1));
            var status = propagator.Run();

            Assert.AreEqual(Resolution.Decided, status);

            var result = propagator.ToValueArray <int>().ToArray2d();

            Assert.AreEqual(4, result.GetLength(0));
            Assert.AreEqual(4, result.GetLength(1));

            Assert.AreEqual(1, result[0, 0]);
            Assert.AreEqual(1, result[3, 3]);
        }
        public void Check(TilePropagator propagator)
        {
            pathView.Update();

            var info           = PathConstraintUtils.GetArticulationPoints(pathView.Graph, pathView.CouldBePath, pathView.MustBeRelevant);
            var isArticulation = info.IsArticulation;

            if (info.ComponentCount > 1)
            {
                propagator.SetContradiction();
                return;
            }

            // All articulation points must be paths,
            // So ban any other possibilities
            for (var i = 0; i < pathView.Graph.NodeCount; i++)
            {
                if (isArticulation[i] && !pathView.MustBePath[i])
                {
                    pathView.SelectPath(i);
                }
            }

            // Any path tiles / EndPointTiles not in the connected component aren't safe to add.
            // Disabled for now, unclear exactly when it is needed
            if (info.ComponentCount > 0)
            {
                var component = info.Component;
                for (int i = 0; i < pathView.Graph.NodeCount; i++)
                {
                    if (component[i] == null && pathView.CouldBeRelevant[i])
                    {
                        pathView.BanRelevant(i);
                    }
                }
            }
        }
        public void TestBorderConstraint()
        {
            var a = new int[, ] {
                { 1, 0, 0 },
                { 0, 1, 1 },
                { 0, 1, 1 },
            };

            var model      = AdjacentModel.Create(a, true);
            var propagator = new TilePropagator(model, new GridTopology(10, 10, false), true, constraints: new[] {
                new BorderConstraint {
                    Tiles = new [] { new Tile(0) },
                }
            });
            var status = propagator.Run();

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

            Assert.AreEqual(0, result[0, 0]);
            Assert.AreEqual(0, result[9, 0]);
            Assert.AreEqual(0, result[0, 9]);
            Assert.AreEqual(0, result[9, 9]);
        }
        public void Check(TilePropagator propagator)
        {
            var topology = propagator.Topology;

            foreach (var i in changeTracker.GetChangedIndices())
            {
                if (TryMapIndex(propagator, i, out var i2))
                {
                    topology.GetCoord(i, out var x, out var y, out var z);
                    topology.GetCoord(i2, out var x2, out var y2, out var z2);

                    foreach (var tile in propagator.TileModel.Tiles)
                    {
                        if (TryMapTile(tile, out var tile2))
                        {
                            if (propagator.IsBanned(x, y, z, tile) && !propagator.IsBanned(x2, y, z, tile2))
                            {
                                propagator.Ban(x2, y, z, tile2);
                            }
                        }
                    }
                }
            }
        }
Beispiel #29
0
        public void TestUnassignableEager()
        {
            var model = new AdjacentModel(DirectionSet.Cartesian2d);
            var tile1 = new Tile(1);
            var tile2 = new Tile(2);
            var tiles = new[] { tile1, tile2 };

            model.AddAdjacency(tiles, tiles, Direction.XPlus);
            model.AddAdjacency(tiles, tiles, Direction.YPlus);
            model.SetUniformFrequency();

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

            var count = 3;

            var options = new TilePropagatorOptions
            {
                Constraints = new[]
                {
                    new CountConstraint
                    {
                        Tiles = new[] { tile1, }.ToHashSet(),
                Count      = count,
                Comparison = CountComparison.Exactly,
                Eager      = true,
                    }
                }
            };
            var propagator = new TilePropagator(model, topology, options);

            propagator.Select(1, 0, 0, tile2);

            propagator.Run();

            Assert.AreEqual(Resolution.Contradiction, propagator.Status);
        }
Beispiel #30
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 Topology(2, 1, false);

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

            var edgedPathConstraint = new EdgedPathConstraint(
                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();
        }