public void TestSetFrequencyWithRotations()
        {
            var model = new AdjacentModel(DirectionSet.Cartesian2d);

            var tile1 = new Tile(1);
            var tile2 = new Tile(2);

            var builder = new TileRotationBuilder(4, true);

            builder.AddSymmetry(tile1, TileSymmetry.T);
            builder.SetTreatment(tile1, TileRotationTreatment.Generated);
            builder.SetTreatment(tile2, TileRotationTreatment.Generated);

            var rotations = builder.Build();

            model.SetFrequency(tile1, 1.0, rotations);
            model.SetFrequency(tile2, 1.0, rotations);

            var tileModelMapping = model.GetTileModelMapping(new GridTopology(10, 10, false));
            var patternModel     = tileModelMapping.PatternModel;

            double GetFrequency(Tile tile)
            {
                return(patternModel.Frequencies[tileModelMapping.TilesToPatternsByOffset[0][tile].First()]);
            }

            Assert.AreEqual(0.25, GetFrequency(tile1));
            Assert.AreEqual(0.25, GetFrequency(new Tile(new RotatedTile {
                Tile = tile1, Rotation = new Rotation(90)
            })));
            Assert.AreEqual(0.125, GetFrequency(tile2));
        }
Example #2
0
        public void TestRotationalAddAdjacenciesAdvanced()
        {
            var model = new AdjacentModel(Directions.Cartesian2d);
            var tile1 = new Tile(1);
            var tile2 = new Tile(2);
            var tile3 = new Tile(3);
            var tile4 = new Tile(4);

            var rotationBuilder = new TileRotationBuilder(TileRotationTreatment.Missing);

            rotationBuilder.Add(tile1, 1, false, tile3);
            rotationBuilder.Add(tile2, 1, false, tile4);
            var rotations = rotationBuilder.Build();

            model.AddAdjacency(new[] { tile1 }, new[] { tile2 }, 1, 0, 0, 4, false, rotations);

            var patternModel = model.GetPatternModel();

            CollectionAssert.AreEquivalent(new int[] { 1 }, patternModel.Propagator[0][0]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[0][1]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[0][2]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[0][3]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[1][0]);
            CollectionAssert.AreEquivalent(new int[] { 0 }, patternModel.Propagator[1][1]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[1][2]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[1][3]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[2][0]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[2][1]);
            CollectionAssert.AreEquivalent(new int[] { 3 }, patternModel.Propagator[2][2]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[2][3]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[3][0]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[3][1]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[3][2]);
            CollectionAssert.AreEquivalent(new int[] { 2 }, patternModel.Propagator[3][3]);
        }
Example #3
0
        public void TestTileRotationBuilderContradiction2()
        {
            var builder = new TileRotationBuilder();

            builder.Add(new Tile(1), 0, true, new Tile(2));
            Assert.Throws <Exception>(() => builder.Add(new Tile(2), 0, true, new Tile(3)));
        }
Example #4
0
        public void TestTileRotationBuilderCompounding()
        {
            var builder = new TileRotationBuilder();

            builder.Add(new Tile(1), 0, true, new Tile(2));
            builder.Add(new Tile(2), 1, false, new Tile(2));

            var rotation = builder.Build();
            var b1       = rotation.Rotate(new Tile(1), 1, false, out var r1);

            Assert.IsTrue(b1);
            Assert.AreEqual(new Tile(1), r1);
        }
Example #5
0
        public void MirrorSetup()
        {
            var trb = new TileRotationBuilder(4, true, TileRotationTreatment.Missing);

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

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

            var reflectX = new Rotation(0, true);

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

            var model = new AdjacentModel(DirectionSet.Cartesian2d);

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


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

            var tr = trb.Build();

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


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

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

            propagator7 = new TilePropagator(model, topology, options);
        }
