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

Duplicando herói na linha Aula 1 Vídeo 9

Seguindo a aula escrevi o código tal qual demonstrado, porém quando faço o teste o jogo impede que atravesse as paredes quando tento andar para cima ou para baixo. Só que ao tentar andar para direita ou esquerda o "H" é replicado ficando com até três "H" na mesma linha. Segue o código

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 nova_posicao[0] < 0
            next
        end
        if nova_posicao[1] < 0
            next
        end
        if nova_posicao[0] >= mapa.size
            next
        end
        if nova_posicao[1] >= mapa[0].size
            next
        end
        if mapa[nova_posicao[0]][nova_posicao[1]] == "X"
            next
        end

        mapa[heroi[0]][heroi[1]] = " "
        mapa[nova_posicao[0]][nova_posicao[1]] = "H"
    end    
end

Vi e revi a aula algumas vezes e não consegui identificar onde está o erro.

4 respostas
solução!

Bom dia Frank,

não sei se já passou pela lição correta, mas isso acontece porque na função calcula_nova_posicao você está modificando o array heroi. Logo, heroi e nova_posicao possuem as mesmas coordenadas.

Isso acontece porque arrays são passados por referência para as funções. Toda manipulação dentro da função altera o array original, porque são a mesma coisa.

Para prevenir esse comportamento, dentro de calcula_nova_posicao faça imediatamente uma copia de heroi e retorne a cópia:

nova_posicao = heroi.dup
#...
nova_posicao 

Ítalo vou tentar mais tarde porque não estou em casa, mas segui as orientações e até revisei o código várias vezes com o apresentado pelo Guilherme no vídeo 9. Teoricamente não deveria acontecer, já que o dele funciona normalmente. Vou tentar essa duplicata que você disse, embora não saiba do que se trata. Quando testar comunico aqui. E obrigado pelo retorno.

Não funcionou. Segue o código

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
    # não achei
end

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

def posicao_valida? (mapa, posicao)
    linhas = mapa.size
    colunas = mapa[0].size
    estourou_linhas = posicao[0] < 0 || posicao[0] >= linhas
    estourou_colunas = posicao[1] < 0 || posicao[1] >= colunas

    if estourou_linhas || estourou_colunas
        return false
    end
    if mapa[posicao[0]][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 = dar_boas_vindas
    joga nome
end

Na funçãocalcula_nova_posicao, depois que você faz a cópia para nova_posicao, você tem que utilizar essa variável nas contas em vez e heroi:

    case direcao
        when "W"
            nova_posicao[0] -= 1
        when "S"
            nova_posicao[0] += 1
        when "A"
            nova_posicao[1] -= 1
        when "D"
            nova_posicao[1] += 1
    end

Não me lembro bem onde exatamente, já que os vídeos não são titulados na barra lateral, mas ele explica essa questão dos parâmetros da função, inclusive com gráficos. É a mesma lição onde ele usa o método dup.

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