Inicio     |     Sobre     |     GitHub     |     Games     |     Contato                        

quinta-feira, 25 de janeiro de 2024

Resumindo Recursividade para Game Devs


Recursão:

A recursão é um conceito em programação onde uma função chama a si mesma para resolver um problema. Pode ser comparado a uma tarefa que se divide em partes menores, cada uma resolvida de forma semelhante.


Como Funciona:

Quando a função é chamada, ela executa uma parte do problema e, em seguida, chama a si mesma com uma versão menor desse problema. O processo continua até que o problema seja suficientemente pequeno para ser resolvido diretamente, evitando um loop infinito.

Exemplo Prático na Unity:

Suponha que você queira criar uma função recursiva para calcular o fatorial de um número em um jogo Unity. O fatorial de um número n é o produto de todos os inteiros de 1 até n.

csharp
using UnityEngine; public class ExemploRecursao : MonoBehaviour 
{
    void Start()
    {
        int numero = 5;
        int resultado = CalcularFatorial(numero);
         Debug.Log(
"O fatorial de " + numero + " é: " + resultado);
    }

    int CalcularFatorial(int n)
    {
        // Caso base: fatorial de 0 ou 1 é 1
        if (n == 0 || n == 1)
        {
            return 1;
        }
        else
        {
            // Chamada recursiva: n! = n * (n-1)!
            return n * CalcularFatorial(n - 1);
        }
    }
}

Neste exemplo, a função CalcularFatorial chama a si mesma até que atinja o caso base (quando n é 0 ou 1), retornando o resultado final. A chamada recursiva é utilizada para reduzir o problema maior (fatorial de n) em problemas menores (fatoriais de números menores).

Outro Exemplo Prático:


Vamos considerar um exemplo prático de uso de recursão em um jogo Unity para modelar o comportamento de uma hierarquia de inimigos.

Suponha que você tenha inimigos que formam uma árvore de decisão, onde cada inimigo pode ter vários subordinados. Cada subordinado segue o mesmo padrão de comportamento, criando uma estrutura recursiva. Vamos criar um exemplo simples onde inimigos seguem um líder e, por sua vez, podem ter subordinados.

csharp
using UnityEngine;

public class ExemploRecursaoInimigos : MonoBehaviour
{
    public string nomeInimigo;

    void Start()
    {
         CriarHierarquiaInimigos(this);
    }

    void CriarHierarquiaInimigos(ExemploRecursaoInimigos lider)
    {
         Debug.Log("Inimigo " + nomeInimigo + " segue o líder " + lider.nomeInimigo);
        // Simulação de subordinados (pode chamar a si mesmo para criar uma sub-hierarquia)
        if (Random.value < 0.7f)
        {
             ExemploRecursaoInimigos subordinado1 = new     GameObject("Subordinado1").AddComponent<ExemploRecursaoInimigos>();   
             subordinado1.nomeInimigo = "Subordinado1";
             subordinado1.CriarHierarquiaInimigos(this);
        }
        if (Random.value < 0.5f)
        {
             ExemploRecursaoInimigos subordinado2 = new GameObject("Subordinado2").AddComponent<ExemploRecursaoInimigos>();     
             subordinado2.nomeInimigo = "Subordinado2";
             subordinado2.CriarHierarquiaInimigos(this);
        }
    }
}

Neste exemplo, cada inimigo (objeto da classe ExemploRecursaoInimigos) cria subordinados que, por sua vez, podem ter seus próprios subordinados. Isso cria uma hierarquia de inimigos com um comportamento recursivo, onde cada nível segue o mesmo padrão, chamando a si mesmo para criar subordinados. Essa abordagem é útil para representar estruturas de jogo onde inimigos seguem padrões similares em diferentes níveis hierárquicos.

🚩Cuidado!!

Recursão e iteração são duas abordagens distintas para realizar repetições em programação. A principal diferença reside na forma como a repetição é alcançada:

Recursão:

Definição: A recursão é um conceito onde uma função chama a si mesma para resolver um problema. A chamada recursiva continua até que o problema seja suficientemente pequeno para ser resolvido diretamente (caso base).

Exemplo: Um exemplo seria a função de cálculo do fatorial, onde n!=n×(n1)!. Cada chamada reduz o problema até atingir o caso base (fatorial de 0 ou 1).


csharp
using UnityEngine;

public class ExemploRecursao : MonoBehaviour
{
    void Start()
    {
        int numero = 5;
        int resultadoRecursivo = CalcularFatorialRecursivo(numero);
        Debug.Log("O fatorial de " + numero + " é (recursivo): " + resultadoRecursivo);
    }

    int CalcularFatorialRecursivo(int n)
    {
        if (n == 0 || n == 1)
        {
            return 1;
        }
        else
        {
            return n * CalcularFatorialRecursivo(n - 1);
        }
    }
}

Iteração (Laços de Repetição):

Definição: A iteração utiliza estruturas de controle de fluxo, como loops, para repetir uma porção de código até que uma condição seja atendida. Não há chamadas de função a si mesma.

Exemplo: Um exemplo seria o mesmo cálculo do fatorial usando um loop for.


csharp
using UnityEngine;

public class ExemploIteracao : MonoBehaviour
{
    void Start()
    {
        int numero = 5;
        int resultadoIterativo = CalcularFatorialIterativo(numero);
         Debug.Log("O fatorial de " + numero + " é (iterativo): " + resultadoIterativo);
    }

    int CalcularFatorialIterativo(int n)
    {
        int resultado = 1;
        for (int i = 1; i <= n; i++)
        {
             resultado *= i;
        }
        return resultado;
    }
}

Considerações:

  • Recursão pode ser mais intuitiva para certos problemas, mas pode resultar em pilha de chamadas profunda, consumindo mais memória.
  • Iteração geralmente é mais eficiente em termos de consumo de recursos, mas pode ser menos intuitiva para alguns problemas.

A escolha entre recursão e iteração depende do problema em questão e da eficiência desejada. Em muitos casos, ambas as abordagens são equivalentes, e a escolha pode ser uma questão de estilo de programação e preferência pessoal.

Referências:

https://www.youtube.com/shorts/0NA4DOfwkAI

https://www.youtube.com/watch?v=NKymAD4pJZI&t=328s

Nenhum comentário:

Postar um comentário