public FollowPathHeuristic(
     IFilteredIndexPicker filteredIndexPicker,
     TilePropagator propagator,
     EdgedPathSpec edgedPathSpec)
 {
     this.filteredIndexPicker = filteredIndexPicker;
     this.propagator          = propagator;
     this.edgedPathSpec       = edgedPathSpec;
 }
Пример #2
0
 public void Init(TilePropagator propagator)
 {
     if (PathSpec is PathSpec pathSpec)
     {
         // Convert PathSpec to EdgedPathSpec
         // As we have a bug with PathSpec ignoring paths of length 2.
         // (probably should use bridge edges instead of articulation points)
         ISet <Direction> allDirections = new HashSet <Direction>(Enumerable.Range(0, propagator.Topology.DirectionsCount).Cast <Direction>());
         var edgedPathSpec = new EdgedPathSpec
         {
             Exits         = pathSpec.Tiles.ToDictionary(x => x, _ => allDirections),
             RelevantCells = pathSpec.RelevantCells,
             RelevantTiles = pathSpec.RelevantTiles,
             TileRotation  = pathSpec.TileRotation,
         };
         pathView = edgedPathSpec.MakeView(propagator);
     }
     else
     {
         pathView = PathSpec.MakeView(propagator);
     }
     pathView.Init();
 }
Пример #3
0
        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;
            }
        }