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 GridTopology(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 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 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 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 TestMaskWithOverlapping() { var a = new int[, ] { { 1, 0 }, { 0, 1 }, }; var model = OverlappingModel.Create(a, 2, false, 8); var mask = new bool[4 * 5]; for (var x = 0; x < 5; x++) { for (var y = 0; y < 4; y++) { if (x == 2 || x == 3) { mask[x + y * 5] = false; } else { mask[x + y * 5] = true; } } } var topology = new GridTopology(5, 4, false).WithMask(mask); var propagator = new TilePropagator(model, topology); propagator.Select(0, 0, 0, new Tile(1)); propagator.Select(4, 0, 0, new Tile(0)); propagator.Run(); Assert.AreEqual(Resolution.Decided, propagator.Status); }
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 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(); }
private static void PrintGridTopologies() { ConsoleWriter.Default.PrintCaption("GridTopology.GetGridTopologies()"); ConsoleNavigation.Default.PrintNavigation(GridTopology.GetGridTopologies(), (i, topology) => { ConsoleWriter.Default.WriteObject(topology, 3); }, "Select a grid topology to show additional information"); }
public TopoArray2D(T[,] values, bool periodic) { Topology = new GridTopology( values.GetLength(0), values.GetLength(1), periodic); this.values = values; }
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 TestBacktracking() { // 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 propagator = tileBorders.Select(tile1 => tile1.Select((c, i) => { var d = new[] { 3, 0, 2, 1 }[i]; var o = (i + 2) % 4; return(Tuple.Create(d, tileBorders .Select((tile2, i2) => Tuple.Create(tile2, i2)) .Where(t => t.Item1[o] == c) .Select(t => t.Item2) .ToArray())); }) .OrderBy(x => x.Item1) .Select(x => x.Item2) .ToArray() ).ToArray(); var model = new PatternModel { Frequencies = tileBorders.Select(x => 1.0).ToArray(), Propagator = propagator, }; var topology = new GridTopology(10, 10, false); var seed = Environment.TickCount; var r = new Random(seed); Console.WriteLine("Seed {0}", seed); var wavePropagator = new WavePropagator(model, topology, 10, randomDouble: r.NextDouble); var status = wavePropagator.Run(); Assert.AreEqual(Resolution.Decided, status); Console.WriteLine($"Backtrack Count {wavePropagator.BacktrackCount}"); }
/// <summary> /// Reads a layer of a Map into an <see cref="ITopoArray{T}"/> /// </summary> public static ITopoArray <Tile> ReadLayer(Map map, TileLayer layer) { if (map.Orientation == Orientation.orthogonal || map.Orientation == Orientation.isometric && map.StaggerAxis == StaggerAxis.None) { var layerArray = new Tile[layer.Width, layer.Height]; var i = 0; for (int y = 0; y < layer.Height; y++) { for (int x = 0; x < layer.Width; x++) { layerArray[x, y] = GidToTile(layer.Data[i++], map.Orientation); } } return(TopoArray.Create(layerArray, false)); } else if (map.Orientation == Orientation.hexagonal) { // Tiled uses a staggered hex layout, while we use an axial one // Convert between them, masking out the dead space // For now, only support one mode of staggering if (map.StaggerAxis != StaggerAxis.y) { throw new NotImplementedException($"Maps staggered on x axis not supported"); } var width = layer.Width + (layer.Height + 1) / 2; var height = layer.Height; var layerArray = new Tile[width, height]; var mask = new bool[width * height]; var topology = new GridTopology(DirectionSet.Hexagonal2d, width, height, false, false, mask); int i = 0; var isStaggered = map.StaggerIndex == StaggerIndex.even; var xoffset = isStaggered ? -1 : 0; for (int y = 0; y < layer.Height; y++) { if (isStaggered) { xoffset += 1; } for (int x = 0; x < layer.Width; x++) { var newY = y; var newX = x + xoffset; layerArray[newX, newY] = GidToTile(layer.Data[i++], Orientation.hexagonal); var index = topology.GetIndex(newX, newY, 0); mask[index] = true; } isStaggered = !isStaggered; } return(TopoArray.Create(layerArray, topology)); } else { throw new NotImplementedException($"{map.Orientation} not supported"); } }
// Inspired by Tessera's Castle scene public void CastleSetup() { var topology = new GridTopology(10, 10, 10, false); var model = CastleModel.Get(); propagator3 = new TilePropagator(model, topology, new TilePropagatorOptions { }); }
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); } } } } } }
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)); }
// ReSharper disable once ExcessiveIndentation public GridTopology ToGridTopology() { var gridTopology = new GridTopology(Rows, Columns, Displays.Select(display => display.ToGridTopologyDisplay()).ToArray()) { ApplyWithBezelCorrectedResolution = ApplyWithBezelCorrectedResolution, ImmersiveGaming = ImmersiveGaming, BaseMosaicPanoramic = BaseMosaicPanoramic, DriverReloadAllowed = DriverReloadAllowed, AcceleratePrimaryDisplay = AcceleratePrimaryDisplay }; IDisplaySettings bestDisplaySettings = null; foreach (var displaySetting in gridTopology.GetPossibleDisplaySettings()) { if (displaySetting.Width == Resolution.Width && displaySetting.Height == Resolution.Height) { if (displaySetting.BitsPerPixel == ColorDepth) { if (displaySetting.Frequency == Frequency) { bestDisplaySettings = displaySetting; break; } if (bestDisplaySettings == null || displaySetting.Frequency > bestDisplaySettings.Frequency) { bestDisplaySettings = displaySetting; } } else if (bestDisplaySettings == null || displaySetting.BitsPerPixel > bestDisplaySettings.BitsPerPixel) { bestDisplaySettings = displaySetting; } } else if (bestDisplaySettings == null || displaySetting.Width * displaySetting.Height > bestDisplaySettings.Width * bestDisplaySettings.Height) { bestDisplaySettings = displaySetting; } } if (bestDisplaySettings != null) { gridTopology.SetDisplaySettings(bestDisplaySettings); } return(gridTopology); }
public void TestChessboard(ModelConstraintAlgorithm algorithm) { var model = new PatternModel { Frequencies = new double[] { 1, 1 }, Propagator = new int[][][] { new int[][] { new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, }, new int[][] { new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, }, } }; var width = 10; var height = 10; var topology = new GridTopology(width, height, true); var options = new WavePropagatorOptions { ModelConstraintAlgorithm = algorithm }; var propagator = new WavePropagator(model, topology, options); var status = propagator.Run(); Assert.AreEqual(Resolution.Decided, status); var a = propagator.ToTopoArray().ToArray2d(); var topLeft = a[0, 0]; for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { Assert.IsTrue((a[x, y] == topLeft) ^ (x % 2 == 0) ^ (y % 2 == 0)); } } // Should be impossible with an odd sized region topology = new GridTopology(width + 1, height + 1, true); propagator = new WavePropagator(model, topology, options); status = propagator.Run(); Assert.AreEqual(Resolution.Contradiction, status); // Should be possible with an odd sized region, if we have the right mask var mask = new bool[(width + 1) * (height + 1)]; for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { mask[x + y * (width + 1)] = true; } } topology = new GridTopology(width + 1, height + 1, true).WithMask(mask); propagator = new WavePropagator(model, topology, options); status = propagator.Run(); Assert.AreEqual(Resolution.Decided, status); }
public static SurroundTopology FromPathTargetInfo(PathTargetInfo pathTargetInfo) { // We go through the code if only the path belongs to a NVIDIA virtual surround display if (pathTargetInfo.DisplayTarget.EDIDManufactureCode != "NVS") { return(null); } try { var correspondingWindowsPathInfo = PathInfo.GetAllPaths() .FirstOrDefault( info => info.TargetsInfo.Any( targetInfo => targetInfo.DisplayTarget == pathTargetInfo.DisplayTarget)); if (correspondingWindowsPathInfo != null) { // If position is same, then the two paths are equal, after all position is whats important in path sources var correspondingNvidiaPathInfo = NvAPIWrapper.Display.PathInfo.GetDisplaysConfig() .FirstOrDefault( info => (info.Position.X == correspondingWindowsPathInfo.Position.X) && (info.Position.Y == correspondingWindowsPathInfo.Position.Y) && (info.Resolution.Width == correspondingWindowsPathInfo.Resolution.Width) && (info.Resolution.Height == correspondingWindowsPathInfo.Resolution.Height)); if (correspondingNvidiaPathInfo != null) { // We now assume that there is only one target for a NVS path var correspondingNvidiaTargetInfo = correspondingNvidiaPathInfo.TargetsInfo.FirstOrDefault(); if (correspondingNvidiaTargetInfo != null) { var correspondingNvidiaTopology = GridTopology.GetGridTopologies() .FirstOrDefault( topology => topology.Displays.Select(display => display.DisplayDevice) .Contains(correspondingNvidiaTargetInfo.DisplayDevice)); if (correspondingNvidiaTopology != null) { return(new SurroundTopology(correspondingNvidiaTopology)); } } } } } catch { // ignored } return(null); }
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; } }
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 TestMemoizeIndices() { var model = new PatternModel { Frequencies = new double[] { 1, 1 }, // Free model Propagator = new int[][][] { new int[][] { new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, }, new int[][] { new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, new int[] { 0, 1 }, }, } }; var width = 10; var height = 10; var topology = new GridTopology(width, height, true); var indexPicker = new CustomIndexPicker(); var memoIndexPicker = new MemoizeIndexPicker(indexPicker); var options = new WavePropagatorOptions { BacktrackPolicy = new ConstantBacktrackPolicy(1), IndexPicker = memoIndexPicker, PatternPicker = new SimpleOrderedPatternPicker(), Constraints = new[] { new DontBanOneConstraint() }, }; var propagator = new WavePropagator(model, topology, options); // Attempts to pick pattern 0 at index 0, should contradict and backtrack var status = propagator.Step(); Assert.AreEqual(Resolution.Undecided, status); Assert.AreEqual(1, propagator.BacktrackCount); CollectionAssert.AreEqual(propagator.GetPossiblePatterns(0), new[] { 1 }); Assert.AreEqual(1, indexPicker.Count); // Should re-attempt index zero, with no effect. propagator.Step(); Assert.AreEqual(Resolution.Undecided, status); Assert.AreEqual(1, propagator.BacktrackCount); CollectionAssert.AreEqual(propagator.GetPossiblePatterns(0), new[] { 1 }); Assert.AreEqual(1, indexPicker.Count); // Attempts to pick pattern 0 at index 1, should contradict and backtrack propagator.Step(); Assert.AreEqual(Resolution.Undecided, status); Assert.AreEqual(2, propagator.BacktrackCount); CollectionAssert.AreEqual(propagator.GetPossiblePatterns(1), new[] { 1 }); Assert.AreEqual(2, indexPicker.Count); // etc }
public bool Apply() { try { Thread.Sleep(2000); try { var surroundTopologies = Paths.SelectMany(path => path.Targets) .Select(target => target.SurroundTopology) .Where(topology => topology != null) .Select(topology => topology.ToGridTopology()) .ToArray(); if (surroundTopologies.Length == 0) { var currentTopologies = GridTopology.GetGridTopologies(); if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1)) { surroundTopologies = GridTopology.GetGridTopologies() .SelectMany(topology => topology.Displays) .Select(displays => new GridTopology(1, 1, new[] { displays })) .ToArray(); } } if (surroundTopologies.Length > 0) { GridTopology.SetGridTopologies(surroundTopologies, SetDisplayTopologyFlag.MaximizePerformance); } } catch { // ignored } Thread.Sleep(19000); PathInfo.ApplyPathInfos(Paths.Select(path => path.ToPathInfo()), true, true); Thread.Sleep(9000); RefreshActiveStatus(); return(true); } catch { RefreshActiveStatus(); return(false); } }
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 TestParityConstraint() { var w = 10; var h = 10; var topology = new GridTopology(10, 10, false); var pathModel = new PathModel(forks: false); var constraint = new ParityConstraint { PathSpec = new EdgedPathSpec { Exits = pathModel.Exits }, }; var options = new TilePropagatorOptions { BackTrackDepth = -1, Constraints = new[] { constraint }, }; var propagator = new TilePropagator(pathModel.Model, topology, options); for (var x = 0; x < w; x++) { for (var y = 0; y < h; y++) { void Select(Tile t) => propagator.Select(x, y, 0, t); if (x == 0 && y == 1) { Select(pathModel.Straight2); continue; } if (x == 0 || y == 0 || x == w - 1 || y == h - 1) { Select(pathModel.Empty); } } } propagator.Step(); Assert.AreEqual(Resolution.Contradiction, propagator.Status); }
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 { }); }
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 TestChessboard3d(ModelConstraintAlgorithm algorithm) { var model = new PatternModel { Frequencies = new double[] { 1, 1 }, Propagator = new int[][][] { new int[][] { new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, }, new int[][] { new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, }, } }; var width = 4; var height = 4; var depth = 4; var topology = new GridTopology(width, height, depth, true); var options = new WavePropagatorOptions { ModelConstraintAlgorithm = algorithm }; var propagator = new WavePropagator(model, topology, options); var status = propagator.Run(); Assert.AreEqual(Resolution.Decided, status); var a = propagator.ToTopoArray(); var topLeft = a.Get(0, 0, 0); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { for (var z = 0; z < depth; z++) { Assert.IsFalse((a.Get(x, y, z) == topLeft) ^ (x % 2 == 0) ^ (y % 2 == 0) ^ (z % 2 == 0)); } } } // Should be impossible with an odd sized region topology = new GridTopology(width + 1, height + 1, depth + 1, true); propagator = new WavePropagator(model, topology, options); status = propagator.Run(); Assert.AreEqual(Resolution.Contradiction, status); }
public SurroundTopology(GridTopology topology) { Rows = topology.Rows; Columns = topology.Columns; Resolution = new Size(topology.Resolution.Width, topology.Resolution.Height); ColorDepth = topology.Resolution.ColorDepth; Frequency = topology.Frequency; Displays = topology.Displays.Where( display => Resolution.Width > display.Overlap.HorizontalOverlap && Resolution.Height > display.Overlap.VerticalOverlap) .Select(display => new SurroundTopologyDisplay(display)) .ToArray(); ApplyWithBezelCorrectedResolution = topology.ApplyWithBezelCorrectedResolution; ImmersiveGaming = topology.ImmersiveGaming; BaseMosaicPanoramic = topology.BaseMosaicPanoramic; DriverReloadAllowed = topology.DriverReloadAllowed; AcceleratePrimaryDisplay = topology.AcceleratePrimaryDisplay; }
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)); }