예제 #1
0
        /// <summary>
        /// Returns a two dimensional grid where each field contains the distance from the start point (the empty field).
        /// </summary>
        /// <returns>The path.</returns>
        /// <param name="gameGrid">Game grid.</param>
        /// <param name="fromLocation">the location to start from.</param>
        /// <param name="currentActiveTreasure">The current active treasre can always be stepped onto.</param>
        public static Grid2D<int> PreparePathGrid(GameFieldGrid gameGrid, GridLocation fromLocation, TreasureType currentActiveTreasure)
        {
            if(gameGrid == null)
            {
                throw new ArgumentNullException ("gameGrid");
            }

            if(fromLocation == null)
            {
                throw new ArgumentNullException ("fromLocation");
            }

            // Create a grid as big as the game field. The content of each item is the distance from the staring point (the empty spot).
            var pathGrid = new Grid2D<int> (gameGrid.Rows, gameGrid.Columns, pathFindingMaxVal);

            // Use a Disjkstra algorithm to find a path from the empty spot to the current active treasure.
            // First, set the presumed target location to a distance of 0.
            pathGrid.SetItem (fromLocation, 0);

            // Start calculating distances.
            while(true)
            {
                // Set to true if at least one field was changed. If nothing is changed during one loop, we're done.
                bool gridChanged = false;

                // Loop all fields until each field contains a distance value.
                for (int row = 0; row < gameGrid.Rows; row++)
                {
                    for (int col = 0; col < gameGrid.Columns; col++)
                    {
                        // Distance is one more than it was at the current location. Set for the surrounding fields.
                        int newDistance = pathGrid.GetItem (row, col);
                        if(newDistance != pathFindingMaxVal)
                        {
                            newDistance++;
                        }

                        var checkLocations = AIHelpers.GetAccessibleAdjacentLocations(gameGrid, new GridLocation(row, col), currentActiveTreasure);
                        foreach(var checkLocation in checkLocations)
                        {
                            // Remember the distance to the start point.
                            int currentDistance = pathGrid.GetItem (checkLocation);
                            if(newDistance < currentDistance)
                            {
                                pathGrid.SetItem (checkLocation, newDistance);
                                gridChanged = true;
                            }
                        }
                    }
                }

                // Bail out of the algorithm if we visited all nodes.
                if(!gridChanged)
                {
                    break;
                }
            }
            return pathGrid;
        }