/// <summary> /// Returns a UnitRange containing up to 3 lists of points: which squares the unit can move to, /// which squares the unit can attack, and which squares the unit can utility-ize. /// </summary> /// <param name="unit">The unit we are querying for</param> /// <param name="blockedSpaces">spaces the unit is not allowed to occupy (e.g. due to ally unit already being there)</param> /// <returns></returns> /// //TODO: Add this to a different class public UnitRange GetPathsForUnit(UnitEntity unit, Position unitPosition, List <Position> blockedSpaces) { UnitRange retRange = new UnitRange(); List <PathNode> unvisited = new List <PathNode>(); List <PathNode> accessible = new List <PathNode>(); //Step 1 //make a node for each tile within raw movement range. unvisited = GetUnvisitedTiles(unit.Move, unitPosition, unit.MoveCosts, unit.TeamID); //Step 2 //run Dijkstra's algorithm accessible = DijkstraPathfinder.CalculatePathDistance(unvisited, unitPosition.xPos, unitPosition.yPos); //Accessible now has only the squares which the unit can actually reach. //break them back into Tuples for the UnitRange HashSet <Position> validPositions = new HashSet <Position>(); foreach (PathNode node in accessible.Where(node => node.distance <= unit.Move)) { validPositions.Add(new Position(node.pos.xPos, node.pos.yPos)); } //blocked positions can be pathed through, but not ended in. //you can end in your own space though validPositions.RemoveWhere(s => blockedSpaces.Contains(s) && !(s.Equals(unitPosition))); //Item ranges HashSet <Position> attackRanges = unit.AllAttackRanges(); HashSet <Position> utilityRanges = unit.AllUtilityRanges(); HashSet <Position> attackablePositions = new HashSet <Position>(); HashSet <Position> utilityPositions = new HashSet <Position>(); foreach (Position pos in validPositions) { foreach (Position offset in attackRanges) { Position targetTile = new Position(pos.xPos + offset.xPos, pos.yPos + offset.yPos); if (targetTile.xPos >= 0 && targetTile.xPos < Width && targetTile.yPos >= 0 && targetTile.yPos < Height) { attackablePositions.Add(targetTile); } } foreach (Position offset in utilityRanges) { Position targetTile = new Position(pos.xPos + offset.xPos, pos.yPos + offset.yPos); if (targetTile.xPos >= 0 && targetTile.xPos < Width && targetTile.yPos >= 0 && targetTile.yPos < Height) { utilityPositions.Add(targetTile); } } } retRange.moveRange = validPositions; retRange.attackRange = attackablePositions; retRange.utilityRange = utilityPositions; return(retRange); }
/// <summary> /// Returns a UnitRange containing up to 3 lists of points: which squares the unit can move to, /// which squares the unit can attack, and which squares the unit can utility-ize. /// </summary> /// <param name="unit">The unit we are querying for</param> /// <param name="blockedSpaces">spaces the unit is not allowed to occupy (e.g. due to enemy unit already being there)</param> /// <returns></returns> /// //TODO: Add this to a different class public UnitRange GetPathsForUnit(UnitEntity unit, List <Position> blockedSpaces) { UnitRange retRange = new UnitRange(); //List<PathNode> unvisited = new List<PathNode>(); //List<PathNode> accessible = new List<PathNode>(); ////Step 1 ////make a node for each tile within raw movement range. //unvisited = GetUnvisitedTiles(unit.speed, unit.xPos, unit.yPos, unit.moveCosts); ////Step 2 ////run Dijkstra's algorithm //accessible = DijkstraPathfinder.CalculatePathDistance(unvisited, unit.xPos, unit.yPos); ////Accessible now has only the squares which the unit can actually reach. ////break them back into Tuples for the UnitRange //HashSet<Position> validPositions = new HashSet<Position>(); //foreach (PathNode node in accessible.Where(node => node.distance <= unit.speed)) //{ // validPositions.Add(new Position(node.pos.xPos, node.pos.yPos)); //} ////blocked positions can be pathed through, but not ended in //validPositions.RemoveWhere(s => blockedSpaces.Contains(s)); ////Item ranges //HashSet<Position> attackRanges = unit.AllAttackRanges(); //HashSet<Position> utilityRanges = unit.AllUtilityRanges(); //HashSet<Position> attackablePositions = new HashSet<Position>(); //HashSet<Position> utilityPositions = new HashSet<Position>(); //foreach (Position pos in validPositions) //{ // foreach (Position offset in attackRanges) // { // Position targetTile = new Position(pos.xPos + offset.xPos, pos.yPos + offset.yPos); // if (targetTile.xPos >= 0 && targetTile.xPos < Width && targetTile.yPos >= 0 && targetTile.yPos < Height) // { // attackablePositions.Add(targetTile); // } // } // foreach (Position offset in utilityRanges) // { // Position targetTile = new Position(pos.xPos + offset.xPos, pos.yPos + offset.yPos); // if (targetTile.xPos >= 0 && targetTile.xPos < Width && targetTile.yPos >= 0 && targetTile.yPos < Height) // { // utilityPositions.Add(targetTile); // } // } //} //retRange.moveRange = validPositions; //retRange.attackRange = attackablePositions; //retRange.utilityRange = utilityPositions; return(retRange); }