public Dictionary <Direction, T> GetNeighbours(int x, int y, bool includeDiagonal = false)
        {
            var directions = Enum.GetValues(typeof(Direction));
            var neighbours = new Dictionary <Direction, T>();

            foreach (Direction dir in directions)
            {
                if (includeDiagonal || ((int)dir % 2) == 0)
                {
                    var(modX, modY) = DirectionHelper.StepInDirection(dir, x, y, 1);
                    neighbours.Add(dir, this[modX, modY]);
                }
            }
            return(neighbours);
        }
        public (int totalSteps, List <(T tile, int distance)> poi) FloodFillDistanceFinder(int xStart, int yStart, IEnumerable <T> pointsOfInterest)
        {
            var poi      = pointsOfInterest.ToHashSet();
            var poiFound = new List <(T, int)>();

            var frontier = new List <(int x, int y)> {
                (xStart, yStart)
            };
            var floodedGrid = new Grid <bool>(false, originAtBottom);

            floodedGrid[xStart, yStart] = true;

            int steps = 0;

            while (frontier.Any())
            {
                var nextFrontier = new List <(int x, int y)>();
                foreach ((int x, int y) in frontier)
                {
                    var neighbours      = GetNeighbours(x, y);
                    var floodNeighbours = floodedGrid.GetNeighbours(x, y);
                    foreach (var key in neighbours.Keys)
                    {
                        if (!floodNeighbours[key])
                        {
                            var neighbourCoords = DirectionHelper.StepInDirection(key, x, y, 1);
                            if (poi.Contains(neighbours[key]))
                            {
                                poiFound.Add((neighbours[key], steps + 1));
                            }
                            if (passableTerrain.Contains(neighbours[key]))
                            {
                                nextFrontier.Add(neighbourCoords);
                            }
                            floodedGrid[neighbourCoords.x, neighbourCoords.y] = true;
                        }
                    }
                }
                frontier = nextFrontier;
                steps++;
            }
            return(steps - 1, poiFound);
        }
        public Dictionary <Direction, T> GetNeighbours(int x, int y, bool includeDiagonal = false)
        {
            var directions = Enum.GetValues(typeof(Direction));
            var neighbours = new Dictionary <Direction, T>();

            foreach (Direction dir in directions)
            {
                if (includeDiagonal || ((int)dir % 2) == 0)
                {
                    var actualDirection = originAtBottom ? dir : dir.Opposite();
                    var(modX, modY) = DirectionHelper.StepInDirection(dir, x, y, 1);
                    if (modX >= 0 && modY >= 0 && modX < grid.GetLength(0) && modY < grid.GetLength(1))
                    {
                        neighbours.Add(actualDirection, grid[modX, modY]);
                    }
                    else
                    {
                        neighbours.Add(actualDirection, defaultTile); //Alternative: not adding to dictionary, downside, different behaviour from Grid
                    }
                }
            }
            return(neighbours);
        }