private int RaiseTerrain(int chunkSize, int budget, MapRegion region)
        {
            searchFrontierPhase++;

            var firstCell = GetRandomCell(region);

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

            var centre = firstCell.Coordinates;

            var rise = Random.value < HighRiseProbability ? 2 : 1;
            var size = 0;

            while (size < chunkSize && searchFrontier.Count > 0)
            {
                var current           = searchFrontier.Dequeue();
                var originalElevation = current.Elevation;
                var newElevation      = originalElevation + rise;

                if (newElevation > ElevationMaximum)
                {
                    continue; // skip high point and its neighbours, so we grow around peaks
                }
                current.Elevation = newElevation;
                if (originalElevation < WaterLevel && newElevation >= WaterLevel && --budget == 0)
                {
                    break;
                }
                size++;

                for (var d = HexDirection.NE; d <= HexDirection.NW; d++)
                {
                    var neighbour = current.GetNeighbour(d);
                    if (neighbour && neighbour.SearchPhase < searchFrontierPhase)
                    {
                        neighbour.SearchPhase     = searchFrontierPhase;
                        neighbour.Distance        = neighbour.Coordinates.DistanceTo(centre);
                        neighbour.SearchHeuristic = Random.value < JitterProbability ? 1 : 0;
                        searchFrontier.Enqueue(neighbour);
                    }
                }
            }
            searchFrontier.Clear();
            return(budget);
        }
Esempio n. 2
0
        private bool Search(HexCell fromCell, HexCell toCell, HexUnit unit)
        {
            searchFrontierPhase += 2;

            fromCell.Distance    = 0;
            fromCell.SearchPhase = searchFrontierPhase;

            if (searchFrontier == null)
            {
                searchFrontier = new HexCellPriorityQueue();
            }
            else
            {
                searchFrontier.Clear();
            }
            searchFrontier.Enqueue(fromCell);

            while (searchFrontier.Count > 0)
            {
                var current = searchFrontier.Dequeue();
                if (current == toCell)
                {
                    return(true);
                }

                current.SearchPhase++;
                var currentTurn = (current.Distance - 1) / unit.Speed;

                for (var d = HexDirection.NE; d <= HexDirection.NW; d++)
                {
                    var neighbour = current.Neighbours[(int)d];

                    if (neighbour == null || neighbour.SearchPhase > searchFrontierPhase)
                    {
                        continue;
                    }
                    if (!unit.IsValidDestination(neighbour))
                    {
                        continue;
                    }
                    var moveCost = unit.GetMoveCost(current, neighbour, d);
                    if (moveCost < 0)
                    {
                        continue;
                    }

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

                    if (neighbour.SearchPhase < searchFrontierPhase)
                    {
                        neighbour.SearchPhase     = searchFrontierPhase;
                        neighbour.Distance        = distance;
                        neighbour.PathFrom        = current;
                        neighbour.SearchHeuristic = neighbour.Coordinates.DistanceTo(toCell.Coordinates);
                        searchFrontier.Enqueue(neighbour);
                    }
                    else if (distance < neighbour.Distance)
                    {
                        var oldPriority = neighbour.SearchPriority;
                        neighbour.Distance = distance;
                        neighbour.PathFrom = current;
                        searchFrontier.Change(neighbour, oldPriority);
                    }
                }
            }

            return(false);
        }