예제 #1
0
    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);
    }
예제 #2
0
    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);
    }
예제 #3
0
    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);
                    }
                }
            }
        }
    }