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

index 4 out of string

Quando rodo meu código dá esse erro: "index 4 out of string (IndexError)".

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
  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
  estorou_linhas = posicao[0] < 0 || posicao[0] >= linhas
  estorou_colunas = posicao[1] < 0 || posicao[1] >= colunas
  if estorou_linhas || estorou_colunas
    return false
  end

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

def posicoes_validas_a_partir_de mapa, novo_mapa, posicao
  posicoes = []

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

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

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

end

def copia_mapa mapa
  novo_mapa = mapa.join("\n").tr("F", " ").split
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 joga nome
  mapa = le_mapa 2
  while true
    desenha_mapa mapa
    direcao = pede_movimento
    heroi = encontra_jogador mapa
    nova_posicao = calcula_nova_posicao heroi, direcao
    move_fantasmas mapa

    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_foge_foge
  nome = da_boas_vindas
  joga nome
end
5 respostas

Oi Rhadamés, tudo bem? Você tem esse projeto completo no GitHub? Assim eu consigo baixar todos os arquivos e testar. Olhando o código assim, é bem difícil identificar onde tá o problema...

Arrisco dizer que é algo no arquivo do mapa, mas não dá pra dizer com certeza.

Estou testando aqui e tentando entender o que tá acontecendo. Com certeza estamos acessando algo fora do limite da string que define o mapa, mas tá difícil encontrar o por que... É logo no momento de mover os fantasmas...

solução!

Olá Rhadamés,

Como Wanderson disse, o problema está na hora de mover o fantasma, mais exatamente na hora de copiar o mapa para mover o fantasma.

Na sua função copia_mapa está faltando o \n no final:

novo_mapa = mapa.join("\n").tr("F", " ").split "\n"

Adicionando isso não tive mais erros ao executar o seu código. Verifica se o problema era só isso mesmo.

Agora funcionou! Muito Obrigado! Realmente, eu tinha esquecido de passar o parâmetro pro split, o código ficou tão complexo que nem deu pra perceber :) Eu nunca encontraria esse bug kkkkkk.