public List <PathNode> FindLinearPath(int startX, int startY, int endX, int endY, out float nodeCost) { nodeCost = 0f; if (!GridCoords.IsInGrid(startX, startY)) { return(null); } if (!GridCoords.IsInGrid(endX, endY)) { return(null); } PathNode startNode = grid[startX, startY].PathNode; PathNode endNode = grid[endX, endY].PathNode; // vertical if (startNode.x == endNode.x) { nodeCost = 1f; return(GetVerticalPath(startNode, endNode)); } // horizontal else if (startNode.y == endNode.y) { nodeCost = 1f; return(GetHorizontalPath(startNode, endNode)); } //else if (Mathf.Abs(startNode.x - endNode.x) == Mathf.Abs(startNode.y - endNode.y)) //{ // nodeCost = 1.4142f; // return GetDiagonalPath(startNode, endNode); //} return(null); }
public List <PathNode> FindPath(int startX, int startY, int endX, int endY, bool safePathOnly) { if (!GridCoords.IsInGrid(startX, startY)) { return(null); } if (!GridCoords.IsInGrid(endX, endY)) { return(null); } PathNode startNode = grid[startX, startY].PathNode; PathNode endNode = grid[endX, endY].PathNode; openList = new List <PathNode> { startNode }; closedList = new List <PathNode>(); for (int x = 0; x < currentGridInfo.gameGridSize.x; x++) { for (int y = 0; y < currentGridInfo.gameGridSize.y; y++) { PathNode pathNode = grid[x, y].PathNode; pathNode.gCost = int.MaxValue; pathNode.CalculateFCost(); pathNode.cameFromNode = null; } } startNode.gCost = 0; startNode.hCost = CalculateDistanceCost(startNode, endNode); startNode.CalculateFCost(); while (openList.Count > 0) { PathNode currentNode = GetLowestFCostNode(openList); if (currentNode == endNode) { return(CalculatePath(endNode)); } openList.Remove(currentNode); closedList.Add(currentNode); foreach (PathNode neighbourNode in GetValidNeighbourList(currentNode)) { if (closedList.Contains(neighbourNode)) { continue; } if (!neighbourNode.isTraversable) { closedList.Add(neighbourNode); continue; } else if (!neighbourNode.isSafe && safePathOnly) { closedList.Add(neighbourNode); continue; } int tentativeGCost = currentNode.gCost + CalculateDistanceCost(currentNode, neighbourNode); if (tentativeGCost < neighbourNode.gCost) { neighbourNode.cameFromNode = currentNode; neighbourNode.gCost = tentativeGCost; neighbourNode.hCost = CalculateDistanceCost(neighbourNode, endNode); neighbourNode.CalculateFCost(); if (!openList.Contains(neighbourNode)) { openList.Add(neighbourNode); } } } } // Out of nodes on the openList return(null); }
private void PlaceSingleShipOnMap(Ship ship) { List <GridTile> allCandidateTiles = new List <GridTile>(); List <GridTile> finalCandidates = new List <GridTile>(); int minShipHeat = int.MaxValue; foreach (var tile in GridCoords.CurrentGridInfo.gameGridTiles) { if (tile.tileType == 0) { allCandidateTiles.Add(tile); if (tile.ShipStartHeat < minShipHeat) { minShipHeat = tile.ShipStartHeat; } } } foreach (var sh in shipInventory) { if (sh == ship) { continue; } TileCoordinates shipPos = GridCoords.FromWorldToTilePosition(sh.transform.position); if (!GridCoords.IsInGrid(shipPos.tileX, shipPos.tileY)) { continue; } GridTile tileToRemove = GridCoords.CurrentGridInfo.gameGridTiles[shipPos.tileX, shipPos.tileY]; allCandidateTiles.Remove(tileToRemove); } int count = 0; foreach (var tile in allCandidateTiles) { if (tile.ShipStartHeat <= minShipHeat + 2) { finalCandidates.Add(tile); count++; } } int randomIndex = UnityEngine.Random.Range(0, count); Vector2 shipPosition = finalCandidates[randomIndex].TileCenter; TileCoordinates shipCoords = finalCandidates[randomIndex].TileCoordinates; ship.transform.position = shipPosition; // Add heat, one circle cast per heat distance for (int j = 1; j <= shipHeatDistance; j++) { float heatCastRadius = GridCoords.CurrentGridInfo.TileWidth * j; Collider2D[] allHits = Physics2D.OverlapCircleAll(shipPosition, heatCastRadius, tileLayerMask); foreach (var hit in allHits) { GridTile candidate = hit.GetComponent <GridTile>(); if (hit != null) { candidate.AddShipHeat(1); } } } foreach (var tile in allCandidateTiles) { // If same X if (tile.tileX == shipCoords.tileX) { // If not exact same tile if (tile.tileY != shipCoords.tileY) { // If neighbour if (tile.tileY == shipCoords.tileY - 1 || tile.tileY == shipCoords.tileY + 1) { tile.AddShipHeat(2); } // If other else { tile.AddShipHeat(2); } } } if (tile.tileY == shipCoords.tileY) { // If not exact same tile if (tile.tileX != shipCoords.tileX) { // If neighbour if (tile.tileX == shipCoords.tileX - 1 || tile.tileX == shipCoords.tileX + 1) { tile.AddShipHeat(2); } // If other else { tile.AddShipHeat(2); } } } } }