Пример #1
0
    /// <summary>
    /// Devuelve el nodo más adecuado de la lista de nodos accesibles
    /// </summary>
    /// <param name="_selectedNodes">Lista de nodos aceccesibles</param>
    private GridNode BestNodeSelection(Unit chip)
    {
        // mutate return
        float seed = 0.15f;

        if (chip.role == StrategicRole.Defense)
        {
            seed = 0.3f;
        }
        else if (chip.role == StrategicRole.Center)
        {
            seed = 0.2f;
        }
        else if (chip.role == StrategicRole.Forward)
        {
            seed = 0.1f;
        }

        if (Random.value < seed)
        {
            return(Mutate(chip));
        }

        // comportamientos
        GridNode        best         = null;
        GridNode        objective    = flagEnemy;
        List <GridNode> menances     = new List <GridNode>();
        UpgradeArea     nearestBoost = NearestBoostArea(chip); // saca el upgrade area compatible más cercana
        int             len          = int.MaxValue;
        bool            priority     = false;

        foreach (GridNode g in _selectedNodes) // buscar elementos con prioridad
        {
            if (IsNodeOnArea(g) && g.isOccupied != null)
            {
                if (g == flagEnemy) // si es la bandera enemiga
                {
                    return(g);
                }
                else if (g.isOccupied.tag == "Unit") // si es una ficha
                {
                    Unit anotherUnit = (Unit)g.isOccupied;
                    if (!_team.IsUnitInTeam(anotherUnit)) // si la unidad no es amiga
                    {
                        float power      = chip.GetUnitPower(anotherUnit);
                        float powerEnemy = anotherUnit.GetUnitPower(chip);
                        if (power < powerEnemy) // si la enemiga es más fuerte
                        {
                            menances.Add(g);
                            priority = true;
                        }
                        else if (power > powerEnemy) // si la enemiga es más debil
                        {
                            best = g;
                        }
                    }
                }
                else if (nearestBoost != null && g == nearestBoost.GetGridNode())
                {
                    best = g;
                }
            }
        }

        if (priority) // se activa el return prioritario cuando hay amenazas
        {
            // returnea el nodo accesible más lejano al enemigo y más proximo al objetivo
            return(path.GetOptimalFurtherNode(_selectedNodes, menances, flagEnemy));
        }
        else if (best != null)
        {
            return(best);
        }
        else // si no se han encontrado elementos con prioridad
        {
            switch (chip.role) // modificar objetivo según rol estratégico
            {
            case StrategicRole.Forward:     // modo ataque
                if (nearestBoost != null)
                {
                    if (path.GetDistance(chip.GetGridNode(), nearestBoost.GetGridNode()) < totalDistance / 6)
                    {
                        objective = nearestBoost.GetGridNode();
                    }
                    else
                    {
                        objective = flagEnemy;
                    }
                }
                else
                {
                    objective = flagEnemy;
                }
                break;

            case StrategicRole.Defense:     // modo defensa
                if (nearestBoost != null)
                {
                    if (path.GetDistance(chip.GetGridNode(), nearestBoost.GetGridNode()) < totalDistance / 10)
                    {
                        objective = nearestBoost.GetGridNode();
                    }
                    else
                    {
                        objective = flagAlly;
                    }
                }
                else
                {
                    objective = flagAlly;
                }
                break;

            default:     // modo cobertura
                if (nearestBoost != null)
                {
                    if (path.GetDistance(chip.GetGridNode(), nearestBoost.GetGridNode()) < totalDistance / 3)
                    {
                        objective = nearestBoost.GetGridNode();
                    }
                    else
                    {
                        objective = flagEnemy;
                    }
                }
                else
                {
                    objective = flagEnemy;
                }

                break;
            }

            foreach (GridNode g in _selectedNodes) // recorrer la lista de nodos accesibles y elegir el camino más corto
            {
                if (IsNodeOnArea(g))               // si el nodo es accesible
                {
                    if (g.isOccupied == null)      // si el nodo está vacio
                    {
                        int newLen = path.BestPathLength(g, objective);
                        if (newLen < len)  // si el camino actual es mas corto que el mejor registrado
                        {
                            len  = newLen; // actualizar camino mas corto encontrado
                            best = g;      // actualizar mejor nodo
                        }
                    }
                }
            }
        }

        return(best);
    }