コード例 #1
0
        public void Init(TilePropagator propagator)
        {
            ISet <Tile> actualTiles;
            ISet <Tile> actualEndPointTiles;

            if (TileRotation != null)
            {
                actualTiles         = new HashSet <Tile>(TileRotation.RotateAll(Tiles));
                actualEndPointTiles = EndPointTiles == null ? null : new HashSet <Tile>(TileRotation.RotateAll(EndPointTiles));
            }
            else
            {
                actualTiles         = Tiles;
                actualEndPointTiles = EndPointTiles;
            }

            tileSet         = propagator.CreateTileSet(actualTiles);
            selectedTracker = propagator.CreateSelectedTracker(tileSet);
            endPointTileSet = EndPointTiles != null?propagator.CreateTileSet(actualEndPointTiles) : null;

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

            graph = PathConstraintUtils.CreateGraph(propagator.Topology);

            Check(propagator, true);
        }
コード例 #2
0
        public void Init(TilePropagator propagator)
        {
            tileSet         = propagator.CreateTileSet(Tiles);
            endPointTileSet = EndPointTiles != null?propagator.CreateTileSet(EndPointTiles) : null;

            graph = PathConstraintUtils.CreateGraph(propagator.Topology);
        }
コード例 #3
0
        public void Init(TilePropagator propagator)
        {
            tileset1       = propagator.CreateTileSet(Tiles1);
            tileset2       = propagator.CreateTileSet(Tiles2);
            nearbyTracker1 = new SeparationConstraint.NearbyTracker {
                MinDistance = MinDistance, Topology = propagator.Topology
            };
            nearbyTracker2 = new SeparationConstraint.NearbyTracker {
                MinDistance = MinDistance, Topology = propagator.Topology
            };
            changeTracker1 = propagator.CreateSelectedChangeTracker(tileset1, nearbyTracker1);
            changeTracker2 = propagator.CreateSelectedChangeTracker(tileset2, nearbyTracker2);

            // Review the initial state
            foreach (var index in propagator.Topology.GetIndices())
            {
                if (changeTracker1.GetQuadstate(index).IsYes())
                {
                    nearbyTracker1.VisitNearby(index, false);
                }
                if (changeTracker2.GetQuadstate(index).IsYes())
                {
                    nearbyTracker2.VisitNearby(index, false);
                }
            }

            Check(propagator);
        }
コード例 #4
0
        public void Init(TilePropagator propagator)
        {
            pathTileSet     = propagator.CreateTileSet(Exits.Keys);
            endPointTileSet = EndPointTiles != null?propagator.CreateTileSet(EndPointTiles) : null;

            graph = CreateEdgedGraph(propagator.Topology);

            var tileRotation = TileRotation ?? new TileRotation();

            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.Directions, d, rot));
                        }

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

            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);
        }
コード例 #5
0
        public void TestBannedSelected()
        {
            var a = new int[, ] {
                { 1, 2, 3 },
                { 3, 1, 2 },
                { 2, 3, 1 },
            };
            var model      = AdjacentModel.Create(a, true);
            var topology   = new GridTopology(10, 10, false);
            var propagator = new TilePropagator(model, topology);

            var tile1 = new Tile(1);
            var set1  = propagator.CreateTileSet(new[] { new Tile(1) });
            var set12 = propagator.CreateTileSet(new[] { new Tile(1), new Tile(2) });

            {
                propagator.GetBannedSelected(0, 0, 0, tile1, out var isBanned1, out var isSelected1);
                propagator.GetBannedSelected(0, 0, 0, set1, out var isBanned2, out var isSelected2);
                propagator.GetBannedSelected(0, 0, 0, set12, out var isBanned3, out var isSelected3);

                Assert.AreEqual(false, isBanned1);
                Assert.AreEqual(false, isBanned2);
                Assert.AreEqual(false, isBanned3);
                Assert.AreEqual(false, isSelected1);
                Assert.AreEqual(false, isSelected2);
                Assert.AreEqual(false, isSelected3);
            }

            propagator.Ban(0, 0, 0, new Tile(3));

            {
                propagator.GetBannedSelected(0, 0, 0, tile1, out var isBanned1, out var isSelected1);
                propagator.GetBannedSelected(0, 0, 0, set1, out var isBanned2, out var isSelected2);
                propagator.GetBannedSelected(0, 0, 0, set12, out var isBanned3, out var isSelected3);

                Assert.AreEqual(false, isBanned1);
                Assert.AreEqual(false, isBanned2);
                Assert.AreEqual(false, isBanned3);
                Assert.AreEqual(false, isSelected1);
                Assert.AreEqual(false, isSelected2);
                Assert.AreEqual(true, isSelected3);
            }

            propagator.Ban(0, 0, 0, new Tile(1));

            {
                propagator.GetBannedSelected(0, 0, 0, tile1, out var isBanned1, out var isSelected1);
                propagator.GetBannedSelected(0, 0, 0, set1, out var isBanned2, out var isSelected2);
                propagator.GetBannedSelected(0, 0, 0, set12, out var isBanned3, out var isSelected3);

                Assert.AreEqual(true, isBanned1);
                Assert.AreEqual(true, isBanned2);
                Assert.AreEqual(false, isBanned3);
                Assert.AreEqual(false, isSelected1);
                Assert.AreEqual(false, isSelected2);
                Assert.AreEqual(true, isSelected3);
            }
        }
