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

            graph = PathConstraintUtils.CreateGraph(propagator.Topology);
        }
コード例 #2
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);
        }
コード例 #3
0
 public SelectedTracker(TilePropagator tilePropagator, WavePropagator wavePropagator, TileModelMapping tileModelMapping, TilePropagatorTileSet tileSet)
 {
     this.tilePropagator   = tilePropagator;
     this.wavePropagator   = wavePropagator;
     this.tileModelMapping = tileModelMapping;
     this.tileSet          = tileSet;
     patternCounts         = new int[tilePropagator.Topology.IndexCount];
 }
コード例 #4
0
 internal SelectedChangeTracker(TilePropagator tilePropagator, WavePropagator wavePropagator, TileModelMapping tileModelMapping, TilePropagatorTileSet tileSet, IQuadstateChanged onChange)
 {
     this.tilePropagator   = tilePropagator;
     this.wavePropagator   = wavePropagator;
     this.tileModelMapping = tileModelMapping;
     this.tileSet          = tileSet;
     this.onChange         = onChange;
     patternCounts         = new int[tilePropagator.Topology.IndexCount];
     values = new Quadstate[tilePropagator.Topology.IndexCount];
 }
コード例 #5
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);
 }
コード例 #6
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;
        }
コード例 #7
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);
        }
コード例 #8
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);
        }
コード例 #9
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);
        }
コード例 #10
0
        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]);
        }
コード例 #11
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;
            }
        }
コード例 #12
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);
        }
コード例 #13
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);
                    }
                }
            }
        }
コード例 #14
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;
            }
        }
コード例 #15
0
 public void Init(TilePropagator propagator)
 {
     tileSet = propagator.CreateTileSet(Tiles);
     graph   = PathConstraintUtils.CreateGraph(propagator.Topology);
 }