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

Código compila, mapa é impresso mas não obedece aos comandos

O mapa é impresso uma primeira vez, mas ao informar algum comando (com as teclas: a, s, w ou d) o programa "trava" - um novo mapa não é impresso e o pacman não anda.

Seguem meus arquivos:

fogefoge.c

#include<stdio.h>
#include<stdlib.h>
#include "fogefoge.h"
#include<time.h>
#include "mapa.h"
#include "mapa.c"

MAPA m;
POSICAO heroi;
int i,j;

int praondeofantasmavai(int xatual, int yatual, int* xdestino, int* ydestino){
    //As opções de deslocamento que o fantasma tem
    int opcoes[4][2] = {
    { xatual, yatual+1},
    { xatual+1, yatual},
    { xatual, yatual-1},
    { xatual-1, yatual}
    };
    srand(time(0));
    //Há 10 chances do fantasma ter um deslocamento para uma posição válida
    for(i=0;i<10;i++){
        //Adquirindo um número randômico qualquer de 0 a 3
        int posicao = rand() % 4;
        //Se for uma posicao válida
        //Nós então atribuímos valores a xdestino e ydestino
        if(ehvalida(&m, opcoes[posicao][0], opcoes[posicao][1]) && ehvazia(&m, opcoes[posicao][0], opcoes[posicao][1])){
            *xdestino = opcoes[posicao][0];
            *ydestino = opcoes[posicao][1];
            //Retorna verdadeiro quando a atribuição ocorre de forma correta
            return 1;
        }
    }
    
    return 0;
}
void fantasmas(){
    MAPA copia;
    
    copiamapa(&copia,&m);
    
    for(i=0;i<m.linhas;i++){
        for(j=0;j<m.colunas;j++){
            
            if (copia.matriz[i][j]==FANTASMA){
                
                int xdestino;
                int ydestino;
                
                int encontrou = praondeofantasmavai(i,j,&xdestino, &ydestino);
                
                if(encontrou){
                    andanomapa(&m, i, j, xdestino, ydestino);
                }
                
                if(ehvalida(&m, i, j+1) && ehvazia(&m, i, j+1)){
                    andanomapa(&m, i, j, i, j+1);
                }
            }
        }
    }
    liberamapa(&copia);
}

int acabou(){
    return 0;
}

// Validar a entrada do usuário
// Caso o usuário digite uma letra diferente daquelas usadas para comando então
// o pacman não vai se movimentar
int ehdirecao(char direcao){
    return direcao == 'a' || direcao == 'w' || direcao == 's' || direcao == 'd';
}

void move(char direcao){
    
    // Se não for uma direção válida então o pacman não se movimenta
    if(!ehdirecao(direcao) )
        return;
    
    // Descobrindo o que tem na 'casa' para qual o comando do usuário levaria o pacman
    int proximox = heroi.x;
    int proximoy = heroi.y;
    
    switch(direcao){
        case ESQUERDA:
            proximoy--;
            break;
        case CIMA:
            proximox--;
            break;
        case BAIXO:
            proximox++;
            break;
        case DIREITA:
            proximoy++;
            break;
    }

    // Valida a posicao para a qual o comando do usuário 'aponta'
    if(!ehvalida(&m, proximox, proximoy))
        return;
    // Se a proxima posição não for vazia '.' então o pacman não pode se deslocar
    if(!ehvazia(&m, proximox, proximoy))
        return;
    
    andanomapa(&m, heroi.x, heroi.y, proximox, proximoy);
    // Atualizando a posição do heroi no mapa
    heroi.x = proximox;
    heroi.y = proximoy;
}

int main(){
    
    lemapa(&m);
    encontramapa(&m,&heroi, HEROI);
    
    do {
        
    imprimemapa(&m);
    
    char comando;
    scanf(" %c", &comando);
    
    move(comando);
    fantasmas();
        
    } while (!acabou());
    
    liberamapa(&m);
    
    return 0;
}

fogefoge.h

//HEADER DEMAIS FUNÇÕES DO JOGO*************************************************
#define CIMA 'w'
#define BAIXO 's'
#define DIREITA 'd'
#define ESQUERDA 'a'

int acabou();
void move(char direcao);
int ehdirecao(char direcao);
void fantasmas();
int praondeofantasmavai(int xatual, int yatual, int* xdestino, int* ydestino);
2 respostas

... CONTINUAÇÃO

mapa.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int i,j;

void copiamapa(MAPA* destino, MAPA* origem){
    destino->linhas = origem->linhas;
    destino->colunas = origem->colunas;
    
    alocamapa(destino);
    for(i=0;i<origem->linhas;i++){
        strcpy(destino->matriz[i], origem->matriz[i]);
    }
}