コード例 #6
0
        public void Init(TilePropagator propagator)
        {
            ISet <Tile> actualEndPointTiles;

            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;
                        }
                    }
                }
                actualEndPointTiles = EndPointTiles == null ? null : new HashSet <Tile>(TileRotation.RotateAll(EndPointTiles));
            }
            else
            {
                actualExits         = Exits;
                actualEndPointTiles = EndPointTiles;
            }

            pathTileSet         = propagator.CreateTileSet(Exits.Keys);
            pathSelectedTracker = propagator.CreateSelectedTracker(pathTileSet);
            endPointTileSet     = EndPointTiles != null?propagator.CreateTileSet(actualEndPointTiles) : null;

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

            graph = CreateEdgedGraph(propagator.Topology);


            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));

            Check(propagator, true);
        }
コード例 #7
0
        public void Init(TilePropagator propagator)
        {
            var tileSet = propagator.CreateTileSet(Tiles);

            var point = Point ?? GetRandomPoint(propagator, tileSet);

            propagator.Select(point.X, point.Y, point.Z, tileSet);
        }
コード例 #8
0
 public void Init(TilePropagator propagator)
 {
     if (propagator.Topology.Directions.Type != Topo.DirectionSetType.Cartesian2d &&
         propagator.Topology.Directions.Type != Topo.DirectionSetType.Cartesian3d)
     {
         // This wouldn't be that hard to fix
         throw new Exception("MaxConsecutiveConstraint only supports cartesian topologies.");
     }
     tileSet = propagator.CreateTileSet(Tiles);
 }
コード例 #9
0
        public void Init(TilePropagator propagator)
        {
            var oddPathTiles = PathSpec.Exits.Where(x => x.Value.Count() % 2 == 1).Select(x => x.Key).ToList();

            oddPathTilesSet = propagator.CreateTileSet(oddPathTiles);
            oddPathTracker  = oddPathTiles.Count > 0 ? propagator.CreateSelectedTracker(oddPathTilesSet) : null;
            pathView        = (EdgedPathView)PathSpec.MakeView(propagator);
            this.propagator = propagator;
            this.topology   = propagator.Topology;
        }
コード例 #10
0
        public void Init(TilePropagator propagator)
        {
            var topology = propagator.Topology as GridTopology;

            if (topology == null ||
                topology.Directions.Type != Topo.DirectionSetType.Cartesian2d &&
                topology.Directions.Type != Topo.DirectionSetType.Cartesian3d)
            {
                // This wouldn't be that hard to fix
                throw new Exception("MaxConsecutiveConstraint only supports cartesian topologies.");
            }
            tileSet         = propagator.CreateTileSet(Tiles);
            selectedTracker = propagator.CreateSelectedTracker(tileSet);
        }
コード例 #11
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);
        }
コード例 #12
0
        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);
                            }
                        }
                    }
                }
            }
        }
コード例 #13
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;
            }
        }
