Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Recursão

Gostaria de compreender melhor a recursão.

Não entrou na minha cabeça, ainda, como que as linhas após

executa_remocao mapa, posicao.direita, quantidade

chegam a ser executadas.

Pela lógica, ao acompanharmos a sequência de execução do programa, ele passa pela linha

executa_remocao mapa, posicao.direita, quantidade

quatro vezes e retorna a função remove, não passando pelas funções seguintes. Mas quando vamos ver, na prática, é como se todas as linhas fossem executadas ao mesmo tempo. Ora, porque isso ocorre só aqui e não nas demais funções do programa? Que mágica foi essa que o Guilherme fez?

Seque o código:

def executa_remocao(mapa, posicao, quantidade)
    return if mapa[posicao.linha][posicao.coluna] == "X"    
    posicao.remove_do mapa
    remove mapa, posicao, quantidade - 1
end


def remove(mapa, posicao, quantidade)
    return if quantidade == 0
    executa_remocao mapa, posicao.direita, quantidade
    executa_remocao mapa, posicao.esquerda, quantidade
    executa_remocao mapa, posicao.cima, quantidade
    executa_remocao mapa, posicao.baixo, quantidade

end
5 respostas

Oi Lucas, tudo bem?É.. Recursão é bom complicadinho no começo pra entender e pode se tornar um grande problema se mal utilizada. A questão no codigo é a seguinte (acredito que esta é a parte da bomba certo?).

Bom, recursão é uma técnica usada para problemas em que precisamos usar a mesma função várias vezes, em vez de um loop qualquer, chamando a função várias vezes, este loop é feito com a propria função, que se chama e decrementa um contador para que não fique rodando eternamente a mesma coisa... O que acontece nesse caso é o seguinde, imagina a pilha de execução que simplifica mais as coisas:

No executa_remocao ele chama a funcao remove_do, passando a posicao, o mapa e o contator recrementando 1. Então a função remove_do, executa mais 3 vezes a função executa_remocao. Somando um total de 4 no final e finalizando o ciclo quado o contador for 0. Agora repare outro detalhe, ele só decrementa o contador se a posicao não for uma parece X, fazendo com que o código não destrua as paredes, não faria sentido né? ou talvez sim! depende do jogo :D.

Conseguiu entender melhor? Espero ter ajudado!Quaquer dúvida pode perguntar, assim como eu, temos vários outros colegas aqui pra ajudar.

Bons estudos.

Wanderson, estou quase compreendendo.

A questão é a seguinte...

pensando em pilhas de execução:

a função "remove" é chamada,

daí chamamos o executa_remocao para a direita e vamos decrementando o valor de "quantidade" até chegar a zero e então "retornamos" a função remove. Porém, uma vez retornada, não era para as demais funções de "executa_remoção" (que utilizam como parâmetro os demais lados) serem chamadas, pois elas estão depois do "remove para a direita". Mas na prática elas são executadas! Como isso acontece?

A formatação do código não ficou muito boa quando copiei da primeira vez. Vou tentar novamente:

def executa_remocao(mapa, posicao, quantidade)
    return if mapa[posicao.linha][posicao.coluna] == "X"    
    posicao.remove_do mapa
    remove mapa, posicao, quantidade - 1
end


def remove(mapa, posicao, quantidade)
    return if quantidade == 0
    executa_remocao mapa, posicao.direita, quantidade
    executa_remocao mapa, posicao.esquerda, quantidade
    executa_remocao mapa, posicao.cima, quantidade
    executa_remocao mapa, posicao.baixo, quantidade

end
solução!

Oi Lucas, pensando dessa forma, você está ignorando a existencia dos muros. Mas vamos lá. Acontece a chamada do remove que é apontada para a direita e retorna de novo pra remoção que compara, qual é o próximo caractere? É um muro? volta, sem decrementar e passa pra linha debaixo. Agora na esquerda, é outro muro? volta sem decrementar nada e tenta a próxima linha, se não for um muro, ele remove o que estiver na posição e decrementa o contador.

Conseguiu acompanhar?Caso nao encontre um muro, ele vai remover o que estiver na posição apontada. Caso seja um muro, ele vai pra proxima, sem decrementar.Tudo vai depender do mapa neste caso, que é o que guia a condição da recursão.

Que tal um novo teste? Tente criar um novo mapa, com poucas possiveis posições pra você ver outros objetos sendo removidos ou que tal na hora de remover aldo de uma posicao, colocar um novo caractere no lugar, pra você conseguir ver o caminho que a recursão tomou. Experimente na hora de explodir a bomba, em vez de colocar caracteres de espaço em branco, colocar um traço - ou até um o.

Que tal um mapa diferente? por exemplo: (acredito que neste mapa, só um fantasma explode)

XXXX
XX X
XFFX
X* X
XHFX

Faça o teste, me respoda quando tiver feito! Espero ter ajudado... Bons estudos.

Ótimo Wanderson! Estou pretendendo agora! Muito obrigado.

Ótimo Wanderson! Estou compreendendo agora! Muito obrigado.