void andanomapa(MAPA* m, int xorigem, int yorigem, int xdestino, int ydestino){
    char personagem = m->matriz[xorigem][yorigem];
    //Movimenta qualquer que seja o personagem em uma determinada posição
    m->matriz[xdestino][ydestino] = personagem;
    //Coloca a posição anterior como vazia '.'
    m->matriz[xorigem][yorigem] = VAZIO;
}

int ehvalida(MAPA* m, int x, int y){
    // Se o comando 'apontar' para uma linha maior do que o limite de linhas da matriz
    if(x >= m->linhas)
        return 0;
    // Se o comando 'apontar' para uma coluna maior que o limite de colunas da matriz
    if(y >= m->colunas)
        return 0;
    
    return 1;
}

int ehvazia(MAPA* m, int x, int y){
    return m->matriz[x][y] == VAZIO;
}

void encontramapa(MAPA* m, POSICAO* p, char c){

    for (i=0;i<m->linhas;i++){
        for (j=0;j<m->colunas;j++){
            if(m->matriz[i][j] == c){
                p->x=i;
                p->y=j;
                break;
            }
        }
    }
    
}

void liberamapa(MAPA* m){
    
   for(i=0;i<m->linhas;i++){
          free(m->matriz[i]);
    }
    
    free(m->matriz);
    
}

void alocamapa(MAPA* m){
    
    m->matriz = (char**)malloc(sizeof(char*) * m->linhas);
    
    for(i=0;i< m->linhas;i++){
        m->matriz[i] = (char*)malloc(sizeof(char) * (m->colunas + 1));
    }
    
}

void lemapa(MAPA* m){
// Abre o arquivo***************************************************************	
    FILE* f;
    f = fopen("mapa.txt", "r");
// Informa se tiver erro na leitura*********************************************    
    if(f==0){
        printf("Erro na leitura do mapa\n");
        exit(1); 
    }
// Lê a quantidade de linhas****************************************************   
    fscanf(f,"%d %d", &(m->linhas), &(m->colunas));
// Aloca o tamanho do array*****************************************************
    alocamapa(m);
// Lê as várias linhas**********************************************************
    for(i=0;i<m->linhas;i++){
        fscanf(f,"%s", m->matriz[i]); 
    }
    fclose(f);
}

void imprimemapa(MAPA* m){
    for(i=0;i<m->linhas;i++){
        printf("%s\n", m->matriz[i]);
    }
}

mapa.h

//HEADER DAS FUNÇÕES RELACIONADAS AO MAPA**************************************
#define HEROI '@'
#define FANTASMA 'F'
#define VAZIO '.'
#define PAREDE_VERTICAL '|'
#define PAREDE_HORIZONAL '-'

struct mapa{
    char** matriz; 
    int linhas;
    int colunas;
};
typedef struct mapa MAPA;

struct posicao{
    int x;
    int y;
};
typedef struct posicao POSICAO;

void liberamapa(MAPA* m);
void lemapa(MAPA* m);
void alocamapa(MAPA* m);
void imprimemapa(MAPA* m);
void encontramapa(MAPA* m, POSICAO* p, char c);
int ehvalida(MAPA* m, int x, int y);
int ehvazia(MAPA* m, int x, int y);
void andanomapa(MAPA* m, int xorigem, int yorigem, int xdestino, int ydestino);
void copiamapa(MAPA* destino, MAPA* origem);

Não adianta entrar com comandos Insira aqui a descrição dessa imagem para ajudar na acessibilidade

solução!

Bom dia, Lorena!

Analisando seu código, parece que há algumas áreas onde melhorias e verificações adicionais podem ajudar a identificar e corrigir o problema onde o programa "trava" ao tentar mover o Pac-Man.

Aqui estão as alterações sugeridas:

  1. Adicionar Mensagens de Depuração: Adicione printf para verificar o fluxo do programa e capturar o estado em diferentes pontos.

  2. Ajuste na Função ehvalida: Verifique se as coordenadas são maiores ou iguais a zero, além de serem menores que os limites do mapa.

  3. Remover Inclusão de mapa.c em fogefoge.c: Em fogefoge.c, remova a linha #include "mapa.c", pois ela já está sendo compilada separadamente.

Logo abaixo estarão as mudanças nos arquivos relevantes, mas por contarem com uma grande quantidade de código publiquei na plataforma do Gist, então basta acessar o link para ter acesso:

Ao adicionar os códigos apresentados no link dentro dos respectivos arquivos, o seu projeto deve rodar sem mais problemas.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.