Example #1
0
 public static IEnumerable <ITopoArray <Tile> > GetRotatedSamples(
     ITopoArray <Tile> sample,
     int rotationalSymmetry,
     bool reflectionalSymmetry,
     TileRotation tileRotation = null)
 {
     if (sample.Topology.Directions.Type == DirectionsType.Hexagonal2d)
     {
         var reflections = reflectionalSymmetry ? 2 : 1;
         for (var r = 0; r < reflections; r++)
         {
             for (var i = 0; i < 6; i += (6 / rotationalSymmetry))
             {
                 yield return(TopoArrayUtils.HexRotate(sample, i, r > 0, tileRotation));
             }
         }
     }
     else
     {
         var reflections = reflectionalSymmetry ? 2 : 1;
         for (var r = 0; r < reflections; r++)
         {
             for (var i = 0; i < 4; i += (4 / rotationalSymmetry))
             {
                 yield return(TopoArrayUtils.Rotate(sample, i, r > 0, tileRotation));
             }
         }
     }
 }
Example #2
0
 public void AddSample(ITopoArray <Tile> sample, TileRotation tileRotation = null)
 {
     foreach (var s in OverlappingAnalysis.GetRotatedSamples(sample, tileRotation))
     {
         AddSample(s);
     }
 }
Example #3
0
        private void SetupAdjacencies(TileModel model, TileRotation tileRotation, IList <AdjacentModel.Adjacency> adjacencies)
        {
            if (Config.PadTile != null)
            {
                adjacencies = AdjacencyUtils.ForcePadding(adjacencies, Parse(Config.PadTile));
            }

            if (adjacencies.Count > 0)
            {
                var adjacentModel = model as AdjacentModel;
                if (adjacentModel == null)
                {
                    throw new ConfigurationException("Setting adjacencies is only supported for the \"adjacent\" model.");
                }
                foreach (var a in adjacencies)
                {
                    adjacentModel.AddAdjacency(a);
                }

                // If there are no samples, set frequency to 1 for everything mentioned in this block
                foreach (var tile in adjacentModel.Tiles.ToList())
                {
                    adjacentModel.SetFrequency(tile, 1, tileRotation);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Finds a tile and all its rotations, and sets their total frequency.
        /// </summary>
        public void SetFrequency(Tile tile, double frequency, TileRotation tileRotation)
        {
            var rotatedTiles = new List <Tile>();

            foreach (var rotation in tileRotation.RotationGroup)
            {
                if (tileRotation.Rotate(tile, rotation, out var result))
                {
                    // Note this deliberatly can count tiles twice
                    rotatedTiles.Add(result);
                }
            }
            foreach (var rt in rotatedTiles)
            {
                int pattern = GetPattern(rt);
                frequencies[pattern] = 0.0;
            }
            var incrementalFrequency = frequency / rotatedTiles.Count;

            foreach (var rt in rotatedTiles)
            {
                int pattern = GetPattern(rt);
                frequencies[pattern] += incrementalFrequency;
            }
        }
Example #5
0
 /// <summary>
 /// Basiskonstruktor.
 /// </summary>
 public Tile()
 {
     Rotation = TileRotation.None;
     TileSheetRectangle = Rectangle.Empty;
     Shape = new AABBShape();
     Body = new Body();
     ID = IDManager.Instance.TileID;
 }
Example #6
0
 public Tile(TileRotation rotate = TileRotation.NONE)
 {
     Image = ImageProvider.Instance.GetImage(GetImageName());
     Rotation = rotate;
     Width = Image.Width;
     Height = Image.Height;
     Fields = new Collection<Field>();
     Init();
 }
Example #7
0
        /// <summary>
        /// Declares that the tiles in dest can be placed adjacent to the tiles in src, in the direction specified.
        /// Then it adds similar declarations for other rotations and reflections, as specified by rotations.
        /// </summary>
        public void AddAdjacency(IList <Tile> src, IList <Tile> dest, Direction dir, TileRotation tileRotation = null)
        {
            RequireDirections();
            var d = (int)dir;
            var x = directions.DX[d];
            var y = directions.DY[d];
            var z = directions.DZ[d];

            AddAdjacency(src, dest, x, y, z, tileRotation);
        }
        public static IEnumerable<ITopoArray<Tile>> GetRotatedSamples(
            ITopoArray<Tile> sample,
            TileRotation tileRotation = null)
        {
            tileRotation = tileRotation ?? new TileRotation();

            foreach (var rotation in tileRotation.RotationGroup)
            {
                yield return TopoArrayUtils.Rotate(sample, rotation, tileRotation);
            }
        }
        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 #10
0
        public void AddSample(ITopoArray <Tile> sample, TileRotation tileRotation = null)
        {
            if (sample.Topology.Depth == 1)
            {
                nz = 1;
            }

            var topology = sample.Topology.AsGridTopology();

            var periodicX = topology.PeriodicX;
            var periodicY = topology.PeriodicY;
            var periodicZ = topology.PeriodicZ;

            foreach (var s in OverlappingAnalysis.GetRotatedSamples(sample, tileRotation))
            {
                OverlappingAnalysis.GetPatterns(s, nx, ny, nz, periodicX, periodicY, periodicZ, patternIndices, patternArrays, frequencies);
            }

            // Update the model based on the collected data
            var directions = topology.Directions;

            // TODO: Don't regenerate this from scratch every time
            propagator = new List <HashSet <int>[]>(patternArrays.Count);
            for (var p = 0; p < patternArrays.Count; p++)
            {
                propagator.Add(new HashSet <int> [directions.Count]);
                for (var d = 0; d < directions.Count; d++)
                {
                    var l = new HashSet <int>();
                    for (var p2 = 0; p2 < patternArrays.Count; p2++)
                    {
                        var dx = directions.DX[d];
                        var dy = directions.DY[d];
                        var dz = directions.DZ[d];
                        if (Aggrees(patternArrays[p], patternArrays[p2], dx, dy, dz))
                        {
                            l.Add(p2);
                        }
                    }
                    propagator[p][d] = l;
                }
            }

            patternsToTiles = patternArrays
                              .Select((x, i) => new KeyValuePair <int, Tile>(i, x.Values[0, 0, 0]))
                              .ToDictionary(x => x.Key, x => x.Value);

            tilesToPatterns = patternsToTiles.ToLookup(x => x.Value, x => x.Key);
        }
Example #11
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 #12
0
        /// <summary>
        /// Finds a tile and all its rotations, and sets their total frequency.
        /// </summary>
        public void SetFrequency(Tile tile, double frequency, TileRotation tileRotation)
        {
            var rotatedTiles = tileRotation.RotateAll(tile).ToList();

            foreach (var rt in rotatedTiles)
            {
                int pattern = GetPattern(rt);
                frequencies[pattern] = 0.0;
            }
            var incrementalFrequency = frequency / rotatedTiles.Count;

            foreach (var rt in rotatedTiles)
            {
                int pattern = GetPattern(rt);
                frequencies[pattern] += incrementalFrequency;
            }
        }
        public static IEnumerable <ITopoArray <Tile> > GetRotatedSamples(
            ITopoArray <Tile> sample,
            TileRotation tileRotation = null)
        {
            tileRotation = tileRotation ?? new TileRotation();

            foreach (var rotation in tileRotation.RotationGroup)
            {
                if (sample.Topology.Directions.Type == DirectionsType.Hexagonal2d)
                {
                    yield return(TopoArrayUtils.HexRotate(sample, rotation, tileRotation));
                }
                else
                {
                    yield return(TopoArrayUtils.Rotate(sample, rotation, tileRotation));
                }
            }
        }
Example #14
0
        public void AddSample(ITopoArray <Tile> sample, TileRotation tileRotation = null)
        {
            if (sample.Topology.Depth == 1)
            {
                nz = 1;
            }

            var topology = sample.Topology.AsGridTopology();

            var periodicX = topology.PeriodicX;
            var periodicY = topology.PeriodicY;
            var periodicZ = topology.PeriodicZ;

            foreach (var s in OverlappingAnalysis.GetRotatedSamples(sample, tileRotation))
            {
                OverlappingAnalysis.GetPatterns(s, nx, ny, nz, periodicX, periodicY, periodicZ, patternIndices, patternArrays, frequencies);
            }

            sampleTopologyDirections = topology.Directions;
            propagator = null;// Mark as dirty
        }
Example #15
0
        public TileModel GetModel(DirectionSet directions, SampleSet sampleSet, TileRotation tileRotation)
        {
            var       samples     = sampleSet.Samples;
            var       modelConfig = Config.Model ?? new Adjacent();
            TileModel tileModel;

            if (modelConfig is Overlapping overlapping)
            {
                var model = new OverlappingModel(overlapping.NX, overlapping.NY, overlapping.NZ);
                foreach (var sample in samples)
                {
                    model.AddSample(sample, tileRotation);
                }
                tileModel = model;
            }
            else if (modelConfig is Adjacent adjacent)
            {
                var model = new AdjacentModel(directions);
                foreach (var sample in samples)
                {
                    model.AddSample(sample, tileRotation);
                }
                tileModel = model;
            }
            else
            {
                throw new ConfigurationException($"Unrecognized model type {modelConfig.GetType()}");
            }

            var autoAdjacencies = Config.AutoAdjacency
                ? AdjacencyUtils.GetAutoAdjacencies(sampleSet, tileRotation, Config.AutoAdjacencyTolerance)
                : new AdjacentModel.Adjacency[0];
            var manualAdjacencies = GetManualAdjacencies(sampleSet.Directions, tileRotation);

            SetupAdjacencies(tileModel, tileRotation, autoAdjacencies.Concat(manualAdjacencies).ToList());
            SetupTiles(tileModel, tileRotation);

            return(tileModel);
        }
Example #16
0
        private void SetupAdjacencies(TileModel model, TileRotation tileRotation)
        {
            if (Config.Adjacencies != null)
            {
                var adjacentModel = model as AdjacentModel;
                if (adjacentModel == null)
                {
                    throw new ConfigurationException("Setting adjacencies is only supported for the \"adjacent\" model.");
                }

                foreach (var a in Config.Adjacencies)
                {
                    var srcAdj  = a.Src.Select(Parse).Select(tileRotation.Canonicalize).ToList();
                    var destAdj = a.Dest.Select(Parse).Select(tileRotation.Canonicalize).ToList();
                    adjacentModel.AddAdjacency(srcAdj, destAdj, a.X, a.Y, a.Z, tileRotation);
                }

                // If there are no samples, set frequency to 1 for everything mentioned in this block
                foreach (var tile in adjacentModel.Tiles)
                {
                    adjacentModel.SetFrequency(tile, 1, tileRotation);
                }
            }
        }
Example #17
0
        public static Vector2? GetInversedVector(Vector2? vect, int width, int height, TileRotation rotation)
        {
            Vector2? newVector = null;

            if (vect == null)
            {
                return null;
            }

            switch (rotation)
            {
                case TileRotation.DEGREE_90:
                    newVector = new Vector2(width - vect.Value.Y, vect.Value.X);
                    break;
                case TileRotation.DEGREE_180:
                    newVector = new Vector2(width - vect.Value.X, height - vect.Value.Y);
                    break;
                case TileRotation.DEGREE_270:
                    newVector = new Vector2(vect.Value.Y, height - vect.Value.X);
                    break;
            }

            return newVector;
        }
Example #18
0
 private void SetupTiles(TileModel model, TileRotation tileRotation)
 {
     if (Config.Tiles != null)
     {
         foreach (var tile in Config.Tiles)
         {
             var value = Parse(tile.Value);
             if (tile.MultiplyFrequency != null)
             {
                 var    cf = tile.MultiplyFrequency.Trim();
                 double cfd;
                 if (cf.EndsWith("%"))
                 {
                     cfd = double.Parse(cf.TrimEnd('%'), CultureInfo.InvariantCulture) / 100;
                 }
                 else
                 {
                     cfd = double.Parse(cf, CultureInfo.InvariantCulture);
                 }
                 model.MultiplyFrequency(value, cfd, tileRotation);
             }
         }
     }
 }
Example #19
0
 public static IList <AdjacentModel.Adjacency> GetAutoAdjacencies(SampleSet sampleSet, TileRotation tileRotations, double tolerance)
 {
     if (sampleSet.ExportOptions is BitmapSetExportOptions bseo)
     {
         var subTiles = GetSubTiles(bseo, out var subTileTopology);
         return(GetAutoAdjacencies(subTiles, subTileTopology, tileRotations, DiffColor, tolerance));
     }
     if (sampleSet.ExportOptions is VoxSetExportOptions vseo)
     {
         var subTiles = GetSubTiles(vseo, out var subTileTopology);
         return(GetAutoAdjacencies(subTiles, subTileTopology, tileRotations, DiffIndex, tolerance));
     }
     throw new Exception("AutoAdjacency not supported for this type of tile set");
 }
Example #20
0
        public void LoadContent(Layer layer, Vector2 tileSheetPosition, Vector2 mapPosition, TileRotation rotation)
        {
            this.layer = layer;
            layer.OnScaleChange += updateRectangle;
            mapTilePosition = mapPosition;
            Rotation = rotation;
            TileSheetRectangle = new Rectangle((int)(tileSheetPosition.X * layer.TileDimensions.X), (int)(tileSheetPosition.Y * layer.TileDimensions.Y),
                                               (int)layer.TileDimensions.X, (int)layer.TileDimensions.Y);
            Body.Position = mapPosition * layer.TileDimensions * layer.Scale;

            Shape.OnAreaChanged += delegate
            { Body.Area = Shape.Area; };

            Body.LoadContent(Material.Tile);
            Shape.LoadContent(this, layer.TileDimensions.X, layer.TileDimensions.Y, layer.Scale);
        }
Example #21
0
        public List <ITileConstraint> GetConstraints(DirectionSet directions, TileRotation tileRotation)
        {
            var is3d = directions.Type == DirectionSetType.Cartesian3d;

            var constraints = new List <ITileConstraint>();

            if (Config.Ground != null)
            {
                var groundTile = Parse(Config.Ground);
                constraints.Add(new BorderConstraint
                {
                    Sides = is3d ? BorderSides.ZMin : BorderSides.YMax,
                    Tiles = new[] { groundTile },
                });
                constraints.Add(new BorderConstraint
                {
                    Sides      = is3d ? BorderSides.ZMin : BorderSides.YMax,
                    Tiles      = new[] { groundTile },
                    InvertArea = true,
                    Ban        = true,
                });
            }

            if (Config.Constraints != null)
            {
                foreach (var constraint in Config.Constraints)
                {
                    if (constraint is PathConfig pathData)
                    {
                        var tiles = new HashSet <Tile>(pathData.Tiles.Select(Parse));
#pragma warning disable CS0618 // Type or member is obsolete
                        var p = new PathConstraint(tiles, pathData.EndPoints, tileRotation)
#pragma warning restore CS0618 // Type or member is obsolete
                        {
                            EndPointTiles = pathData.EndPointTiles == null ? null : new HashSet <Tile>(pathData.EndPointTiles.Select(Parse))
                        };
                        constraints.Add(p);
                    }
                    else if (constraint is EdgedPathConfig edgedPathData)
                    {
                        var exits = edgedPathData.Exits.ToDictionary(
                            kv => Parse(kv.Key), x => (ISet <Direction>) new HashSet <Direction>(x.Value.Select(ParseDirection)));
#pragma warning disable CS0618 // Type or member is obsolete
                        var p = new EdgedPathConstraint(exits, edgedPathData.EndPoints, tileRotation)
#pragma warning restore CS0618 // Type or member is obsolete
                        {
                            EndPointTiles = edgedPathData.EndPointTiles == null ? null : new HashSet <Tile>(edgedPathData.EndPointTiles.Select(Parse))
                        };
                        constraints.Add(p);
                    }
                    else if (constraint is BorderConfig borderData)
                    {
                        var tiles        = borderData.Tiles.Select(Parse).ToArray();
                        var sides        = borderData.Sides == null ? BorderSides.All : (BorderSides)Enum.Parse(typeof(BorderSides), borderData.Sides, true);
                        var excludeSides = borderData.ExcludeSides == null ? BorderSides.None : (BorderSides)Enum.Parse(typeof(BorderSides), borderData.ExcludeSides, true);
                        if (!is3d)
                        {
                            sides        = sides & ~BorderSides.ZMin & ~BorderSides.ZMax;
                            excludeSides = excludeSides & ~BorderSides.ZMin & ~BorderSides.ZMax;
                        }
                        constraints.Add(new BorderConstraint
                        {
                            Tiles        = tiles,
                            Sides        = sides,
                            ExcludeSides = excludeSides,
                            InvertArea   = borderData.InvertArea,
                            Ban          = borderData.Ban,
                        });
                    }
                    else if (constraint is FixedTileConfig fixedTileConfig)
                    {
                        constraints.Add(new FixedTileConstraint
                        {
                            Tiles = fixedTileConfig.Tiles.Select(Parse).ToArray(),
                            Point = fixedTileConfig.Point,
                        });
                    }
                    else if (constraint is MaxConsecutiveConfig maxConsecutiveConfig)
                    {
                        var axes = maxConsecutiveConfig.Axes?.Select(ParseAxis);
                        constraints.Add(new MaxConsecutiveConstraint
                        {
                            Tiles    = new HashSet <Tile>(maxConsecutiveConfig.Tiles.Select(Parse)),
                            MaxCount = maxConsecutiveConfig.MaxCount,
                            Axes     = axes == null ? null : new HashSet <Axis>(axes),
                        });
                    }
                    else if (constraint is MirrorXConfig mirrorYConfig)
                    {
                        constraints.Add(new MirrorXConstraint
                        {
                            TileRotation = tileRotation,
                        });
                    }
                    else if (constraint is MirrorYConfig mirrorXConfig)
                    {
                        constraints.Add(new MirrorYConstraint
                        {
                            TileRotation = tileRotation,
                        });
                    }
                    else if (constraint is CountConfig countConfig)
                    {
                        constraints.Add(new CountConstraint
                        {
                            Tiles      = new HashSet <Tile>(countConfig.Tiles.Select(Parse)),
                            Comparison = countConfig.Comparison,
                            Count      = countConfig.Count,
                            Eager      = countConfig.Eager,
                        });
                    }
                    else if (constraint is SeparationConfig separationConfig)
                    {
                        constraints.Add(new SeparationConstraint
                        {
                            Tiles       = new HashSet <Tile>(separationConfig.Tiles.Select(Parse)),
                            MinDistance = separationConfig.MinDistance,
                        });
                    }
                    else if (constraint is ConnectedConfig connectedConfig)
                    {
                        constraints.Add(new ConnectedConstraint
                        {
                            PathSpec = GetPathSpec(connectedConfig.PathSpec),
                        });
                    }
                    else if (constraint is LoopConfig loopConfig)
                    {
                        constraints.Add(new LoopConstraint
                        {
                            PathSpec = GetPathSpec(loopConfig.PathSpec),
                        });
                    }
                    else if (constraint is AcyclicConfig acyclicConfig)
                    {
                        constraints.Add(new AcyclicConstraint
                        {
                            PathSpec = GetPathSpec(acyclicConfig.PathSpec),
                        });
                    }
                    else
                    {
                        throw new NotImplementedException($"Unknown constraint type {constraint.GetType()}");
                    }
                }
            }

            return(constraints);
        }
Example #22
0
        /// <summary>
        /// Rotate field to reflect tile rotation
        /// </summary>
        /// <param name="field">field to rotate</param>
        /// <param name="rotation">rotation - 0 / 90 / 180 / 270 degrees</param>
        /// <param name="width">tile width</param>
        /// <param name="height">tile height</param>
        public static void RotateField(Field field, TileRotation rotation, int width, int height)
        {
            var newVector = MapVector.GetInversedVector(new Vector2(field.Rect.X, field.Rect.Y), width, height, rotation);
            var newX = (int)newVector.Value.X;
            var newY = (int)newVector.Value.Y;

            var tempOpenLeft = field.OpenLeft;
            var tempOpenRight = field.OpenRight;
            var tempOpenTop = field.OpenTop;
            var tempOpenBottom = field.OpenBottom;

            var tempTopField = field.TopField;
            var tempBottomField = field.BottomField;
            var tempLeftField = field.LeftField;
            var tempRightField = field.RightField;
            var tempTopRightField = field.TopRightField;
            var tempTopLeftField = field.TopLeftField;
            var tempBottomLeftField = field.BottomLeftField;
            var tempBottomRightField = field.BottomRightField;

            switch (rotation)
            {
                case TileRotation.DEGREE_90:
                    newX -= field.Rect.Width;
                    field.OpenLeft = tempOpenBottom;
                    field.OpenRight = tempOpenTop;
                    field.OpenTop = tempOpenLeft;
                    field.OpenBottom = tempOpenRight;

                    field.TopField = tempLeftField;
                    field.BottomField = tempRightField;
                    field.LeftField = tempBottomField;
                    field.RightField = tempTopField;

                    field.TopLeftField = tempBottomLeftField;
                    field.TopRightField = tempTopLeftField;
                    field.BottomRightField = tempTopRightField;
                    field.BottomLeftField = tempBottomRightField;
                    break;
                case TileRotation.DEGREE_180:
                    newX -= field.Rect.Width;
                    newY -= field.Rect.Height;
                    field.OpenLeft = tempOpenRight;
                    field.OpenRight = tempOpenLeft;
                    field.OpenTop = tempOpenBottom;
                    field.OpenBottom = tempOpenTop;

                    field.LeftField = tempRightField;
                    field.RightField = tempLeftField;
                    field.TopField = tempBottomField;
                    field.BottomField = tempTopField;

                    field.TopLeftField = tempBottomRightField;
                    field.TopRightField = tempBottomLeftField;
                    field.BottomRightField = tempTopLeftField;
                    field.BottomLeftField = tempTopRightField;
                    break;
                case TileRotation.DEGREE_270:
                    newY -= field.Rect.Height;
                    field.OpenLeft = tempOpenTop;
                    field.OpenRight = tempOpenBottom;
                    field.OpenTop = tempOpenRight;
                    field.OpenBottom = tempOpenLeft;

                    field.LeftField = tempTopField;
                    field.RightField = tempBottomField;
                    field.TopField = tempRightField;
                    field.BottomField = tempLeftField;

                    field.TopLeftField = tempTopRightField;
                    field.TopRightField = tempBottomRightField;
                    field.BottomRightField = tempBottomLeftField;
                    field.BottomLeftField = tempTopLeftField;
                    break;
            }

            field.Rect = new Rectangle(newX, newY, field.Rect.Width, field.Rect.Height);
            field.OriginRect = field.Rect;
        }
Example #23
0
        private IList <AdjacentModel.Adjacency> GetManualAdjacencies(DirectionSet directions, TileRotation tileRotation)
        {
            if (Config.Adjacencies == null)
            {
                return(new AdjacentModel.Adjacency[0]);
            }

            AdjacentModel.Adjacency Convert(AdjacencyData a)
            {
                return(new AdjacentModel.Adjacency
                {
                    Src = a.Src.Select(Parse).Select(tileRotation.Canonicalize).ToArray(),
                    Dest = a.Dest.Select(Parse).Select(tileRotation.Canonicalize).ToArray(),
                    Direction = a.Direction,
                });
            }

            return(AdjacencyUtils.Rotate(
                       Config.Adjacencies.Select(Convert).ToList(),
                       tileRotation.RotationGroup,
                       directions,
                       tileRotation));
        }
Example #24
0
 public void Rotate(TileRotation rotation, int width, int height)
 {
     FieldHelper.RotateField(this, rotation, width, height);
 }
Example #25
0
 /// <summary>
 /// Elforgatja a mezőt. A mező belső reprezentációjában van egy "rotation" tag, ami a mező aktuális elfordulását írja le, relatív a mező alapállapotához.
 /// </summary>
 public void Rotate()
 {
     Rotation = Rotation.GetNext();
 }
Example #26
0
        public static ITopoArray <Tile> HexRotate(ITopoArray <Tile> original, Rotation rotation, TileRotation tileRotation = null)
        {
            bool TileRotate(Tile tile, out Tile result)
            {
                return(tileRotation.Rotate(tile, rotation, out result));
            }

            return(HexRotate <Tile>(original, rotation, tileRotation == null ? null : (TileRotate <Tile>)TileRotate));
        }
Example #27
0
 public static IList <AdjacentModel.Adjacency> Rotate(IList <AdjacentModel.Adjacency> adjacencies, RotationGroup rg, DirectionSet directions, TileRotation tileRotation)
 {
     return(rg.SelectMany(r => Rotate(adjacencies, r, directions, tileRotation)).ToList());
 }
Example #28
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, TileRotation tileRotation = null)
        {
            RequireDirections();

            tileRotation = tileRotation ?? new TileRotation();

            foreach (var rotation in tileRotation.RotationGroup)
            {
                var(x2, y2) = TopoArrayUtils.RotateVector(directions.Type, x, y, rotation);

                AddAdjacency(
                    tileRotation.Rotate(src, rotation).ToList(),
                    tileRotation.Rotate(dest, rotation).ToList(),
                    x2, y2, z);
            }
        }
Example #29
0
 public static IList <AdjacentModel.Adjacency> Rotate(IList <AdjacentModel.Adjacency> adjacencies, Rotation rotation, DirectionSet directions, TileRotation tileRotation)
 {
     return(adjacencies
            .Select(x => Rotate(x, rotation, directions, tileRotation))
            .Where(x => x.Src.Length > 0 && x.Dest.Length > 0)
            .ToList());
 }
Example #30
0
 public static AdjacentModel.Adjacency Rotate(AdjacentModel.Adjacency adjacency, Rotation rotation, DirectionSet directions, TileRotation tileRotation)
 {
     return(new AdjacentModel.Adjacency
     {
         Src = tileRotation.Rotate(adjacency.Src, rotation).ToArray(),
         Dest = tileRotation.Rotate(adjacency.Dest, rotation).ToArray(),
         Direction = TopoArrayUtils.RotateDirection(directions, adjacency.Direction, rotation),
     });
 }
Example #31
0
 public TileEnterA(TileRotation rotate = TileRotation.NONE) : base(rotate)
 {
 }
Example #32
0
        public static ITopoArray <Tile> HexRotate(ITopoArray <Tile> original, int rotate, bool reflectX = false, TileRotation tileRotation = null)
        {
            bool TileRotate(Tile tile, out Tile result)
            {
                return(tileRotation.Rotate(tile, rotate, reflectX, out result));
            }

            return(HexRotate <Tile>(original, rotate, reflectX, tileRotation == null ? null : (TileRotate <Tile>)TileRotate));
        }
Example #33
0
        public TileModel GetModel(DirectionSet directions, ITopoArray <Tile>[] samples, TileRotation tileRotation)
        {
            var       modelConfig = Config.Model ?? new Adjacent();
            TileModel tileModel;

            if (modelConfig is Overlapping overlapping)
            {
                var model = new OverlappingModel(overlapping.NX, overlapping.NY, overlapping.NZ);
                foreach (var sample in samples)
                {
                    model.AddSample(sample, tileRotation);
                }
                tileModel = model;
            }
            else if (modelConfig is Adjacent adjacent)
            {
                var model = new AdjacentModel(directions);
                foreach (var sample in samples)
                {
                    model.AddSample(sample, tileRotation);
                }
                tileModel = model;
            }
            else
            {
                throw new ConfigurationException($"Unrecognized model type {modelConfig.GetType()}");
            }

            SetupAdjacencies(tileModel, tileRotation);
            SetupTiles(tileModel, tileRotation);

            return(tileModel);
        }
 public EdgedPathConstraint(IDictionary <Tile, ISet <Direction> > exits, Point[] endPoints = null, TileRotation tileRotation = null)
 {
     this.Exits        = exits;
     this.EndPoints    = endPoints;
     this.TileRotation = tileRotation;
 }
Example #35
0
 public PathConstraint(ISet <Tile> tiles, Point[] endPoints = null, TileRotation tileRotation = null)
 {
     this.Tiles        = tiles;
     this.EndPoints    = endPoints;
     this.TileRotation = tileRotation;
 }
Example #36
0
        public List <ITileConstraint> GetConstraints(DirectionSet directions, TileRotation tileRotation)
        {
            var is3d = directions.Type == DirectionSetType.Cartesian3d;

            var constraints = new List <ITileConstraint>();

            if (Config.Ground != null)
            {
                var groundTile = Parse(Config.Ground);
                constraints.Add(new BorderConstraint
                {
                    Sides = is3d ? BorderSides.ZMin : BorderSides.YMax,
                    Tiles = new[] { groundTile },
                });
                constraints.Add(new BorderConstraint
                {
                    Sides      = is3d ? BorderSides.ZMin : BorderSides.YMax,
                    Tiles      = new[] { groundTile },
                    InvertArea = true,
                    Ban        = true,
                });
            }

            if (Config.Constraints != null)
            {
                foreach (var constraint in Config.Constraints)
                {
                    if (constraint is PathConfig pathData)
                    {
                        var tiles = new HashSet <Tile>(pathData.Tiles.Select(Parse));
                        var p     = new PathConstraint(tiles, pathData.EndPoints);
                        constraints.Add(p);
                    }
                    else if (constraint is EdgedPathConfig edgedPathData)
                    {
                        var exits = edgedPathData.Exits.ToDictionary(
                            kv => Parse(kv.Key), x => (ISet <Direction>) new HashSet <Direction>(x.Value.Select(ParseDirection)));
                        var p = new EdgedPathConstraint(exits, edgedPathData.EndPoints, tileRotation);
                        constraints.Add(p);
                    }
                    else if (constraint is BorderConfig borderData)
                    {
                        var tiles        = borderData.Tiles.Select(Parse).ToArray();
                        var sides        = borderData.Sides == null ? BorderSides.All : (BorderSides)Enum.Parse(typeof(BorderSides), borderData.Sides, true);
                        var excludeSides = borderData.ExcludeSides == null ? BorderSides.None : (BorderSides)Enum.Parse(typeof(BorderSides), borderData.ExcludeSides, true);
                        if (!is3d)
                        {
                            sides        = sides & ~BorderSides.ZMin & ~BorderSides.ZMax;
                            excludeSides = excludeSides & ~BorderSides.ZMin & ~BorderSides.ZMax;
                        }
                        constraints.Add(new BorderConstraint
                        {
                            Tiles        = tiles,
                            Sides        = sides,
                            ExcludeSides = excludeSides,
                            InvertArea   = borderData.InvertArea,
                            Ban          = borderData.Ban,
                        });
                    }
                    else if (constraint is FixedTileConfig fixedTileConfig)
                    {
                        constraints.Add(new FixedTileConstraint
                        {
                            Tiles = fixedTileConfig.Tiles.Select(Parse).ToArray(),
                            Point = fixedTileConfig.Point,
                        });
                    }
                    else if (constraint is MaxConsecutiveConfig maxConsecutiveConfig)
                    {
                        var axes = maxConsecutiveConfig.Axes?.Select(ParseAxis);
                        constraints.Add(new MaxConsecutiveConstraint
                        {
                            Tiles    = new HashSet <Tile>(maxConsecutiveConfig.Tiles.Select(Parse)),
                            MaxCount = maxConsecutiveConfig.MaxCount,
                            Axes     = axes == null ? null : new HashSet <Axis>(axes),
                        });
                    }
                    else if (constraint is MirrorConfig mirrorConfig)
                    {
                        constraints.Add(new MirrorConstraint
                        {
                            TileRotation = tileRotation,
                        });
                    }
                    else
                    {
                        throw new NotImplementedException($"Unknown constraint type {constraint.GetType()}");
                    }
                }
            }

            return(constraints);
        }
Example #37
0
        public static ITopoArray <Tile> Rotate(ITopoArray <Tile> original, Rotation rotation, TileRotation tileRotation = null)
        {
            var type = original.Topology.Directions.Type;

            if (type == DirectionSetType.Cartesian2d ||
                type == DirectionSetType.Cartesian3d)
            {
                return(SquareRotate(original, rotation, tileRotation));
            }
            else if (type == DirectionSetType.Hexagonal2d)
            {
                return(HexRotate(original, rotation, tileRotation));
            }
            else
            {
                throw new Exception($"Unknown directions type {type}");
            }
        }
Example #38
0
 public TileExitA(TileRotation rotate = TileRotation.NONE) : base(rotate)
 {
 }
Example #39
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);
        }