Example #6
0
        public TileRotation GetTileRotation(TileRotationTreatment?rotationTreatment, Topology topology)
        {
            var tileData = Config.Tiles;

            var tileRotationBuilder = new TileRotationBuilder(Config.RotationalSymmetry, Config.ReflectionalSymmetry, rotationTreatment ?? TileRotationTreatment.Unchanged);
            var rotationGroup       = tileRotationBuilder.RotationGroup;

            // Setup tiles
            if (tileData != null)
            {
                foreach (var td in tileData)
                {
                    var tile = Parse(td.Value);
                    if (td.TileSymmetry != null)
                    {
                        var ts = TileSymmetryUtils.Parse(td.TileSymmetry);
                        tileRotationBuilder.AddSymmetry(tile, ts);
                    }
                    if (td.ReflectX != null)
                    {
                        tileRotationBuilder.Add(tile, new Rotation(0, true), Parse(td.ReflectX));
                    }
                    if (td.ReflectY != null)
                    {
                        tileRotationBuilder.Add(tile, new Rotation(180, true), Parse(td.ReflectY));
                    }
                    if (td.RotateCw != null)
                    {
                        tileRotationBuilder.Add(tile, new Rotation(rotationGroup.SmallestAngle, false), Parse(td.RotateCw));
                    }
                    if (td.RotateCcw != null)
                    {
                        tileRotationBuilder.Add(tile, new Rotation(360 - rotationGroup.SmallestAngle, false), Parse(td.RotateCcw));
                    }
                    if (td.RotationTreatment != null)
                    {
                        tileRotationBuilder.SetTreatment(tile, td.RotationTreatment.Value);
                    }
                }
            }

            return(tileRotationBuilder.Build());
        }
Example #7
0
        internal override ITileConstraint GetTileConstraint(AdjacentModel model)
        {
            var actualSymmetricTilesX = new HashSet <TesseraTile>(hasSymmetricTiles ? symmetricTilesX : GetSymmetricTilesX());
            var actualSymmetricTilesZ = new HashSet <TesseraTile>(hasSymmetricTiles ? symmetricTilesZ : GetSymmetricTilesZ());

            // TODO: Not working in demo
            // TODO: Symmetric definition doesn't work with rotated tiles!

            var trb = new TileRotationBuilder(4, true, TileRotationTreatment.Missing);

            foreach (var tile in model.Tiles)
            {
                var modelTile = (ModelTile)tile.Value;
                if ((modelTile.Rotation.RotateCw % 180 == 0 ? actualSymmetricTilesX :  actualSymmetricTilesZ).Contains(modelTile.Tile))
                {
                    var r          = new Rotation(0, true);
                    var bounds     = modelTile.Tile.GetBounds();
                    var modelTile2 = new ModelTile
                    {
                        Tile     = modelTile.Tile,
                        Offset   = modelTile.Offset,
                        Rotation = modelTile.Rotation,
                    };
                    trb.Add(tile, r, new Tile(modelTile2));
                }
                else if (modelTile.Tile.reflectable)
                {
                    var r          = new Rotation(0, true);
                    var modelTile2 = new ModelTile
                    {
                        Tile     = modelTile.Tile,
                        Offset   = modelTile.Offset,
                        Rotation = modelTile.Rotation * r,
                    };
                    trb.Add(tile, r, new Tile(modelTile2));
                }
            }

            return(new DeBroglie.Constraints.MirrorXConstraint
            {
                TileRotation = trb.Build(),
            });
        }
Example #8
0
        private TileRotation GetTileRotation(List <TileData> tileData, TileRotationTreatment?rotationTreatment, Topology topology)
        {
            var tileRotationBuilder = new TileRotationBuilder(rotationTreatment ?? TileRotationTreatment.Unchanged);

            // Setup tiles
            if (tileData != null)
            {
                foreach (var td in tileData)
                {
                    var tile = Parse(td.Value);
                    if (td.TileSymmetry != null)
                    {
                        var ts = TileSymmetryUtils.Parse(td.TileSymmetry);
                        tileRotationBuilder.AddSymmetry(tile, ts);
                    }
                    if (td.ReflectX != null)
                    {
                        tileRotationBuilder.Add(tile, 0, true, Parse(td.ReflectX));
                    }
                    if (td.ReflectY != null)
                    {
                        tileRotationBuilder.Add(tile, topology.Directions.Count / 2, true, Parse(td.ReflectY));
                    }
                    if (td.RotateCw != null)
                    {
                        tileRotationBuilder.Add(tile, 1, false, Parse(td.RotateCw));
                    }
                    if (td.RotateCcw != null)
                    {
                        tileRotationBuilder.Add(tile, -1, false, Parse(td.RotateCcw));
                    }
                    if (td.RotationTreatment != null)
                    {
                        tileRotationBuilder.SetTreatment(tile, td.RotationTreatment.Value);
                    }
                }
            }

            return(tileRotationBuilder.Build());
        }
        public void TestRotationalAddAdjacenciesAdvanced()
        {
            var model = new AdjacentModel(DirectionSet.Cartesian2d);
            var tile1 = new Tile(1);
            var tile2 = new Tile(2);
            var tile3 = new Tile(3);
            var tile4 = new Tile(4);


            var rotationBuilder = new TileRotationBuilder(4, false, TileRotationTreatment.Missing);

            rotationBuilder.Add(tile1, new Rotation(90), tile3);
            rotationBuilder.Add(tile2, new Rotation(90), tile4);
            var rotations = rotationBuilder.Build();

            model.AddAdjacency(new[] { tile1 }, new[] { tile2 }, 1, 0, 0, rotations);

            model.SetUniformFrequency();

            var patternModel = model.GetTileModelMapping(new GridTopology(10, 10, false)).PatternModel;

            CollectionAssert.AreEquivalent(new int[] { 1 }, patternModel.Propagator[0][0]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[0][1]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[0][2]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[0][3]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[1][0]);
            CollectionAssert.AreEquivalent(new int[] { 0 }, patternModel.Propagator[1][1]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[1][2]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[1][3]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[2][0]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[2][1]);
            CollectionAssert.AreEquivalent(new int[] { 3 }, patternModel.Propagator[2][2]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[2][3]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[3][0]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[3][1]);
            CollectionAssert.AreEquivalent(new int[] {   }, patternModel.Propagator[3][2]);
            CollectionAssert.AreEquivalent(new int[] { 2 }, patternModel.Propagator[3][3]);
        }
