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

Os fantasmas desaparecem

Olá, após dar o primeiro movimento os fantasmas desaparecem. O que pode ser?

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)
    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)
    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

        valor_atual = mapa[posicao[0]][posicao[1]]
        if  valor_atual == "X" || valor_atual == "P"
            return false
        end

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

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

    posicao = posicoes[0]
    mapa[linha][coluna]  = " "
    novo_mapa[posicao[0]][posicao[1]] = "P"

end
def copia_mapa(mapa)
    novo_mapa = mapa.join("\n").tr("P"," ").split "\n"
end
def move_fantasmas(mapa)
    caractere_do_fantasma = "P"
    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 joga(nome)
    mapa = le_mapa 2

    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"
        mapa = move_fantasmas mapa
    end
end

def inicia_fogefoge
    nome = da_boas_vindas
    joga nome

end
1 resposta
solução!

Olá, Adriano!

Duas questões:

O return antecipado no método move_fantasma

Você fez

    return posicoes.empty?

o que NÃO é o mesmo que

    if posicoes.empty?
        return
    end

Um return sem o if vai sempre parar o método, retornado o valor de posicoes.empty?

Não é o que queremos.

Queremos retornar antecipadamente no caso de posicoesestar vazio.

Colocando a posição na variável errada no método posicoes_validas_a_partir_de

Você colocou

        posicao << baixo

mas deveria ser

        posicoes << baixo

O mesmo vale para direita, cima e esquerda.

O array posicoes é o que vai ser retornado!