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

O programa trava no momento de passar a primeira direção (provavel problema no método calcula_nova_posicao)

O termial não retorna informação sobre o erro. Após dar a primeira direção, o programa é interrompido e occorre a seguinte mensagem:

(most recent call last): 2: from main.rb:4:in <main>' 1: from /Users/fallev/Google_Drive/Pessoal/Coding/Ruby/projetos/foge_foge/foge_foge.rb:109:ininicia_fogefoge' /Users/fallev/Google_Drive/Pessoal/Coding/Ruby/projetos/foge_foge/foge_foge.rb:90:in `joga': undef

A linha 90 refere-se a:

        nova_posicao = Heroi.calcula_nova_posicao direcao

foge_foge.rb :

require_relative 'ui'
require_relative 'heroi'

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 != nil
            jogador = Heroi.new
            jogador.linha = linha
            jogador.coluna = coluna_do_heroi
            return jogador
        end
    end
    nil
end

def posicao_valida? (mapa, posicao)
    if posicao[0] < 0 || posicao[1] < 0 || posicao[0] >= mapa.size || posicao[1] >= mapa[0].size || mapa[posicao[0]][posicao[1]] == "X" || mapa[posicao[0]][posicao[1]] == "F"
        return false
    end
    true
end

def soma_vetor (vetor1, vetor2)
    [vetor1[0] + vetor2[0], vetor1[1] + vetor2[1]]
end

def posicoes_validas_a_partir_de (mapa, novo_mapa, posicao)
    posicoes = []
    movimentos = [[+1, 0], [0, +1], [-1, 0], [0, -1]]

    movimentos.each do |movimento|
        nova_posicao = soma_vetor(movimento, posicao)
        if posicao_valida?(mapa, nova_posicao) && posicao_valida?(novo_mapa, nova_posicao)
            posicoes << nova_posicao
        end
    end
    posicoes
end

def move_fantasma (mapa, novo_mapa, linha, coluna)
    posicoes = posicoes_validas_a_partir_de mapa, novo_mapa, [linha, coluna]
    if posicoes.empty?
        return
    end

    aleatorio = rand posicoes.size
    posicao = posicoes[aleatorio]

    mapa[linha][coluna] = " "
    novo_mapa[posicao[0]][posicao[1]] = "F"
end

def copia_mapa mapa
    novo_mapa = mapa.join("\n").tr("F", " ").split("\n") #ver se o () funciona. video 2
end

def move_fantasmas (mapa)
    caractere_do_fantasma = "F"
    novo_mapa = copia_mapa mapa
    mapa.each_with_index do |linha_atual, linha|
        linha_atual.chars.each_with_index do |caractere_atual, coluna|
            eh_fantasma = caractere_atual == caractere_do_fantasma
            if eh_fantasma
                move_fantasma mapa, novo_mapa, linha, coluna
            end
        end
    end
    novo_mapa
end

def jogador_perdeu?(mapa)
    perdeu = !encontra_jogador(mapa)
end

def joga (nome)
    mapa = le_mapa 2

    while true
        desenha mapa
        direcao = pede_movimento
        heroi = encontra_jogador mapa
        nova_posicao = Heroi.calcula_nova_posicao direcao

        if !posicao_valida? mapa, nova_posicao.to_array
            next
        end

        Heroi.remove_do mapa
        nova_posicao.coloca_no mapa

        mapa = move_fantasmas mapa    
        if jogador_perdeu? mapa
            game_over
            break
        end
    end
end

def inicia_fogefoge
    nome = da_boas_vindas
    joga nome
end

heroi.rb :

class Heroi
    attr_accessor :linha, :coluna

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

    def to_array
        [linha, coluna]
    end

    def remove_do(mapa)
        mapa[linha][coluna] = " " 
    end

    def coloca_no(mapa)
        mapa[linha][coluna] = "H"
    end
end

Acabaram as idéias sobre o que fazer para debugar! o_O

2 respostas
solução!

Fala Fábio beleza ?

Dentro do método joga heroi é em minúsculo no seu código está em maiúsculo em dois trechos:

nova_posicao = Heroi.calcula_nova_posicao direcao

Heroi.remove_do mapa

Só fazer a troca e vai funcionar, lembrando que só vai conseguir mover o herói com letras maiúsculas, caso queria mover com minúscula e maiúsculas:

No arquivo ui.rb, na variável movimento você coloca .upcase assim ele vai ler minúscula com se fossem maiúsculas e vc vai poder usar como quiser

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

Resolvido! Muito obrigado, Felipe!

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