コード例 #1
0
        private int RaiseTerrain(int chunkSize, int budget, MapRegion region)
        {
            searchFrontierPhase += 1;
            HexCell firstCell = GetRandomCell(region);

            firstCell.SearchPhase     = searchFrontierPhase;
            firstCell.Distance        = 0;
            firstCell.SearchHeuristic = 0;
            searchFrontier.Enqueue(firstCell);
            HexCoordinates center = firstCell.coordinates;

            int rise = Random.value < highRiseProbability ? 2 : 1;
            int size = 0;

            while (size < chunkSize && searchFrontier.Count > 0)
            {
                HexCell current           = searchFrontier.Dequeue();
                int     originalElevation = current.Elevation;

                int newElevation = originalElevation + rise;
                if (newElevation > elevationMaximum)
                {
                    continue;
                }

                current.Elevation = newElevation;
                if (
                    originalElevation < waterLevel &&
                    newElevation >= waterLevel && --budget == 0
                    )
                {
                    break;
                }
                size += 1;

                for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
                {
                    HexCell neighbor = current.GetNeighbor(d);
                    if (neighbor && neighbor.SearchPhase < searchFrontierPhase)
                    {
                        neighbor.SearchPhase     = searchFrontierPhase;
                        neighbor.Distance        = neighbor.coordinates.DistanceTo(center);
                        neighbor.SearchHeuristic = Random.value < jitterProbability ? 1 : 0;
                        searchFrontier.Enqueue(neighbor);
                    }
                }
            }
            searchFrontier.Clear();

            return(budget);
        }
コード例 #2
0
        private bool Search(HexCell fromCell, HexCell toCell, HexUnit unit)
        {
            int speed = unit.Speed;

            searchFrontierPhase += 2;
            if (searchFrontier == null)
            {
                searchFrontier = new HexCellPriorityQueue();
            }
            else
            {
                searchFrontier.Clear();
            }

            fromCell.SearchPhase = searchFrontierPhase;
            fromCell.Distance    = 0;
            searchFrontier.Enqueue(fromCell);

            while (searchFrontier.Count > 0)
            {
                HexCell current = searchFrontier.Dequeue();
                current.SearchPhase += 1;

                if (current == toCell)
                {
                    return(true);
                }

                int currentTurn = (current.Distance - 1) / speed;
                for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
                {
                    HexCell neighbor = current.GetNeighbor(d);
                    if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                    {
                        continue;
                    }

                    if (!unit.IsValidDestination(neighbor))
                    {
                        continue;
                    }
                    int moveCost = unit.GetMoveCost(current, neighbor, d);
                    if (moveCost < 0)
                    {
                        continue;
                    }

                    int distance = current.Distance + moveCost;
                    int turn     = (distance - 1) / speed;
                    if (turn > currentTurn)
                    {
                        distance = turn * speed + moveCost;
                    }

                    if (neighbor.SearchPhase < searchFrontierPhase)
                    {
                        neighbor.SearchPhase     = searchFrontierPhase;
                        neighbor.Distance        = distance;
                        neighbor.PathFrom        = current;
                        neighbor.SearchHeuristic = neighbor.coordinates.DistanceTo(toCell.coordinates);
                        searchFrontier.Enqueue(neighbor);
                    }
                    else if (distance < neighbor.Distance)
                    {
                        int oldPriority = neighbor.SearchPriority;
                        neighbor.Distance = distance;
                        neighbor.PathFrom = current;
                        searchFrontier.Change(neighbor, oldPriority);
                    }
                }
            }
            return(false);
        }