Example #1
0
        /// <summary>
        /// Declares that the tiles in dest can be placed adjacent to the tiles in src, in the direction specified by (x, y, z).
        /// Then it adds similar declarations for other rotations and reflections, as specified by rotations.
        /// </summary>
        public void AddAdjacency(IList <Tile> src, IList <Tile> dest, int x, int y, int z, int rotationalSymmetry, bool reflectionalSymmetry, TileRotation rotations = null)
        {
            rotations = rotations ?? new TileRotation();
            int totalRotationalSymmetry;

            if (directions.Type == DirectionsType.Hexagonal2d)
            {
                totalRotationalSymmetry = 6;
            }
            else
            {
                totalRotationalSymmetry = 4;
            }

            int reflections = reflectionalSymmetry ? 2 : 1;

            for (var r = 0; r < reflections; r++)
            {
                var reflectX = r > 0 ? true : false;
                for (var rotateCw = 0; rotateCw < totalRotationalSymmetry; rotateCw += (totalRotationalSymmetry / rotationalSymmetry))
                {
                    int x2, y2;
                    if (directions.Type == DirectionsType.Hexagonal2d)
                    {
                        (x2, y2) = TopoArrayUtils.HexRotateVector(x, y, rotateCw, reflectX);
                    }
                    else
                    {
                        (x2, y2) = TopoArrayUtils.RotateVector(x, y, rotateCw, reflectX);
                    }

                    AddAdjacency(
                        rotations.Rotate(src, rotateCw, reflectX).ToList(),
                        rotations.Rotate(dest, rotateCw, reflectX).ToList(),
                        x2, y2, z);
                }
            }
        }
        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);
        }
Example #3
0
        /// <summary>
        /// Scales the the occurency frequency of a given tile by the given multiplier,
        /// including other rotations of the tile.
        /// </summary>
        public virtual void MultiplyFrequency(Tile tile, double multiplier, TileRotation tileRotation)
        {
            var rotatedTiles = new HashSet <Tile>();

            foreach (var rotation in tileRotation.RotationGroup)
            {
                if (tileRotation.Rotate(tile, rotation, out var result))
                {
                    if (rotatedTiles.Add(result))
                    {
                        MultiplyFrequency(result, multiplier);
                    }
                }
            }
        }
Example #4
0
        private static IList <AdjacentModel.Adjacency> GetAutoAdjacencies <T>(
            IDictionary <Tile, ITopoArray <T> > subTiles,
            GridTopology subTileTopology,
            TileRotation tileRotations,
            Func <T, T, double> diff,
            double tolerance)
        {
            // Pre-process for rotations
            var allSubTiles = subTiles;

            if (subTileTopology.Width == subTileTopology.Height)
            {
                allSubTiles = new Dictionary <Tile, ITopoArray <T> >();
                foreach (var kv in subTiles)
                {
                    foreach (var rot in tileRotations.RotationGroup)
                    {
                        if (tileRotations.Rotate(kv.Key, rot, out var rt) && !allSubTiles.ContainsKey(rt))
                        {
                            allSubTiles[rt] = TopoArrayUtils.Rotate(kv.Value, rot);
                        }
                    }
                }
            }


            var output = new List <AdjacentModel.Adjacency>();

            // Left-right
            {
                var leftSlices  = allSubTiles.ToDictionary(x => x.Key, x => SliceX(x.Value, 0));
                var rightSlices = allSubTiles.ToDictionary(x => x.Key, x => SliceX(x.Value, subTileTopology.Width - 1));

                foreach (var kv1 in leftSlices)
                {
                    foreach (var kv2 in rightSlices)
                    {
                        if (DiffSlice(kv1.Value, kv2.Value, diff) <= tolerance)
                        {
                            output.Add(new AdjacentModel.Adjacency
                            {
                                Src       = new[] { kv2.Key },
                                Dest      = new[] { kv1.Key },
                                Direction = Direction.XPlus
                            });
                        }
                    }
                }
            }

            //
            {
                var upSlices   = allSubTiles.ToDictionary(x => x.Key, x => SliceY(x.Value, 0));
                var downSlices = allSubTiles.ToDictionary(x => x.Key, x => SliceY(x.Value, subTileTopology.Height - 1));

                foreach (var kv1 in upSlices)
                {
                    foreach (var kv2 in downSlices)
                    {
                        if (DiffSlice(kv1.Value, kv2.Value, diff) <= tolerance)
                        {
                            output.Add(new AdjacentModel.Adjacency
                            {
                                Src       = new[] { kv2.Key },
                                Dest      = new[] { kv1.Key },
                                Direction = Direction.YPlus
                            });
                        }
                    }
                }
            }

            //
            if (subTileTopology.Directions.Type == DirectionSetType.Cartesian3d)
            {
                var aboveSlices = allSubTiles.ToDictionary(x => x.Key, x => SliceZ(x.Value, 0));
                var belowSlices = allSubTiles.ToDictionary(x => x.Key, x => SliceZ(x.Value, subTileTopology.Depth - 1));

                foreach (var kv1 in aboveSlices)
                {
                    foreach (var kv2 in belowSlices)
                    {
                        if (DiffSlice(kv1.Value, kv2.Value, diff) <= tolerance)
                        {
                            output.Add(new AdjacentModel.Adjacency
                            {
                                Src       = new[] { kv2.Key },
                                Dest      = new[] { kv1.Key },
                                Direction = Direction.ZPlus
                            });
                        }
                    }
                }
            }

            return(output);
        }