コード例 #1
0
 public Origin(PathPoint from, Tool tool, int distance)
 {
     From     = from;
     Tool     = tool;
     Distance = distance;
 }
コード例 #2
0
        private static Dictionary <Point, PathPoint> FindShortestPaths(RegionType[,] riskLevelMap, Point start)
        {
            // Dictionary with found paths
            Dictionary <Point, PathPoint> routes = riskLevelMap.ToQueryable((x, y, item) => new PathPoint()
            {
                Location     = new Point(x, y),
                RegionType   = riskLevelMap[y, x],
                ToolToOrigin = RegionToTools[riskLevelMap[y, x]].ToDictionary(z => z, z => new Origin(null, z, int.MaxValue - 10))
            }).ToDictionary(x => x.Location);

            // Set starting point
            routes[start].ToolToOrigin[Tool.Torch] = new Origin(null, Tool.Torch, 0);

            // Create process query
            Queue <PathPoint> toProcess = new Queue <PathPoint>();

            toProcess.Enqueue(routes[start]);

            // Faster search in toProcess
            HashSet <PathPoint> toProcessHash = new HashSet <PathPoint>()
            {
                toProcess.Single()
            };

            // Fast search for neighbours
            Dictionary <PathPoint, PathPoint[]> neigbours = routes.ToDictionary(x => x.Value, x => x.Value.Neighbours(routes).ToArray());

            // Main search loop
            while (toProcess.Any())
            {
                PathPoint currentPoint = toProcess.Dequeue();
                toProcessHash.Remove(currentPoint);

                // Examine all neighbours
                foreach (PathPoint neighbour in neigbours[currentPoint])
                {
                    // What if we didn't change the tool
                    foreach (Tool tool in currentPoint.ToolToOrigin.Keys.Intersect(RegionToTools[neighbour.RegionType]))
                    {
                        int newDistance = currentPoint.ToolToOrigin[tool].Distance + 1;
                        if (neighbour.ToolToOrigin[tool].Distance > newDistance)
                        {
                            neighbour.ToolToOrigin[tool] = new Origin(currentPoint, tool, newDistance);
                            if (!toProcessHash.Contains(neighbour))
                            {
                                toProcess.Enqueue(neighbour);
                                toProcessHash.Add(neighbour);
                            }
                        }
                    }

                    // Or we have to change the tool
                    foreach (Tool oldTool in currentPoint.ToolToOrigin.Keys.Except(RegionToTools[neighbour.RegionType]))
                    {
                        foreach (Tool newTool in RegionToTools[neighbour.RegionType])
                        {
                            int newDistance = currentPoint.ToolToOrigin[oldTool].Distance + 1 + 7;
                            if (neighbour.ToolToOrigin[newTool].Distance > newDistance)
                            {
                                neighbour.ToolToOrigin[newTool] = new Origin(currentPoint, newTool, newDistance);
                                if (!toProcessHash.Contains(neighbour))
                                {
                                    toProcess.Enqueue(neighbour);
                                    toProcessHash.Add(neighbour);
                                }
                            }
                        }
                    }
                }
            }

            return(routes);
        }