Solucionado (ver solução)
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!