public void Init(TilePropagator propagator) { tileSet = propagator.CreateTileSet(Tiles); endPointTileSet = EndPointTiles != null?propagator.CreateTileSet(EndPointTiles) : null; graph = PathConstraintUtils.CreateGraph(propagator.Topology); }
public void Init(TilePropagator propagator) { pathTileSet = propagator.CreateTileSet(Exits.Keys); endPointTileSet = EndPointTiles != null?propagator.CreateTileSet(EndPointTiles) : null; graph = CreateEdgedGraph(propagator.Topology); var tileRotation = TileRotation ?? new TileRotation(); 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.Directions, d, rot)); } var rexits = new HashSet <Direction>(kv.Value.Select(Rotate)); actualExits[rtile] = rexits; } } } 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); }
public SelectedTracker(TilePropagator tilePropagator, WavePropagator wavePropagator, TileModelMapping tileModelMapping, TilePropagatorTileSet tileSet) { this.tilePropagator = tilePropagator; this.wavePropagator = wavePropagator; this.tileModelMapping = tileModelMapping; this.tileSet = tileSet; patternCounts = new int[tilePropagator.Topology.IndexCount]; }
internal SelectedChangeTracker(TilePropagator tilePropagator, WavePropagator wavePropagator, TileModelMapping tileModelMapping, TilePropagatorTileSet tileSet, IQuadstateChanged onChange) { this.tilePropagator = tilePropagator; this.wavePropagator = wavePropagator; this.tileModelMapping = tileModelMapping; this.tileSet = tileSet; this.onChange = onChange; patternCounts = new int[tilePropagator.Topology.IndexCount]; values = new Quadstate[tilePropagator.Topology.IndexCount]; }
public void Init(TilePropagator propagator) { if (propagator.Topology.Directions.Type != Topo.DirectionSetType.Cartesian2d && propagator.Topology.Directions.Type != Topo.DirectionSetType.Cartesian3d) { // This wouldn't be that hard to fix throw new Exception("MaxConsecutiveConstraint only supports cartesian topologies."); } tileSet = propagator.CreateTileSet(Tiles); }
public void Init(TilePropagator propagator) { var oddPathTiles = PathSpec.Exits.Where(x => x.Value.Count() % 2 == 1).Select(x => x.Key).ToList(); oddPathTilesSet = propagator.CreateTileSet(oddPathTiles); oddPathTracker = oddPathTiles.Count > 0 ? propagator.CreateSelectedTracker(oddPathTilesSet) : null; pathView = (EdgedPathView)PathSpec.MakeView(propagator); this.propagator = propagator; this.topology = propagator.Topology; }
public void Init(TilePropagator propagator) { var topology = propagator.Topology as GridTopology; if (topology == null || topology.Directions.Type != Topo.DirectionSetType.Cartesian2d && topology.Directions.Type != Topo.DirectionSetType.Cartesian3d) { // This wouldn't be that hard to fix throw new Exception("MaxConsecutiveConstraint only supports cartesian topologies."); } tileSet = propagator.CreateTileSet(Tiles); selectedTracker = propagator.CreateSelectedTracker(tileSet); }
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); }
public void Init(TilePropagator propagator) { tileset = propagator.CreateTileSet(Tiles); nearbyTracker = new NearbyTracker { MinDistance = MinDistance, Topology = propagator.Topology }; changeTracker = propagator.CreateSelectedChangeTracker(tileset, nearbyTracker); // Review the initial state foreach (var index in propagator.Topology.GetIndices()) { if (changeTracker.GetTristate(index).IsYes()) { nearbyTracker.VisitNearby(index, false); } } Check(propagator); }
public Point GetRandomPoint(TilePropagator propagator, TilePropagatorTileSet tileSet) { var topology = propagator.Topology; var points = new List <Point>(); for (var z = 0; z < topology.Depth; z++) { for (var y = 0; y < topology.Height; y++) { for (var x = 0; x < topology.Width; x++) { if (topology.Mask != null) { var index = topology.GetIndex(x, y, z); if (!topology.Mask[index]) { continue; } } propagator.GetBannedSelected(x, y, z, tileSet, out var isBanned, out var _); if (isBanned) { continue; } points.Add(new Point(x, y, z)); } } } // Choose a random point to select if (points.Count == 0) { throw new System.Exception($"No legal placement of {tileSet}"); } var i = (int)(propagator.RandomDouble() * points.Count); return(points[i]); }
public PathView(PathSpec spec, TilePropagator propagator) { if (spec.TileRotation != null) { tiles = new HashSet <Tile>(spec.TileRotation.RotateAll(spec.Tiles)); endPointTiles = spec.RelevantTiles == null ? null : new HashSet <Tile>(spec.TileRotation.RotateAll(spec.RelevantTiles)); } else { tiles = spec.Tiles; endPointTiles = spec.RelevantTiles; } tileSet = propagator.CreateTileSet(tiles); selectedTracker = propagator.CreateSelectedTracker(tileSet); Graph = PathConstraintUtils.CreateGraph(propagator.Topology); this.propagator = propagator; CouldBePath = new bool[propagator.Topology.IndexCount]; MustBePath = new bool[propagator.Topology.IndexCount]; hasEndPoints = spec.RelevantCells != null || spec.RelevantTiles != null; if (hasEndPoints) { CouldBeRelevant = new bool[propagator.Topology.IndexCount]; MustBeRelevant = new bool[propagator.Topology.IndexCount]; endPointIndices = spec.RelevantCells == null ? null : spec.RelevantCells.Select(p => propagator.Topology.GetIndex(p.X, p.Y, p.Z)).ToList(); endPointTileSet = spec.RelevantTiles != null?propagator.CreateTileSet(endPointTiles) : null; endPointSelectedTracker = spec.RelevantTiles != null?propagator.CreateSelectedTracker(endPointTileSet) : null; } else { CouldBeRelevant = CouldBePath; MustBeRelevant = MustBePath; endPointTileSet = tileSet; } }
public void Init(TilePropagator propagator) { ISet <Tile> actualTiles; ISet <Tile> actualEndPointTiles; if (TileRotation != null) { actualTiles = new HashSet <Tile>(TileRotation.RotateAll(Tiles)); actualEndPointTiles = EndPointTiles == null ? null : new HashSet <Tile>(TileRotation.RotateAll(EndPointTiles)); } else { actualTiles = Tiles; actualEndPointTiles = EndPointTiles; } tileSet = propagator.CreateTileSet(actualTiles); selectedTracker = propagator.CreateSelectedTracker(tileSet); endPointTileSet = EndPointTiles != null?propagator.CreateTileSet(actualEndPointTiles) : null; endPointSelectedTracker = EndPointTiles != null?propagator.CreateSelectedTracker(endPointTileSet) : null; graph = PathConstraintUtils.CreateGraph(propagator.Topology); }
public void Init(TilePropagator propagator) { tileSet = propagator.CreateTileSet(Tiles); countTracker = new CountTracker(propagator.Topology); selectedChangeTracker = propagator.CreateSelectedChangeTracker(tileSet, countTracker); if (Eager) { // Naive implementation /* * // Pick Count random indices * var topology = propagator.Topology; * var pickedIndices = new List<int>(); * var remainingIndices = new List<int>(topology.Indicies); * for (var c = 0; c < Count; c++) * { * var pickedIndexIndex = (int)(propagator.RandomDouble() * remainingIndices.Count); * pickedIndices.Add(remainingIndices[pickedIndexIndex]); * remainingIndices[pickedIndexIndex] = remainingIndices[remainingIndices.Count - 1]; * remainingIndices.RemoveAt(remainingIndices.Count - 1); * } * // Ban or select tiles to ensure an appropriate count * if(Comparison == CountComparison.AtMost || Comparison == CountComparison.Exactly) * { * foreach (var i in remainingIndices) * { * topology.GetCoord(i, out var x, out var y, out var z); * propagator.Ban(x, y, z, tileSet); * } * } * if (Comparison == CountComparison.AtLeast || Comparison == CountComparison.Exactly) * { * foreach (var i in pickedIndices) * { * topology.GetCoord(i, out var x, out var y, out var z); * propagator.Select(x, y, z, tileSet); * } * } */ var topology = propagator.Topology; var width = topology.Width; var height = topology.Height; var depth = topology.Depth; var pickedIndices = new List <int>(); var remainingIndices = new List <int>(topology.GetIndices()); while (true) { var noCount = 0; var yesCount = 0; var maybeList = new List <int>(); for (var z = 0; z < depth; z++) { for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var index = topology.GetIndex(x, y, z); if (topology.ContainsIndex(index)) { var selected = selectedChangeTracker.GetQuadstate(index); if (selected.IsNo()) { noCount++; } if (selected.IsMaybe()) { maybeList.Add(index); } if (selected.IsYes()) { yesCount++; } } } } } var maybeCount = maybeList.Count; if (Comparison == CountComparison.AtMost) { if (yesCount > Count) { // Already got too many, just fail propagator.SetContradiction(); return; } if (yesCount == Count) { // We've reached the limit, ban any more and exit Check(propagator); return; } var pickedIndex = maybeList[(int)(propagator.RandomDouble() * maybeList.Count)]; topology.GetCoord(pickedIndex, out var x, out var y, out var z); propagator.Select(x, y, z, tileSet); } else if (Comparison == CountComparison.AtLeast || Comparison == CountComparison.Exactly) { if (yesCount + maybeCount < Count) { // Already got too few, just fail propagator.SetContradiction(); return; } if (yesCount + maybeCount == Count) { // We've reached the limit, ban any more and exit Check(propagator); return; } var pickedIndex = maybeList[(int)(propagator.RandomDouble() * maybeList.Count)]; topology.GetCoord(pickedIndex, out var x, out var y, out var z); propagator.Ban(x, y, z, tileSet); } } } }
public EdgedPathView(EdgedPathSpec spec, TilePropagator propagator) { if (spec.TileRotation != null) { exits = new Dictionary <Tile, ISet <Direction> >(); foreach (var kv in spec.Exits) { foreach (var rot in spec.TileRotation.RotationGroup) { if (spec.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)); exits[rtile] = rexits; } } } endPointTiles = spec.RelevantTiles == null ? null : new HashSet <Tile>(spec.TileRotation.RotateAll(spec.RelevantTiles)); } else { exits = spec.Exits; endPointTiles = spec.RelevantTiles; } pathTileSet = propagator.CreateTileSet(exits.Keys); pathSelectedTracker = propagator.CreateSelectedTracker(pathTileSet); Graph = CreateEdgedGraph(propagator.Topology); this.propagator = propagator; this.topology = propagator.Topology; var nodesPerIndex = GetNodesPerIndex(); CouldBePath = new bool[propagator.Topology.IndexCount * nodesPerIndex]; MustBePath = new bool[propagator.Topology.IndexCount * nodesPerIndex]; tileSetByExit = exits .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 = tileSetByExit .ToDictionary(kv => kv.Key, kv => propagator.CreateSelectedTracker(kv.Value)); hasEndPoints = spec.RelevantCells != null || spec.RelevantTiles != null; if (hasEndPoints) { CouldBeRelevant = new bool[propagator.Topology.IndexCount * nodesPerIndex]; MustBeRelevant = new bool[propagator.Topology.IndexCount * nodesPerIndex]; endPointIndices = spec.RelevantCells == null ? null : spec.RelevantCells.Select(p => propagator.Topology.GetIndex(p.X, p.Y, p.Z)).ToList(); endPointTileSet = endPointTiles != null?propagator.CreateTileSet(endPointTiles) : null; endPointSelectedTracker = endPointTiles != null?propagator.CreateSelectedTracker(endPointTileSet) : null; } else { CouldBeRelevant = CouldBePath; MustBeRelevant = MustBePath; endPointTileSet = pathTileSet; } }
public void Init(TilePropagator propagator) { tileSet = propagator.CreateTileSet(Tiles); graph = PathConstraintUtils.CreateGraph(propagator.Topology); }