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

Problema para detectar colisão com o muro.

Bom dia!

Estou com o seguinte problema no curso de ruby III. Meu programa vêm funcionando normalmente, mas aos 1:40 do vídeo 9, quando o professor coloca um if no método "joga" para detectar colisão com o muro, eu faço igual ele, mas o meu programa fica bizarro, com o herói andando apenas pros lados e duplicando a posição. Eu cheguei a voltar algumas aulas pra verificar se esqueci de algo, mas aparentemente está ok. Poderiam me ajudar a encontrar o problema? Desde já agradeço.

Abaixo segue o código. Tem dois arquivos fogefoge.rb, um que vinha funcionando normalmente, mas ainda sem o if para detectar colisão, e o outro que está com problemas, após colocar o if pra detectar colisão:

1:40 do vídeo 9

fogefoge_main.rb

require_relative 'fogefoge'

inicia_fogefoge

fogefoge_ui.rb

def da_boas_vindas
    puts "Bem vindo ao Foge-foge"
    puts "Qual é o seu nome?"
    nome = gets.strip
    puts "\n\n\n\n\n\n"
    puts "Começaremos o jogo para você, #{nome}"
    nome
end

def desenha(mapa)
    puts mapa
end

def pede_movimento
    puts "Para onde deseja ir?"
    movimento = gets.strip
end

fogefoge.rb funcionando:

require_relative 'fogefoge_ui'

def le_mapa(numero)
    arquivo = "mapa#{numero}.txt"
    texto = File.read arquivo
    mapa = texto.split "\n"
end

def encontra_jogador(mapa)
    caractere_do_heroi = "H"
    mapa.each_with_index do |linha_atual, linha|
        coluna_do_heroi = linha_atual.index caractere_do_heroi
        if coluna_do_heroi
            return [linha, coluna_do_heroi]
        end
    end
    #não achei!
end

def calcula_nova_posicao(heroi, direcao)
    case direcao
        when "W"
            heroi[0] -= 1 #diminui em 1 a linha atual
        when "S"
            heroi[0] += 1
        when "A"
            heroi[1] -= 1
        when "D"
            heroi[1] += 1
    end
    heroi #devolve a nova posicao
end

def joga(nome)
    mapa = le_mapa 1

    while true
        desenha mapa
        direcao = pede_movimento
        heroi = encontra_jogador mapa
        mapa[heroi[0]][heroi[1]] = " " #coloca um espaço em branco na posição do Herói antes de movê-lo
        nova_posicao = calcula_nova_posicao heroi, direcao    
        mapa[nova_posicao[0]][nova_posicao[1]] = "H" #coloca na posição nova, a letra H
    end
end

def inicia_fogefoge()
    nome = da_boas_vindas
    joga nome
end

fogefoge.rb com problemas:

require_relative 'fogefoge_ui'

def le_mapa(numero)
    arquivo = "mapa#{numero}.txt"
    texto = File.read arquivo
    mapa = texto.split "\n"
end

def encontra_jogador(mapa)
    caractere_do_heroi = "H"
    mapa.each_with_index do |linha_atual, linha|
        coluna_do_heroi = linha_atual.index caractere_do_heroi
        if coluna_do_heroi
            return [linha, coluna_do_heroi]
        end
    end
    #não achei!
end

def calcula_nova_posicao(heroi, direcao)
    case direcao
        when "W"
            heroi[0] -= 1 #diminui em 1 a linha atual
        when "S"
            heroi[0] += 1
        when "A"
            heroi[1] -= 1
        when "D"
            heroi[1] += 1
    end
    heroi #devolve a nova posicao
end

def joga(nome)
    mapa = le_mapa 1

    while true
        desenha mapa
        direcao = pede_movimento
        heroi = encontra_jogador mapa
        nova_posicao = calcula_nova_posicao heroi, direcao    

        if mapa[nova_posicao[0]][nova_posicao[1]] == "X"
            next
        end

        mapa[heroi[0]][heroi[1]] = " " #coloca um espaço em branco na posição do Herói antes de movê-lo
        mapa[nova_posicao[0]][nova_posicao[1]] = "H" #coloca na posição nova, a letra H
    end
end

def inicia_fogefoge()
    nome = da_boas_vindas
    joga nome
end
2 respostas
solução!

Oi Felipe, tudo bem? O problema é bem simples veja. No seu método calcula_nova_posicao, você não está duplicando a posição do heroi.

def calcula_nova_posicao(heroi, direcao)
    heroi = heroi.dup 
    # restante do codigo
end

Quando você calcula a nova posicao, sem duplicar a variavel, você acaba perdendo a localização exata do heroi, assim, quando você executa o proximo passo, o método que encontra o heroi, se perde, porque no mapa ele está em uma determinada posição, mas na memoria, as variaveis apontam pra outra posição. Por causa da confusão, há uma duplicação do personagem no mapa algumas vezes e outras vezes ele não atualiza a posição do heroi no mapa.

Verifica pra mim se resolveu? Espero ter ajudado, bons estudos!

Olá Wanderson!

Desculpe pela demora em responder.

Era isso mesmo. Agora consigo andar com o herói sem problemas. Obrigado pela explicação detalhada. Bom final de semana.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software