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); }
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); }