public void TestDirectionality2() { var model = new AdjacentModel(DirectionSet.Cartesian2d); model.AddAdjacency(new Tile(1), new Tile(2), 1, 0, 0); model.SetUniformFrequency(); var topology = new GridTopology(2, 1, false); var left = Direction.XMinus; var right = Direction.XPlus; #pragma warning disable CS0618 // Type or member is obsolete var edgedPathConstraint = new EdgedPathConstraint( #pragma warning restore CS0618 // Type or member is obsolete new Dictionary <Tile, ISet <Direction> >() { { new Tile(1), new[] { left, right }.ToHashSet() }, { new Tile(2), new[] { left, right }.ToHashSet() }, } ); var propagator = new TilePropagator(model, topology, constraints: new[] { edgedPathConstraint }); propagator.Run(); }
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)); }
internal override ITileConstraint GetTileConstraint(AdjacentModel model) { if (hasPathColors) { var colorSet = new HashSet <int>(pathColors); var pathTilesSet = new HashSet <TesseraTile>(pathTiles); var generator = GetComponent <TesseraGenerator>(); TesseraGeneratorHelper.SetupModelFromTiles(generator.tiles, out var allTiles, out var internalAdjacencies, out var tilesByFaceDir); // All internal connections are valid exits var internalDirs = internalAdjacencies .Concat(internalAdjacencies.Select(t => (t.Item2, t.Item1, DirectionSet.Cartesian3d.Inverse(t.Item3)))) .Where(x => !hasPathTiles || pathTilesSet.Contains(((ModelTile)x.Item1.Value).Tile)) .ToLookup(x => x.Item1, x => x.Item3); // Extneral connections are valid exits only if the color in the center of the face matches var externalDirs = tilesByFaceDir .SelectMany(kv => kv.Value.Select(t => new { FaceDir = kv.Key, FaceDetails = t.Item1, Tile = t.Item2 })) .Where(x => !hasPathTiles || pathTilesSet.Contains(((ModelTile)x.Tile.Value).Tile)) .Where(x => colorSet.Contains(x.FaceDetails.center)) .ToLookup(x => x.Tile, x => x.FaceDir.ToDirection()); var exits = internalDirs.Select(x => x.Key).Union(externalDirs.Select(x => x.Key)) .ToDictionary(x => x, x => (ISet <Direction>) new HashSet <Direction>(internalDirs[x].Concat(externalDirs[x]))); return(new DeBroglie.Constraints.EdgedPathConstraint(exits)); } else if (hasPathTiles) { var actualPathTiles = new HashSet <Tile>(GetModelTiles(pathTiles).Select(x => new Tile(x))); return(new DeBroglie.Constraints.PathConstraint(actualPathTiles)); } else { throw new Exception("One of hasColors or hasPathTiles must be set for PathConstraints"); } }
public void TestRotationalAddAdjacencies() { var model = new AdjacentModel(DirectionSet.Cartesian2d); var tile1 = new Tile(1); var tile2 = new Tile(2); model.SetFrequency(tile1, 1); model.SetFrequency(tile2, 5); model.AddAdjacency(new[] { tile1 }, new[] { tile2 }, 1, 0, 0, new TileRotation(4, false)); var patternModel = model.GetTileModelMapping(new GridTopology(10, 10, false)).PatternModel; Assert.AreEqual(1, patternModel.Frequencies[0]); Assert.AreEqual(5, patternModel.Frequencies[1]); CollectionAssert.AreEquivalent(new[] { 1 }, patternModel.Propagator[0][0]); CollectionAssert.AreEquivalent(new[] { 1 }, patternModel.Propagator[0][1]); CollectionAssert.AreEquivalent(new[] { 1 }, patternModel.Propagator[0][2]); CollectionAssert.AreEquivalent(new[] { 1 }, patternModel.Propagator[0][3]); CollectionAssert.AreEquivalent(new[] { 0 }, patternModel.Propagator[1][0]); CollectionAssert.AreEquivalent(new[] { 0 }, patternModel.Propagator[1][1]); CollectionAssert.AreEquivalent(new[] { 0 }, patternModel.Propagator[1][2]); CollectionAssert.AreEquivalent(new[] { 0 }, patternModel.Propagator[1][3]); }
public void CountSetup() { var model = new AdjacentModel(DirectionSet.Cartesian2d); var tile1 = new Tile(1); var tile2 = new Tile(2); var tiles = new[] { tile1, tile2 }; model.AddAdjacency(tiles, tiles, Direction.XPlus); model.AddAdjacency(tiles, tiles, Direction.YPlus); model.SetUniformFrequency(); var topology = new GridTopology(100, 100, false); var count = 30; var options = new TilePropagatorOptions { Constraints = new[] { new CountConstraint { Tiles = new[] { tile1 }.ToHashSet(), Count = count, Comparison = CountComparison.AtMost, Eager = false, } } }; propagator6 = new TilePropagator(model, topology, options); }
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 void TestSimpleAddAdjacencies() { var model = new AdjacentModel(Directions.Cartesian2d); var tile1 = new Tile(1); var tile2 = new Tile(2); model.SetFrequency(tile1, 1); model.SetFrequency(tile2, 5); model.AddAdjacency(tile1, tile2, 1, 0, 0); model.AddAdjacency(tile1, tile2, 0, 1, 0); model.AddAdjacency(tile2, tile1, 1, 0, 0); model.AddAdjacency(tile2, tile1, 0, 1, 0); var patternModel = model.GetPatternModel(); Assert.AreEqual(1, patternModel.Frequencies[0]); Assert.AreEqual(5, patternModel.Frequencies[1]); CollectionAssert.AreEquivalent(new[] { 1 }, patternModel.Propagator[0][0]); CollectionAssert.AreEquivalent(new[] { 1 }, patternModel.Propagator[0][1]); CollectionAssert.AreEquivalent(new[] { 1 }, patternModel.Propagator[0][2]); CollectionAssert.AreEquivalent(new[] { 1 }, patternModel.Propagator[0][3]); CollectionAssert.AreEquivalent(new[] { 0 }, patternModel.Propagator[1][0]); CollectionAssert.AreEquivalent(new[] { 0 }, patternModel.Propagator[1][1]); CollectionAssert.AreEquivalent(new[] { 0 }, patternModel.Propagator[1][2]); CollectionAssert.AreEquivalent(new[] { 0 }, patternModel.Propagator[1][3]); }
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]); }
public void TestDirectionality() { var model = new AdjacentModel(DirectionSet.Cartesian2d); model.AddAdjacency(new Tile(1), new Tile(2), 1, 0, 0); model.SetUniformFrequency(); var topology = new Topology(2, 1, false); var up = Direction.YPlus; var down = Direction.YMinus; var edgedPathConstraint = new EdgedPathConstraint( new Dictionary <Tile, ISet <Direction> >() { { new Tile(1), new[] { up, down }.ToHashSet() }, { new Tile(2), new[] { up, down }.ToHashSet() }, } ); var propagator = new TilePropagator(model, topology, constraints: new[] { edgedPathConstraint }); propagator.Run(); Assert.AreEqual(Resolution.Contradiction, propagator.Status); }
public void Path2Setup() { var tileCount = 10; var topology = new GridTopology(20, 20, false); var model = new AdjacentModel(DirectionSet.Cartesian2d); var tiles = Enumerable.Range(0, tileCount).Select(x => new Tile(x)).ToList();; model.AddAdjacency(tiles, tiles, Direction.XPlus); model.AddAdjacency(tiles, tiles, Direction.YPlus); model.SetUniformFrequency(); var pathConstraint = new ConnectedConstraint { PathSpec = new PathSpec { Tiles = tiles.Skip(1).ToHashSet() } }; propagatorPath2 = new TilePropagator(model, topology, new TilePropagatorOptions { BackTrackDepth = -1, Constraints = new[] { pathConstraint }, }); }
public void TestDirectionality2() { var model = new AdjacentModel(DirectionSet.Cartesian2d); model.AddAdjacency(new Tile(1), new Tile(2), 1, 0, 0); model.SetUniformFrequency(); var topology = new GridTopology(2, 1, false); var left = Direction.XMinus; var right = Direction.XPlus; var constraint = new ConnectedConstraint { PathSpec = new EdgedPathSpec { Exits = new Dictionary <Tile, ISet <Direction> >() { { new Tile(1), new[] { left, right }.ToHashSet() }, { new Tile(2), new[] { left, right }.ToHashSet() }, } } }; var propagator = new TilePropagator(model, topology, constraints: new[] { constraint }); propagator.Run(); }
public void TestMask() { var a = new int[, ] { { 1, 0 }, { 0, 1 }, }; var model = new AdjacentModel(); model.AddSample(TopoArray.Create(a, true).ToTiles()); var mask = new bool[5 * 5]; for (var x = 0; x < 5; x++) { for (var y = 0; y < 5; y++) { if (x == 2 || y == 2) { mask[x + y * 5] = false; } else { mask[x + y * 5] = true; } } } var topology = new GridTopology(5, 5, true).WithMask(mask); var propagator = new TilePropagator(model, topology); propagator.Run(); Assert.AreEqual(Resolution.Decided, propagator.Status); }
public void QuickStartTest() { ITopoArray <char> sample = TopoArray.Create(new[, ] { { '_', '_', '_' }, { '_', '*', '_' }, { '_', '_', '_' }, }, periodic: false); // Specify the model used for generation var model = new AdjacentModel(sample.ToTiles()); // Set the output dimensions var topology = new Topology(10, 10, periodic: false); // Actually run the algorithm var propagator = new TilePropagator(model, topology); var status = propagator.Run(); if (status != Resolution.Decided) { throw new Exception("Undecided"); } var output = propagator.ToValueArray <char>(); // Display the results for (var y = 0; y < 10; y++) { for (var x = 0; x < 10; x++) { System.Console.Write(output.Get(x, y)); } System.Console.WriteLine(); } }
public void TestBannedSelected() { var a = new int[, ] { { 1, 2, 3 }, { 3, 1, 2 }, { 2, 3, 1 }, }; var model = AdjacentModel.Create(a, true); var topology = new GridTopology(10, 10, false); var propagator = new TilePropagator(model, topology); var tile1 = new Tile(1); var set1 = propagator.CreateTileSet(new[] { new Tile(1) }); var set12 = propagator.CreateTileSet(new[] { new Tile(1), new Tile(2) }); { propagator.GetBannedSelected(0, 0, 0, tile1, out var isBanned1, out var isSelected1); propagator.GetBannedSelected(0, 0, 0, set1, out var isBanned2, out var isSelected2); propagator.GetBannedSelected(0, 0, 0, set12, out var isBanned3, out var isSelected3); Assert.AreEqual(false, isBanned1); Assert.AreEqual(false, isBanned2); Assert.AreEqual(false, isBanned3); Assert.AreEqual(false, isSelected1); Assert.AreEqual(false, isSelected2); Assert.AreEqual(false, isSelected3); } propagator.Ban(0, 0, 0, new Tile(3)); { propagator.GetBannedSelected(0, 0, 0, tile1, out var isBanned1, out var isSelected1); propagator.GetBannedSelected(0, 0, 0, set1, out var isBanned2, out var isSelected2); propagator.GetBannedSelected(0, 0, 0, set12, out var isBanned3, out var isSelected3); Assert.AreEqual(false, isBanned1); Assert.AreEqual(false, isBanned2); Assert.AreEqual(false, isBanned3); Assert.AreEqual(false, isSelected1); Assert.AreEqual(false, isSelected2); Assert.AreEqual(true, isSelected3); } propagator.Ban(0, 0, 0, new Tile(1)); { propagator.GetBannedSelected(0, 0, 0, tile1, out var isBanned1, out var isSelected1); propagator.GetBannedSelected(0, 0, 0, set1, out var isBanned2, out var isSelected2); propagator.GetBannedSelected(0, 0, 0, set12, out var isBanned3, out var isSelected3); Assert.AreEqual(true, isBanned1); Assert.AreEqual(true, isBanned2); Assert.AreEqual(false, isBanned3); Assert.AreEqual(false, isSelected1); Assert.AreEqual(false, isSelected2); Assert.AreEqual(true, isSelected3); } }
public void TestLargeSeparationConstraint() { var model = new AdjacentModel(DirectionSet.Cartesian2d); var tile1 = new Tile(1); var tile2 = new Tile(2); var tiles = new[] { tile1, tile2 }; model.AddAdjacency(tiles, tiles, Direction.XPlus); model.AddAdjacency(tiles, tiles, Direction.YPlus); model.SetUniformFrequency(); var separationConstraint = new SeparationConstraint { Tiles = new[] { tile1 }.ToHashSet(), MinDistance = 10, }; var topology = new GridTopology(100, 100, false); var options = new TilePropagatorOptions { Constraints = new ITileConstraint[] { separationConstraint }, BacktrackType = BacktrackType.Backtrack, }; var propagator = new TilePropagator(model, topology, options); propagator.Run(); Assert.AreEqual(Resolution.Decided, propagator.Status); var r = propagator.ToArray(); for (var x = 0; x < 100; x++) { for (var y = 0; y < 100; y++) { if (r.Get(x, y) != tile1) { continue; } for (var dx = -1; dx <= 1; dx += 2) { for (var dy = -1; dy <= 1; dy += 2) { var x2 = x + dx; var y2 = y + dy; if (x2 >= 0 && x2 < 100 && y2 >= 0 && y2 < 100) { Assert.AreNotEqual(r.Get(x2, y2), tile1); } } } } } }
internal TesseraGeneratorHelper CreateTesseraGeneratorHelper(TesseraGenerateOptions options = null) { options = options ?? new TesseraGenerateOptions(); var progress = options.progress; var seed = options.seed == 0 ? UnityEngine.Random.Range(int.MinValue, int.MaxValue) : options.seed; var xororng = new XoRoRNG(seed); Validate(); TesseraGeneratorHelper.SetupModelFromTiles(tiles, out var allTiles, out var internalAdjacencies, out var tilesByFaceDir); var model = new AdjacentModel(DirectionSet.Cartesian3d); foreach (var(tile, frequency) in allTiles) { model.SetFrequency(tile, frequency); } foreach (var(tile1, tile2, d) in internalAdjacencies) { model.AddAdjacency(tile1, tile2, d); } // Generate adjacencies AddAdjacency(palette, model, Direction.XPlus, tilesByFaceDir[FaceDir.Right], tilesByFaceDir[FaceDir.Left]); AddAdjacency(palette, model, Direction.YPlus, tilesByFaceDir[FaceDir.Up], tilesByFaceDir[FaceDir.Down]); AddAdjacency(palette, model, Direction.ZPlus, tilesByFaceDir[FaceDir.Forward], tilesByFaceDir[FaceDir.Back]); var initialConstraints = searchInitialConstraints ? GetInitialConstraints() : this.initialConstraints; var constraints = GetTileConstraints(model); var actualSkyBox = skyBox == null ? null : new TesseraInitialConstraint { faceDetails = skyBox.faceDetails, offsets = skyBox.offsets, }; return(new TesseraGeneratorHelper( palette, model, allTiles, initialConstraints, constraints, tilesByFaceDir, size, backtrack, actualSkyBox, progress, null, xororng, options.cancellationToken)); }
public void TestPriority() { var t1 = new Tile(1); var t2 = new Tile(2); var t3 = new Tile(3); var model = new AdjacentModel(DirectionSet.Cartesian2d); model.AddAdjacency(t1, t1, Direction.XPlus); model.AddAdjacency(t1, t2, Direction.XPlus); model.AddAdjacency(t2, t2, Direction.XPlus); model.AddAdjacency(t2, t3, Direction.XPlus); model.AddAdjacency(t3, t3, Direction.XPlus); model.SetUniformFrequency(); var topology = new GridTopology(6, 1, false).WithMask(new bool[] { true, true, true, true, true, false }); IDictionary <Tile, PriorityAndWeight> weights = new Dictionary <Tile, PriorityAndWeight> { { t1, new PriorityAndWeight { Priority = 0, Weight = 1 } }, { t2, new PriorityAndWeight { Priority = 1, Weight = 1 } }, { t3, new PriorityAndWeight { Priority = 2, Weight = 1 } }, }; var weightsArray = TopoArray.CreateByIndex(_ => weights, topology); var propagator = new TilePropagator(model, topology, new TilePropagatorOptions { IndexPickerType = IndexPickerType.ArrayPriorityMinEntropy, WeightSetByIndex = TopoArray.CreateByIndex(_ => 0, topology), WeightSets = new Dictionary <int, IDictionary <Tile, PriorityAndWeight> > { { 0, weights } }, }); propagator.Select(0, 0, 0, t1); propagator.Run(); Assert.AreEqual(Resolution.Decided, propagator.Status); var r = propagator.ToValueArray <int>(); Assert.AreEqual(1, r.Get(0, 0)); Assert.AreEqual(2, r.Get(1, 0)); Assert.AreEqual(3, r.Get(2, 0)); Assert.AreEqual(3, r.Get(3, 0)); }
/// <summary> /// Converts generator constraints into a format suitable for DeBroglie. /// </summary> private List <ITileConstraint> GetTileConstraints(AdjacentModel model) { var l = new List <ITileConstraint>(); foreach (var constraintComponent in GetComponents <TesseraConstraint>()) { var constraint = constraintComponent.GetTileConstraint(model); l.Add(constraint); } return(l); }
public void TestSetFrequency() { var model = new AdjacentModel(DirectionSet.Cartesian2d); model.SetFrequency(new Tile(1), 0.5); model.SetFrequency(new Tile(2), 2.0); var patternModel = model.GetTileModelMapping(new GridTopology(10, 10, false)).PatternModel; Assert.AreEqual(0.5, patternModel.Frequencies[0]); Assert.AreEqual(2.0, patternModel.Frequencies[1]); }
public void TestSetFrequency() { var model = new AdjacentModel(Directions.Cartesian2d); model.SetFrequency(new Tile(1), 0.5); model.SetFrequency(new Tile(2), 2.0); var patternModel = model.GetPatternModel(); Assert.AreEqual(0.5, patternModel.Frequencies[0]); Assert.AreEqual(2.0, patternModel.Frequencies[1]); }
public void WangSetup() { // Reproduces the wang tiles found at // https://en.wikipedia.org/wiki/Wang_tile // They only have aperiodic tiling, so they are a hard set to put down. // Clockwise from top var tileBorders = new[] { "rrrg", "brbg", "rggg", "wbrb", "bbwb", "wwrw", "rgbw", "bwbr", "brwr", "ggbr", "rwrg", }; var model = new AdjacentModel(DirectionSet.Cartesian2d); for (var tile1 = 0; tile1 < tileBorders.Length; tile1++) { var tile1Border = tileBorders[tile1]; for (var i = 0; i < 4; i++) { var d = new[] { 3, 0, 2, 1 }[i]; var o = (i + 2) % 4; for (var tile2 = 0; tile2 < tileBorders.Length; tile2++) { var tile2Border = tileBorders[tile2]; if (tile2Border[o] != tile1Border[i]) { continue; } model.AddAdjacency(new Tile(tile1), new Tile(tile2), (Direction)d); } } } model.SetUniformFrequency(); var topology = new GridTopology(15, 15, false); var options = new TilePropagatorOptions { BackTrackDepth = -1, }; propagatorWang = new TilePropagator(model, topology, options); }
public void TestCountConstraint(CountComparison comparison, bool eager) { var model = new AdjacentModel(DirectionSet.Cartesian2d); var tile1 = new Tile(1); var tile2 = new Tile(2); var tiles = new[] { tile1, tile2 }; model.AddAdjacency(tiles, tiles, Direction.XPlus); model.AddAdjacency(tiles, tiles, Direction.YPlus); model.SetUniformFrequency(); var topology = new GridTopology(10, 10, false); var count = 3; var options = new TilePropagatorOptions { Constraints = new[] { new CountConstraint { Tiles = new[] { tile1 }.ToHashSet(), Count = count, Comparison = comparison, Eager = eager, } } }; var propagator = new TilePropagator(model, topology, options); propagator.Run(); Assert.AreEqual(Resolution.Decided, propagator.Status); var actualCount = propagator.ToValueArray <int>().ToArray2d().OfType <int>().Count(x => x == 1); switch (comparison) { case CountComparison.AtMost: Assert.LessOrEqual(actualCount, count); break; case CountComparison.AtLeast: Assert.GreaterOrEqual(actualCount, count); break; case CountComparison.Exactly: Assert.AreEqual(count, actualCount); break; } }
internal override ITileConstraint GetTileConstraint(AdjacentModel model) { // Filter big tiles to just a single model tile to avoid double counting var modelTiles = GetModelTiles(tiles) .Where(x => x.Offset == x.Tile.offsets[0]) .Select(x => new Tile(x)); return(new DeBroglie.Constraints.CountConstraint { Tiles = new HashSet <Tile>(modelTiles), Comparison = comparison, Count = count, Eager = eager, }); }
public TileModel BuildModel() { TileModel model = null; switch (Type) { case ModelType.Adjacent: model = new AdjacentModel(); break; case ModelType.Overlapping: model = new OverlappingModel(3); break; } return(model); }
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); }
public void TestSeparationConstraint() { var model = new AdjacentModel(DirectionSet.Cartesian2d); var tile1 = new Tile(1); var tile2 = new Tile(2); var tiles = new[] { tile1, tile2 }; model.AddAdjacency(tiles, tiles, Direction.XPlus); model.AddAdjacency(tiles, tiles, Direction.YPlus); model.SetUniformFrequency(); var separationConstraint = new SeparationConstraint { Tiles = new[] { tile1 }.ToHashSet(), MinDistance = 3, }; var countConstraint = new CountConstraint { Tiles = new[] { tile1 }.ToHashSet(), Count = 2, Comparison = CountComparison.Exactly, }; var topology = new GridTopology(4, 1, false); var options = new TilePropagatorOptions { Constraints = new ITileConstraint[] { separationConstraint, countConstraint }, BacktrackType = BacktrackType.Backtrack, }; var propagator = new TilePropagator(model, topology, options); propagator.Run(); Assert.AreEqual(Resolution.Decided, propagator.Status); var r = propagator.ToArray(); // Only possible solution given the constraints Assert.AreEqual(tile1, r.Get(0)); Assert.AreEqual(tile2, r.Get(1)); Assert.AreEqual(tile2, r.Get(2)); Assert.AreEqual(tile1, r.Get(3)); }
public void FreeSetup() { var tileCount = 10; var topology = new GridTopology(10, 10, 10, false); var model = new AdjacentModel(DirectionSet.Cartesian3d); var tiles = Enumerable.Range(0, tileCount).Select(x => new Tile(x)).ToList();; model.AddAdjacency(tiles, tiles, Direction.XPlus); model.AddAdjacency(tiles, tiles, Direction.YPlus); model.AddAdjacency(tiles, tiles, Direction.ZPlus); model.SetUniformFrequency(); propagator1 = new TilePropagator(model, topology, new TilePropagatorOptions { }); }
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(), }); }
public void TestDoubleCountConstraint() { var model = new AdjacentModel(DirectionSet.Cartesian2d); var tile1 = new Tile(1); var tile2 = new Tile(2); var tile3 = new Tile(3); var tiles = new[] { tile1, tile2, tile3 }; model.AddAdjacency(new[] { tile2 }, new[] { tile1 }, Direction.XPlus); model.AddAdjacency(new[] { tile1 }, new[] { tile3 }, Direction.XPlus); model.AddAdjacency(new[] { tile3 }, new[] { tile3 }, Direction.XPlus); model.AddAdjacency(new[] { tile3 }, new[] { tile2 }, Direction.XPlus); model.AddAdjacency(tiles, tiles, Direction.YPlus); model.SetUniformFrequency(); var topology = new GridTopology(10, 10, false); var count = 10; var options = new TilePropagatorOptions { Constraints = new[] { new CountConstraint { Tiles = new[] { tile1, tile2 }.ToHashSet(), Count = count, Comparison = CountComparison.Exactly, Eager = true, } } }; var propagator = new TilePropagator(model, topology, options); propagator.Run(); Assert.AreEqual(Resolution.Decided, propagator.Status); var actualCount = propagator.ToValueArray <int>().ToArray2d().OfType <int>().Count(x => x == 1 || x == 2); Assert.AreEqual(count, actualCount); }
public void TestDirtyIndexPicker() { var t1 = new Tile(1); var t2 = new Tile(2); var t3 = new Tile(3); var model = new AdjacentModel(DirectionSet.Cartesian2d); model.AddAdjacency(t1, t1, Direction.XPlus); model.AddAdjacency(t1, t2, Direction.XPlus); model.AddAdjacency(t2, t2, Direction.XPlus); model.AddAdjacency(t2, t3, Direction.XPlus); model.AddAdjacency(t3, t3, Direction.XPlus); model.AddAdjacency(t3, t2, Direction.XPlus); model.AddAdjacency(t2, t1, Direction.XPlus); model.SetUniformFrequency(); var topology = new GridTopology(6, 1, false); var options = new TilePropagatorOptions { IndexPickerType = IndexPickerType.Dirty, TilePickerType = TilePickerType.Ordered, CleanTiles = TopoArray.FromConstant(t1, topology), }; var propagator = new TilePropagator(model, topology, options); propagator.Select(3, 0, 0, t3); propagator.Run(); var a = propagator.ToValueArray <int?>(); Assert.AreEqual(null, a.Get(0, 0)); Assert.AreEqual(null, a.Get(1, 0)); Assert.AreEqual(2, a.Get(2, 0)); Assert.AreEqual(3, a.Get(3, 0)); Assert.AreEqual(2, a.Get(4, 0)); Assert.AreEqual(null, a.Get(5, 0)); }