Example #1
0
        //TODO: @herman, check at the examples.
        /// <summary>
        /// Returns a list containing lines connected to the given points. A line is a list of points.
        /// Only returns correct results for square or hex grids.
        /// </summary>
        /// <example>
        /// <code>
        /// private bool IsSameColour(point1, point2)
        /// {
        ///         return grid[point1].Color == grid[point2].Color;
        /// }
        ///
        /// private SomeMethod()
        /// {
        ///         ...
        ///         var rays = GetConnectedRays&lt;ColourCell, PointyHexPoint, PointyHexNeighborIndex&gt;(
        ///             grid, point, IsSameColour);
        ///         ...
        /// }
        /// </code>
        /// You can of course also use a lambda expression, like this:
        /// <code>
        /// //The following code returns all lines that radiate from the given point
        /// GetConnectedRays&lt;ColourCell, PointyHexPoint, PointyHexNeighborIndex&gt;(
        ///         grid, point, (x, y) => grid[x].Color == grid[y].Color);
        /// </code>
        /// </example>
        /// <typeparam name="TPoint">The type of point of the grid that this algorithm takes.</typeparam>
        /// <param name="grid">Grid in which the calculations are made.</param>
        /// <param name="point">Point where the calculations start.</param>
        /// <param name="rayGenerators"></param> //TODO: Remove this argument? Make that as part of the rayGenerator?
        /// <param name="isNeighborsConnected">
        /// A functions that returns true or false, depending on whether
        /// two points can be considered connected when they are neighbors.For example, if you want
        /// rays of points that refer to cells of the same color, you can pass in a functions that
        /// compares the DefaultColors of cells.
        /// </param>
        public static IEnumerable <IEnumerable <TPoint> > GetConnectedRays <TPoint>(
            IImplicitShape <TPoint> grid,
            TPoint point,
            IEnumerable <IForwardMap <TPoint, TPoint> > rayGenerators,
            Func <TPoint, TPoint, bool> isNeighborsConnected)
        {
            var lines = new List <IEnumerable <TPoint> >();

            foreach (var rayGenertor in rayGenerators)
            {
                var line = new StructList <TPoint>();

                var rayEnd = point;

                while (grid.Contains(rayEnd) && isNeighborsConnected(point, rayEnd))
                {
                    line.Add(rayEnd);
                    rayEnd = rayGenertor.Forward(rayEnd);
                }

                if (line.Count > 1)
                {
                    lines.Add(line);
                }
            }

            return(lines);
        }
Example #2
0
        //TODO remove construction of list!
        /// <summary>
        /// It construct a list of Points that represent a path by using a Dictionary that hold the information from where the point came from.
        /// </summary>
        /// <typeparam name="TPoint">The type of the point.</typeparam>
        /// <param name="cameFrom">Dictionary holding the information from where the point came from.</param>
        /// <param name="currentNode">Node that start the path.</param>
        private static IList <TPoint> ReconstructPath <TPoint>(
            Dictionary <TPoint, TPoint> cameFrom,
            TPoint currentNode)
        {
            IList <TPoint> path = new StructList <TPoint>();

            ReconstructPath(cameFrom, currentNode, path);

            return(path);
        }
Example #3
0
        /// <summary>
        /// Gets the longest line of connected points that contains this point.
        /// <see cref="GetConnectedRays{TPoint}"/>
        /// </summary>
        /// <typeparam name="TPoint">The type of point of the grid that this algorithm takes.</typeparam>
        /// <param name="grid">Grid in which the calculations are made.</param>
        /// <param name="point">Point where the calculations start.</param>
        /// <param name="lineGenerators">List of line generators.</param> //TODO is Generator the right word?
        /// <param name="isNeighborsConnected">
        /// A functions that returns true or false, depending on whether
        /// two points can be considered connected when they are neighbors.For example, if you want
        /// rays of points that refer to cells of the same color, you can pass in a functions that
        /// compares the DefaultColors of cells.
        /// </param>
        public static IEnumerable <IEnumerable <TPoint> > GetConnectedLines <TPoint>(
            IImplicitShape <TPoint> grid,
            TPoint point,
            IEnumerable <IMap <TPoint, TPoint> > lineGenerators,
            Func <TPoint, TPoint, bool> isNeighborsConnected)
        {
            var lines = new List <IEnumerable <TPoint> >();

            foreach (var lineGenerator in lineGenerators)
            {
                var line = new StructList <TPoint>();
                var edge = point;

                //go forwards
                while (grid.Contains(edge) && isNeighborsConnected(point, edge))
                {
                    edge = lineGenerator.Forward(edge);
                }

                //TPoint oppositeNeighbor = point.MoveBy(direction.Negate());
                edge = lineGenerator.Reverse(edge);

                //go backwards
                while (grid.Contains(edge) && isNeighborsConnected(point, edge))
                {
                    line.Add(edge);
                    edge = lineGenerator.Reverse(edge);
                }

                if (line.Count > 1)
                {
                    lines.Add(line);
                }
            }

            return(lines);
        }
Example #4
0
        /// <summary>
        /// Gets all the points (and their costs) from a given point in a given range. This result is stored and returned
        /// in a dictionary.
        /// </summary>
        /// <typeparam name="TPoint">The type of the point used on the grid.</typeparam>
        /// <param name="grid">The grid used to make the calculations.</param>
        /// <param name="start">Point where the calculations will start.</param>
        /// <param name="getConnectedPoints">This function is used to get the connected points to a given point.</param>
        /// <param name="isAccessible">This function is used to know if a point is acessible within the grid.</param>
        /// <param name="getCellMoveCost">This function is used to get the movement cost from moving to a cell.</param>
        /// <param name="moveRange">Range of movement where make the calculations.</param>
        /// <returns></returns>
        public static Dictionary <TPoint, int> GetPointsInRangeCost <TPoint>(
            IGrid <TPoint> grid,
            TPoint start,
            Func <TPoint, IEnumerable <TPoint> > getConnectedPoints,
            Func <TPoint, bool> isAccessible,
            Func <TPoint, TPoint, int> getCellMoveCost,
            int moveRange)
        {
            // Nodes in range
            var closedSet   = new HashSet <TPoint>();
            var costToReach = new Dictionary <TPoint, int>();
            var openSet     = new StructList <TPoint> {
                start
            };

            // Cost from start along best known path up to current point
            var costToReachContains = grid.CloneStructure(false);

            costToReach[start] = 0;

            var currentNeighbors = new List <TPoint>();

            while (!openSet.IsEmpty())
            {
                // Process current node
                var current = FindNodeWithLowestScore(openSet, costToReach);
                openSet.Remove(current);

                closedSet.Add(current);

                CheckGridNeighbors(getConnectedPoints(current), grid, currentNeighbors);

                for (int i = 0; i < currentNeighbors.Count; i++)
                {
                    var neighbor = currentNeighbors[i];

                    if (!closedSet.Contains(neighbor) &&
                        !openSet.Contains(neighbor) &&
                        isAccessible(neighbor) &&
                        (costToReach[current] + getCellMoveCost(current, neighbor) <= moveRange)
                        )
                    {
                        // Cost of current node + neighbor's move cost
                        int newCost = costToReach[current] + getCellMoveCost(current, neighbor);

                        if (costToReachContains[neighbor])
                        {
                            if (costToReach[neighbor] > newCost)
                            {
                                costToReach[neighbor] = newCost;
                            }
                        }
                        else
                        {
                            costToReach[neighbor]         = newCost;
                            costToReachContains[neighbor] = true;
                        }

                        openSet.Add(neighbor);
                    }
                }
            }

            return(costToReach);
        }