コード例 #14
0
        public void Init(TilePropagator propagator)
        {
            tileSet = propagator.CreateTileSet(Tiles);

            countTracker = new CountTracker(propagator.Topology);

            selectedChangeTracker = propagator.CreateSelectedChangeTracker(tileSet, countTracker);

            if (Eager)
            {
                // Naive implementation

                /*
                 * // Pick Count random indices
                 * var topology = propagator.Topology;
                 * var pickedIndices = new List<int>();
                 * var remainingIndices = new List<int>(topology.Indicies);
                 * for (var c = 0; c < Count; c++)
                 * {
                 *  var pickedIndexIndex = (int)(propagator.RandomDouble() * remainingIndices.Count);
                 *  pickedIndices.Add(remainingIndices[pickedIndexIndex]);
                 *  remainingIndices[pickedIndexIndex] = remainingIndices[remainingIndices.Count - 1];
                 *  remainingIndices.RemoveAt(remainingIndices.Count - 1);
                 * }
                 * // Ban or select tiles to ensure an appropriate count
                 * if(Comparison == CountComparison.AtMost || Comparison == CountComparison.Exactly)
                 * {
                 *  foreach (var i in remainingIndices)
                 *  {
                 *      topology.GetCoord(i, out var x, out var y, out var z);
                 *      propagator.Ban(x, y, z, tileSet);
                 *  }
                 * }
                 * if (Comparison == CountComparison.AtLeast || Comparison == CountComparison.Exactly)
                 * {
                 *  foreach (var i in pickedIndices)
                 *  {
                 *      topology.GetCoord(i, out var x, out var y, out var z);
                 *      propagator.Select(x, y, z, tileSet);
                 *  }
                 * }
                 */

                var topology         = propagator.Topology;
                var width            = topology.Width;
                var height           = topology.Height;
                var depth            = topology.Depth;
                var pickedIndices    = new List <int>();
                var remainingIndices = new List <int>(topology.GetIndices());

                while (true)
                {
                    var noCount   = 0;
                    var yesCount  = 0;
                    var maybeList = new List <int>();
                    for (var z = 0; z < depth; z++)
                    {
                        for (var y = 0; y < height; y++)
                        {
                            for (var x = 0; x < width; x++)
                            {
                                var index = topology.GetIndex(x, y, z);
                                if (topology.ContainsIndex(index))
                                {
                                    var selected = selectedChangeTracker.GetQuadstate(index);
                                    if (selected.IsNo())
                                    {
                                        noCount++;
                                    }
                                    if (selected.IsMaybe())
                                    {
                                        maybeList.Add(index);
                                    }
                                    if (selected.IsYes())
                                    {
                                        yesCount++;
                                    }
                                }
                            }
                        }
                    }
                    var maybeCount = maybeList.Count;

                    if (Comparison == CountComparison.AtMost)
                    {
                        if (yesCount > Count)
                        {
                            // Already got too many, just fail
                            propagator.SetContradiction();
                            return;
                        }
                        if (yesCount == Count)
                        {
                            // We've reached the limit, ban any more and exit
                            Check(propagator);
                            return;
                        }
                        var pickedIndex = maybeList[(int)(propagator.RandomDouble() * maybeList.Count)];
                        topology.GetCoord(pickedIndex, out var x, out var y, out var z);
                        propagator.Select(x, y, z, tileSet);
                    }
                    else if (Comparison == CountComparison.AtLeast || Comparison == CountComparison.Exactly)
                    {
                        if (yesCount + maybeCount < Count)
                        {
                            // Already got too few, just fail
                            propagator.SetContradiction();
                            return;
                        }
                        if (yesCount + maybeCount == Count)
                        {
                            // We've reached the limit, ban any more and exit
                            Check(propagator);
                            return;
                        }
                        var pickedIndex = maybeList[(int)(propagator.RandomDouble() * maybeList.Count)];
                        topology.GetCoord(pickedIndex, out var x, out var y, out var z);
                        propagator.Ban(x, y, z, tileSet);
                    }
                }
            }
        }
コード例 #15
0
        public EdgedPathView(EdgedPathSpec spec, TilePropagator propagator)
        {
            if (spec.TileRotation != null)
            {
                exits = new Dictionary <Tile, ISet <Direction> >();
                foreach (var kv in spec.Exits)
                {
                    foreach (var rot in spec.TileRotation.RotationGroup)
                    {
                        if (spec.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));
                            exits[rtile] = rexits;
                        }
                    }
                }
                endPointTiles = spec.RelevantTiles == null ? null : new HashSet <Tile>(spec.TileRotation.RotateAll(spec.RelevantTiles));
            }
            else
            {
                exits         = spec.Exits;
                endPointTiles = spec.RelevantTiles;
            }

            pathTileSet         = propagator.CreateTileSet(exits.Keys);
            pathSelectedTracker = propagator.CreateSelectedTracker(pathTileSet);

            Graph           = CreateEdgedGraph(propagator.Topology);
            this.propagator = propagator;
            this.topology   = propagator.Topology;

            var nodesPerIndex = GetNodesPerIndex();

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

            tileSetByExit = exits
                            .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 = tileSetByExit
                            .ToDictionary(kv => kv.Key, kv => propagator.CreateSelectedTracker(kv.Value));

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

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

                endPointSelectedTracker = endPointTiles != null?propagator.CreateSelectedTracker(endPointTileSet) : null;
            }
            else
            {
                CouldBeRelevant = CouldBePath;
                MustBeRelevant  = MustBePath;
                endPointTileSet = pathTileSet;
            }
        }
コード例 #16
0
 public void Init(TilePropagator propagator)
 {
     tileSet = propagator.CreateTileSet(Tiles);
     graph   = PathConstraintUtils.CreateGraph(propagator.Topology);
 }