Example #10
0
        public void TestGraphAdjacentModel()
        {
            // Define simple cube graph which unfolds and orients as follows
            //
            //    ┌─┐
            //    │4│
            //  ┌─┼─┼─┬─┐
            //  │3│0│1│2│
            //  └─┼─┼─┴─┘
            //    │5│
            //    └─┘
            // Neighbours (from top, clockwise)
            // 0: [4, 1, 5, 3]
            // 1: [4, 2, 5, 0]
            // 2: [4, 3, 5, 1]
            // 3: [4, 0, 5, 2]
            // 4: [2, 1, 0, 3]
            // 5: [0, 1, 2, 3]

            var meshBuilder = new MeshTopologyBuilder(DirectionSet.Cartesian2d);

            meshBuilder.Add(0, 1, Direction.XPlus);
            meshBuilder.Add(0, 3, Direction.XMinus);
            meshBuilder.Add(0, 5, Direction.YPlus);
            meshBuilder.Add(0, 4, Direction.YMinus);
            meshBuilder.Add(1, 2, Direction.XPlus);
            meshBuilder.Add(1, 0, Direction.XMinus);
            meshBuilder.Add(1, 5, Direction.YPlus);
            meshBuilder.Add(1, 4, Direction.YMinus);
            meshBuilder.Add(2, 3, Direction.XPlus);
            meshBuilder.Add(2, 1, Direction.XMinus);
            meshBuilder.Add(2, 5, Direction.YPlus);
            meshBuilder.Add(2, 4, Direction.YMinus);
            meshBuilder.Add(3, 0, Direction.XPlus);
            meshBuilder.Add(3, 2, Direction.XMinus);
            meshBuilder.Add(3, 5, Direction.YPlus);
            meshBuilder.Add(3, 4, Direction.YMinus);
            meshBuilder.Add(4, 1, Direction.XPlus);
            meshBuilder.Add(4, 3, Direction.XMinus);
            meshBuilder.Add(4, 0, Direction.YPlus);
            meshBuilder.Add(4, 2, Direction.YMinus);
            meshBuilder.Add(5, 1, Direction.XPlus);
            meshBuilder.Add(5, 3, Direction.XMinus);
            meshBuilder.Add(5, 2, Direction.YPlus);
            meshBuilder.Add(5, 0, Direction.YMinus);

            var topology = meshBuilder.GetTopology();

            var model = new GraphAdjacentModel(meshBuilder.GetInfo());

            var empty     = new Tile(" ");
            var straight1 = new Tile("║");
            var straight2 = new Tile("═");
            var corner1   = new Tile("╚");
            var corner2   = new Tile("╔");
            var corner3   = new Tile("╗");
            var corner4   = new Tile("╝");

            var tileRotationBuilder = new TileRotationBuilder(4, true, TileRotationTreatment.Missing);

            tileRotationBuilder.AddSymmetry(empty, TileSymmetry.X);
            tileRotationBuilder.AddSymmetry(straight1, TileSymmetry.I);
            tileRotationBuilder.AddSymmetry(straight2, TileSymmetry.I);
            tileRotationBuilder.AddSymmetry(corner1, TileSymmetry.L);
            tileRotationBuilder.AddSymmetry(corner2, TileSymmetry.Q);
            tileRotationBuilder.AddSymmetry(corner3, TileSymmetry.L);
            tileRotationBuilder.AddSymmetry(corner4, TileSymmetry.Q);
            tileRotationBuilder.Add(straight1, new Rotation(90), straight2);
            tileRotationBuilder.Add(corner1, new Rotation(90), corner2);
            tileRotationBuilder.Add(corner2, new Rotation(90), corner3);
            tileRotationBuilder.Add(corner3, new Rotation(90), corner4);
            tileRotationBuilder.Add(corner4, new Rotation(90), corner1);

            var tileRotation = tileRotationBuilder.Build();

            model.AddAdjacency(
                new[] { empty, straight1, corner3, corner4 },
                new[] { empty, straight1, corner1, corner2 },
                Direction.XPlus, tileRotation);

            model.AddAdjacency(
                new[] { straight2, corner1, corner2 },
                new[] { straight2, corner3, corner4 },
                Direction.XPlus, tileRotation);

            model.AddAdjacency(
                new[] { empty, straight2, corner1, corner4 },
                new[] { empty, straight2, corner2, corner3 },
                Direction.YPlus, tileRotation);

            model.AddAdjacency(
                new[] { straight1, corner2, corner3 },
                new[] { straight1, corner1, corner4 },
                Direction.YPlus, tileRotation);

            model.SetUniformFrequency();

            var propagator = new TilePropagator(model, topology, new TilePropagatorOptions
            {
                BackTrackDepth = -1,
            });

            void PrintPropagator()
            {
                var a = propagator.ToValueArray("?", "!");

                var str = @"
                ┌─┐
                │4│
              ┌─┼─┼─┬─┐
              │3│0│1│2│
              └─┼─┼─┴─┘
                │5│
                └─┘";

                for (var i = 0; i < 6; i++)
                {
                    str = str.Replace(i.ToString(), (string)a.Get(i));
                }
                System.Console.Write(str);
            }

            propagator.Run();
            PrintPropagator();

            Assert.AreEqual(Resolution.Decided, propagator.Status);
        }
        public void TestMirrorConstraint()
        {
            var trb = new TileRotationBuilder(4, true, TileRotationTreatment.Missing);

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

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

            var reflectX = new Rotation(0, true);

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

            var model = new AdjacentModel(DirectionSet.Cartesian2d);

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

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

            var tr = trb.Build();

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

            // tile1 reflects to tile 2
            {
                var t2 = new GridTopology(2, 1, false);
                var p2 = new TilePropagator(model, t2, constraints: constraints);
                p2.Select(0, 0, 0, tile1);
                var status = p2.Run();
                Assert.AreEqual(Resolution.Decided, status);
                Assert.AreEqual(tile2, p2.ToArray().Get(1, 0));
            }

            // tile3 reflects to tile3
            {
                var t2 = new GridTopology(2, 1, false);
                var p2 = new TilePropagator(model, t2, constraints: constraints);
                p2.Select(0, 0, 0, tile3);
                var status = p2.Run();
                Assert.AreEqual(Resolution.Decided, status);
                Assert.AreEqual(tile3, p2.ToArray().Get(1, 0));
            }

            // tile3 only tile that can go in a central space
            // (tile5 can go, but has zero frequency)
            // So tile3 should be selected reliably
            {
                var t2     = new GridTopology(3, 1, false);
                var p2     = new TilePropagator(model, t2, constraints: constraints);
                var status = p2.Run();
                Assert.AreEqual(Resolution.Decided, status);
                Assert.AreEqual(tile3, p2.ToArray().Get(1, 0));
            }

            // tile5 can be reflected, but cannot
            // be placed adjacent to it's own reflection
            {
                var t2 = new GridTopology(2, 1, false);
                var p2 = new TilePropagator(model, t2, constraints: constraints);
                p2.Select(0, 0, 0, tile5);
                var status = p2.Run();
                Assert.AreEqual(Resolution.Contradiction, status);
            }

            {
                var t2 = new GridTopology(4, 1, false);
                var p2 = new TilePropagator(model, t2, constraints: constraints);
                p2.Select(0, 0, 0, tile5);
                var status = p2.Run();
                Assert.AreEqual(Resolution.Decided, status);
            }
        }