Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
10
respostas

Erro ao executar o jogo

Olá. Estou recebendo o seguinte erro ao executar o jogo:

fogefoge.rb:46:in `posicao_valida?': undefined local variable or method `nova_posicao' for main:Object (NameError)
    from /Users/cristianopinheiro/Documents/jogo_em_ruby/fogefoge.rb:60:in `joga'
    from /Users/cristianopinheiro/Documents/jogo_em_ruby/fogefoge.rb:70:in `inicia_fogefoge'
    from main.rb:3:in `<main>'

Seguem os arquivos: fogefoge,rb

require_relative '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

end

def calcula_nova_posicao (heroi, direcao)
    case direcao
        when "W"
            heroi[0] -= 1
        when "S"
            heroi[0] += 1
        when "A"
            heroi[1] -= 1
        when "D"
            heroi[1] += 1
        end
        heroi

end
def posicao_valida?(mapa, posicao)
    linhas = mapa.size
    colunas = mapa[0].size
    estoutou_linhas = posicao[0] < 0 || posicao[0] >= linhas
    estouro_colunas = posicao[1] < 0 || posicao[1] >= colunas
    if estoutou_linhas || estouro_colunas
            return false
        end


        if mapa[nova_posicao[0]][nova_posicao[1]] = "X"
            return false
        end
        true
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 !posicao_valida? mapa, nova_posicao
            next    
        end
        mapa[heroi[0]][heroi[1]] = " "
        mapa[nova_posicao[0]][nova_posicao[1]] = "H"
    end
end

def inicia_fogefoge
    nome = da_boas_vindas
    joga nome

end

main.rb

require_relative 'fogefoge'

inicia_fogefoge

O que pode ser? Obrigado desde já

10 respostas

Olá, Adriano.

Percebe pela mensagem, que o erro aconteceu na linha 46, no método posicao_valida? e que o problema é que a variável nova_posicao não foi encontrada:

fogefoge.rb:46:in `posicao_valida?': undefined local variable or method `nova_posicao'

Na alteração de nova_posicao para posicao, acho que você esquece de mudar nesse if:

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

Corriga para:

if mapa[posicao[0]][posicao[1]] = "X"

E veja se funciona!

Obrigado pelo retorno Alexandre. Funcionou, porém quando eu peço 2 vezes para o herói mover para a direita, ou seja, o muro aparece o seguinte erro:

/Users/cristianopinheiro/Documents/jogo_em_ruby/fogefoge.rb:39:in `<': comparison of String with 0 failed (ArgumentError)
    from /Users/cristianopinheiro/Documents/jogo_em_ruby/fogefoge.rb:39:in `posicao_valida?'
    from /Users/cristianopinheiro/Documents/jogo_em_ruby/fogefoge.rb:60:in `joga'
    from /Users/cristianopinheiro/Documents/jogo_em_ruby/fogefoge.rb:70:in `inicia_fogefoge'
    from main.rb:3:in `<main>'

Pelo erro, foi na linha 39 na comparação que vê se é menor que 0:

fogefoge.rb:39:in  `<': comparison of String with 0 failed (ArgumentError)

Veja que o erro diz que há uma comparação entre uma String e o < 0.

Ou seja, o valor de posicao está com um texto dentro.

Isso faz sentido pra você? Consegue pensar em algo?

Sim. Tentei colocar o número 0 como string "0". Mas não funcionou.

insira seu código aqui

E também a conversão para to_i , mas também não funcionou:

linhas.to_i = mapa.size
    colunas.to_i = mapa[0].size
    estoutou_linhas = posicao[0].to_i < 0 || posicao[0].to_i >= linhas
    estouro_colunas = posicao[1].to_i < 0 || posicao[1].to_i >= colunas

Aparece o seguinte erro:

/Users/cristianopinheiro/Documents/jogo_em_ruby/fogefoge.rb:38:in `posicao_valida?': undefined local variable or method `colunas' for main:Object (NameError)
    from /Users/cristianopinheiro/Documents/jogo_em_ruby/fogefoge.rb:60:in `joga'
    from /Users/cristianopinheiro/Documents/jogo_em_ruby/fogefoge.rb:70:in `inicia_fogefoge'
    from main.rb:3:in `<main>'

Alguma sugestão?

Olá, Adriano.

Pode deixar os .to_i na posicao.

Mas para linhas e colunas você não precisa porque você está definindo novas variáveis.

Então, deixe assim:

linhas = mapa.size
colunas = mapa[0].size

Valeu. Agora funciona porém ele não move e coloca um X na posição destino:

def posicao_valida?(mapa, posicao)
    linhas = mapa.size
    colunas = mapa[0].size
    estoutou_linhas = posicao[0].to_i < 0 || posicao[0].to_i >= linhas
    estouro_colunas = posicao[1].to_i < 0 || posicao[1].to_i >= colunas
    if estoutou_linhas || estouro_colunas
            return false
        end


        if mapa[posicao[0]][posicao[1]] = "X"
            return false
        end
        true
end

Olá, Adriano!

No seu if, você está atribuindo (um igual, =) ao invés de comparar (dois iguais, ==).

O certo seria:

        if mapa[posicao[0]][posicao[1]] == "X"
solução!

Aproveitando, faltou colocar o heroi.dup no método calcula_nova_posicao:

def calcula_nova_posicao(heroi, direcao)
    heroi = heroi.dup #inserido
    case direcao
        when "W"
            heroi[0] -= 1
        when "S"
            heroi[0] += 1
        when "A"
            heroi[1] -= 1
        when "D"
            heroi[1] += 1
    end
    heroi
end

Valeu Alexandre. Mas faltou acrescentar ao vídeo da explicação a linha: heroi = heroi.dup

def calcula_nova_posicao (heroi, direcao)
    heroi = heroi.dup
    movimentos = {
        "W" => [-1,0],
        "S" => [+1,0],
        "A" => [0,-1],
        "D" => [0,+1]
    }
        movimento = movimentos[direcao]
        heroi[0] += movimento[0]
        heroi[1] += movimento[1]
        heroi

end

Verdade, Adriano!