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

[Dúvida] A varíavel não está sendo entendida

quando eu aperto as teclas elas não causam variação na posção.

#include <iostream>
#include <stdlib.h>
#include <locale.h>

using namespace std;

char** mapa;
int linhas, colunas;

void liberaMapa();
void leMapa();
void alocaMapa();
void imprimeMapa();
int acabou();
void move(char direcao);

int main()
{
    setlocale(LC_ALL,"");  // Ativa o uso de acentos

   leMapa();
   
   do{
        char comando;
        imprimeMapa();
        
        scanf(" %c", &comando);
        move(comando);
        
   }while(!acabou());

    liberaMapa();

    system("pause");
    return 0;
}

void liberaMapa()
{
    // Liberação da memória alocada
    for (int i = 0; i < linhas; i++)
    {
        free(mapa[i]);
    }
    free(mapa);
}

void leMapa()
{
     FILE *f;
    f = fopen("mapa.txt", "r");

    if (f == 0) 
    {
        printf("Erro na leitura do mapa");
        exit(1);
    }

    fscanf(f, "%d %d", &linhas, &colunas);
    
    alocaMapa();
    
    // Leitura do mapa do arquivo
    for (int i = 0; i < linhas; i++) 
    {
        fscanf(f, "%s", mapa[i]);
    }

    fclose(f);
}

void alocaMapa()
{
    // Alocação dinâmica da matriz
    mapa = (char**)malloc(sizeof(char*) * linhas);
    for (int i = 0; i < linhas; i++)
    {
        mapa[i] = (char*)malloc(sizeof(char) * (colunas + 1)); // +1 para o caractere nulo
    }
}

void imprimeMapa()
{
    // Impressão do mapa
    for (int i = 0; i < linhas; i++) 
    {
        printf("%s\n", mapa[i]);
    }
}

int acabou()
{
    return 0;
}

void move(char direcao)
{
    int x, y, i, j;
    
    for(i = 0; i < linhas; i++)
    {
        for(j = 0; j < linhas; j++)
        {
            if(mapa[i][j] == '@')
            {
                x = i;
                y = j;
                break;
            }
        }   
    }
    switch(direcao)
    {
        case 'a': 
            mapa[x][y-1] = '@';
            break;
        case 'w': 
            mapa[x-1][y] = '@';
            break;
        case 's': 
            mapa[x+1][y] = '@';
            break;
        case 'd': 
            mapa[x][y+1] = '@';
            break;
    }
    // remove um dos Packman
    mapa[x][y] = '.';
}
2 respostas

Bom dia, Pedro! Joia?

O problema está no fato de que a função move não está verificando se a nova posição é válida antes de mover o @. Além disso, ela está alterando a posição do @ sem primeiro verificar se a nova posição está livre ou dentro dos limites do mapa. Por isso, quando você move o @, ele está sendo "duplicado" em vez de movido corretamente.

Para corrigir isso, é necessário adicionar verificações para garantir que o @ se mova apenas para posições válidas. Vamos ajustar a função move para incluir essas verificações:

void move(char direcao)
{
    int x, y, i, j;

    // Encontrar a posição atual do '@'
    for(i = 0; i < linhas; i++)
    {
        for(j = 0; j < colunas; j++)
        {
            if(mapa[i][j] == '@')
            {
                x = i;
                y = j;
                break;
            }
        }
    }

    // Variáveis para a nova posição do '@'
    int novoX = x, novoY = y;

    // Atualizar a nova posição com base na direção
    switch(direcao)
    {
        case 'a':
            novoY = y - 1;
            break;
        case 'w':
            novoX = x - 1;
            break;
        case 's':
            novoX = x + 1;
            break;
        case 'd':
            novoY = y + 1;
            break;
    }

    // Verificar se a nova posição é válida e se está dentro dos limites
    if (novoX >= 0 && novoX < linhas && novoY >= 0 && novoY < colunas && mapa[novoX][novoY] == '.')
    {
        // Mover o '@' para a nova posição
        mapa[novoX][novoY] = '@';
        // Remover o '@' da posição antiga
        mapa[x][y] = '.';
    }
}

Aqui está o que foi alterado e por quê:

  1. Verificação da nova posição: Antes de mover o @, o código verifica se a nova posição está dentro dos limites do mapa (novoX >= 0 && novoX < linhas && novoY >= 0 && novoY < colunas) e se a posição alvo está livre (mapa[novoX][novoY] == '.').
  2. Atualização Condicional: O @ só é movido se a nova posição for válida.

Com essas mudanças, o @ só será movido para posições válidas e livres, evitando a duplicação do caractere. Isso deve corrigir o comportamento do programa.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.
solução!

Entendi, essa parte não tinha sido mostrada em aula ainda, acho que seria mais a frente. Mas, o do professor estava funcionando mesmo sem essas verificações.