//Pathfinding search static bool Search(HexCell fromCell, HexCell toCell, HexUnit unit) { searchFrontierPhase += 2; if (searchFrontier == null) { searchFrontier = new HexCellPriorityQueue(); } else { searchFrontier.Clear(); } fromCell.SearchPhase = searchFrontierPhase; fromCell.MovementCost = 0; searchFrontier.Enqueue(fromCell); while (searchFrontier.Count > 0) { HexCell current = searchFrontier.Dequeue(); current.SearchPhase += 1; if (current == toCell) { return(true); } int currentTurn = (current.MovementCost - 1) / unit.defaultMovementPoints; for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { HexCell neighbor = current.GetNeighbor(d); if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase) { continue; } //Hexes forbidden to move to if (!unit.CanEnter(neighbor)) { continue; } if (!neighbor.Traversable) { continue; } // int hexEnterCost = 0; //Special condition costs here hexEnterCost += neighbor.GetHexEnterMovementModifier(d, unit); //Default cost hexEnterCost += neighbor.IsOcean ? unit.oceanMovementCost : unit.landMovementCost; int combinedCost = current.MovementCost + hexEnterCost; int turn = (combinedCost - 1) / unit.defaultMovementPoints; if (turn > currentTurn) { combinedCost = turn * unit.defaultMovementPoints + hexEnterCost; } if (neighbor.SearchPhase < searchFrontierPhase) //Has not been set before { neighbor.SearchPhase = searchFrontierPhase; neighbor.MovementCost = combinedCost; neighbor.PathFrom = current; neighbor.SearchHeuristic = neighbor.coordinates.DistanceTo(toCell.coordinates); searchFrontier.Enqueue(neighbor); } else if (combinedCost < neighbor.MovementCost) //Update cost { int oldPriority = neighbor.SearchPriority; neighbor.MovementCost = combinedCost; neighbor.PathFrom = current; searchFrontier.Change(neighbor, oldPriority); } } } return(false); }
public static List <HexCell> GetAllReachableCells(HexCell fromCell, HexUnit unit) { ClearPath(); //New unit == Clear old pathfinding if (searcherUnit != unit) { unit.myGrid.ClearSearchHeuristics(); searchFrontierPhase = 0; searchFrontier = null; } searcherUnit = unit; List <HexCell> reachableCells = new List <HexCell>(); searchFrontierPhase += 2; if (searchFrontier == null) { searchFrontier = new HexCellPriorityQueue(); } else { searchFrontier.Clear(); } fromCell.SearchPhase = searchFrontierPhase; fromCell.MovementCost = 0; searchFrontier.Enqueue(fromCell); while (searchFrontier.Count > 0) { HexCell current = searchFrontier.Dequeue(); current.SearchPhase += 1; for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { HexCell neighbor = current.GetNeighbor(d); if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase) { continue; } //Hexes forbidden to move to if (!unit.CanEnter(neighbor)) { continue; } if (!neighbor.Traversable) { continue; } // int hexEnterCost = 0; //Special condition costs here hexEnterCost += neighbor.GetHexEnterMovementModifier(d, unit); //Default cost hexEnterCost += neighbor.IsOcean ? unit.oceanMovementCost : unit.landMovementCost; int combinedCost = current.MovementCost + hexEnterCost; if (neighbor.SearchPhase < searchFrontierPhase) //Has not been set before { neighbor.SearchPhase = searchFrontierPhase; neighbor.MovementCost = combinedCost; if (neighbor.MovementCost <= unit.remainingMovementPoints) { reachableCells.Add(neighbor); searchFrontier.Enqueue(neighbor); } } else if (combinedCost < neighbor.MovementCost) //Update cost { neighbor.MovementCost = combinedCost; } } } return(reachableCells); }