Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Erro ao mover fantasmas

Quando eu movimento o herói aparece o seguinte erro:

Traceback (most recent call last):
        13: from ./main.rb:3:in `<main>'
        12: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:21:in `inicia_jogo'
        11: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:15:in `joga'
        10: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:74:in `move_fantasmas'
         9: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:74:in `each_with_index'
         8: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:74:in `each'
         7: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:75:in `block in move_fantasmas'
         6: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:75:in `each_with_index'
         5: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:75:in `each'
         4: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:78:in `block (2 levels) in move_fantasmas'
         3: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:85:in `move_fantasma'
         2: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:101:in `posicoes_validas_a_partir_de'
         1: from C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:59:in `posicao_valida?'
C:/Users/Usuario/Desktop/programas/fogefoge/fogefoge.rb:59:in `<': comparison of String with 0 failed (ArgumentError)

o meu código esta assim:

main.rb

require_relative "fogefoge"

inicia_jogo

fogefoge.rb

require_relative "ui"

def inicia_jogo
    nome = da_boas_vindas
    joga nome
end

def joga nome
    mapa = le_mapa 2
    while true
        desenha mapa
        direcao = pede_movimento
        heroi = encontra_jogador mapa
        posicao_atual = nova_posicao heroi,direcao
        if !posicao_valida? mapa, posicao_atual
            next
        end
        mapa[heroi[0]][heroi[1]] = " "
        mapa[posicao_atual[0]][posicao_atual[1]] = "H"
        move_fantasmas mapa
    end
end

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

def encontra_jogador mapa
    heroi = "H"
    mapa.each_with_index do |linha_atual,linha|
        coluna_do_heroi = linha_atual.index heroi
        if coluna_do_heroi
            return [linha,coluna_do_heroi]
        end
    end
end

def 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

def posicao_valida? mapa,posicao_atual
    linhas = mapa.size
    colunas = mapa[0].size

    estorou_linha = posicao_atual[0] < 0 || posicao_atual[0] >= linhas
    estorou_coluna = posicao_atual[1] < 0 || posicao_atual[1] >= colunas
    nova_posicao = mapa[posicao_atual[0]][posicao_atual[1]]

    if  nova_posicao == "X" || nova_posicao == "F"
        return false
    end
    if estorou_linha || estorou_coluna
        return false
    end
    true
end

def move_fantasmas mapa
    fantasma = "F"
    mapa.each_with_index do |linha_atual, linha|
        linha_atual.chars.each_with_index do |caracter_atual, caracter|
            eh_fantasma = caracter_atual == fantasma
            if eh_fantasma
                move_fantasma mapa,[linha,caracter]
            end
        end
    end
end

def move_fantasma (mapa,posicao)
    posicoes = posicoes_validas_a_partir_de mapa, posicao
    return if posicoes.empty?
    posicao = posicoes[0]

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

def soma_de_vetores (vetor1,vetor2)
    soma = [vetor1[0]+vetor2[0],vetor1[1]+vetor2[1]]
end


def posicoes_validas_a_partir_de(mapa, posicao)
    posicoes = []
    baixo = mapa[posicao[0] + 1][posicao[1]]
    if posicao_valida? mapa,baixo
        posicoes << baixo
    end
    direita = mapa[posicao[0]][posicao[1] + 1]
    if posicao_valida? mapa,direita
        posicoes << direita
    end
    cima = mapa[posicao[0] - 1][posicao[1]]
    if posicao_valida? mapa,cima
        posicoes << cima
    end
    esquerda = mapa[posicao[0]][posicao[1] - 1]
    if posicao_valida? mapa,esquerda
        posicoes << esquerda
    end
    posicoes
end

ui.rb

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

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

def desenha mapa
    puts mapa
end
1 resposta
solução!

Olá Vinicius,

A causa do erro comparison of String with 0 failed está na função posicoes_validas_a_partir_de, acontece que está sendo passado um valor inválido para a função posicao_valida:

# Como está:
baixo = mapa[posicao[0] + 1][posicao[1]]

# Como deveria ser:
baixo = [posicao[0] + 1, posicao[1]]

Isso em todos os movimentos, o correto seria assim:

def posicoes_validas_a_partir_de(mapa, posicao)
    posicoes = []

    baixo = [posicao[0] + 1, posicao[1]]
    if posicao_valida? mapa, baixo
        posicoes << baixo
    end

    direita = [posicao[0], posicao[1] + 1]
    if posicao_valida? mapa,direita
        posicoes << direita
    end

    cima = [posicao[0] - 1, posicao[1]]
    if posicao_valida? mapa,cima
        posicoes << cima
    end

    esquerda = [posicao[0], posicao[1] - 1]
    if posicao_valida? mapa,esquerda
        posicoes << esquerda
    end

    posicoes
end

Corrigindo esse erro, outro erro aparece mais a frente na execução do código, acontece que na função move_fantasma são utilizadas 2 variáveis que não existem: linha e coluna. Os valores necessários são recebidos pela variável posicao em formato de array, então recomendo a modificação abaixo:

# Código atual:
def move_fantasma (mapa,posicao)
    posicoes = posicoes_validas_a_partir_de mapa, posicao
    return if posicoes.empty?
    posicao = posicoes[0]

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

# Correção:
def move_fantasma (mapa, posicao)
    posicoes = posicoes_validas_a_partir_de mapa, posicao
    return if posicoes.empty?
    nova_posicao = posicoes[0]

    mapa[posicao[0]][posicao[1]] = " "
    mapa[nova_posicao[0]][nova_posicao[1]] = "F"
end

Após essa modificação outro erro aparece: `posicao_valida?': undefined method `[]' for nil:NilClass (NoMethodError), esse erro é causado pelo acesso a uma nova posição que está fora do mapa:

nova_posicao = mapa[posicao_atual[0]][posicao_atual[1]]

A correção é simples, apenas mudando a ordem dessa linha para depois do teste de limites do mapa:

def posicao_valida? mapa, posicao_atual
    linhas = mapa.size
    colunas = mapa[0].size

    estorou_linha = posicao_atual[0] < 0 || posicao_atual[0] >= linhas
    estorou_coluna = posicao_atual[1] < 0 || posicao_atual[1] >= colunas

    # Testa se  posição está dentro do mapa
    if estorou_linha || estorou_coluna
        return false
    end

    # Pega a posição
    nova_posicao = mapa[posicao_atual[0]][posicao_atual[1]]
    if  nova_posicao == "X" || nova_posicao == "F"
        return false
    end

    true
end