1
resposta

Programa para sem motivo...

Código compila sem apresentar erros, programa executa, mas quando tento movimentar o personagem em qualquer direção, a execução se encerra.

Erro começou depois que adicionei o void copiamapa e o vinculei ao void fantasmas.

#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include "fogefoge.h"
#include "mapa.h"

MAPA m;
POSICAO heroi;

void copiamapa(MAPA destino, MAPA origem) {
    destino.linhas = origem.linhas;
    destino.colunas = origem.colunas;

    alocamapa(destino);
    for(int i = 0; i < origem.linhas; i++) {
        strcpy(destino.matriz[i], origem.matriz[i]);
    }
}

void fantasmas() {
    MAPA copia;

    copiamapa(copia, m);

    for(int i = 0; i < m.linhas; i++) {
        for(int j = 0; j < m.colunas; j++) {

            if(copia.matriz[i][j] == FANTASMA) {
                if(ehvalida(i, j+1) && ehvazia(i, j+1)) {
                    andanomapa(i, j, i, j+1);
                }
            }

        }
    }
}

void liberamapa() {
    for(int i = 0; i < m.linhas; i++) {
        free(m.matriz[i]);
    }
    free(m.matriz);
}

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

void lemapa() {
    FILE* f;
    f = fopen("mapa.txt", "r");
    if(f == 0) {
        printf("Erro na leitura do mapa\n");
        exit(1);
    }

    fscanf(f, "%d %d", &(m.linhas), &(m.colunas));

    alocamapa(m);

    for(int i = 0; i < 5; i++) {
        fscanf(f, "%s", m.matriz[i]);
    }

    fclose(f);
}

void imprimemapa() {
    for(int i = 0; i < 5; i++) {
        printf("%s\n", m.matriz[i]);
    }
}

void encontramapa(char c) {
    for(int i = 0; i < m.linhas; i++) {
        for(int j = 0; j < m.colunas; j++) {
            if(m.matriz[i][j] == c) {
                heroi.x = i;
                heroi.y = j;
                break;
            }
        }
    }

}

int acabou() {
    return 0;
}

int ehdirecao(char direcao) {

    return direcao == 'a' || direcao == 'w' || direcao == 's' || direcao == 'd';
}

int ehvalida(int x, int y) {
    if(x >= m.linhas) {
        return 0;
    }
    if(y >= m.colunas) {
        return 0;
    }

    return 1;
}

int ehvazia(int x, int y) {

    return m.matriz[x][y] == VAZIO;
}

void andanomapa(int xorigem, int yorigem, int xdestino, int ydestino) {

    char personagem = m.matriz[xorigem][yorigem];
    m.matriz[xdestino][ydestino] = personagem;
    m.matriz[xorigem][yorigem] = VAZIO;
}

void move(char direcao) {

    if(!ehdirecao(direcao)) {
        return;
    }

    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;
    }

    if(!ehvalida(proximox, proximoy)) {
        return;
    }

    if(!ehvazia(proximox, proximoy)) {
        return;
    }

    andanomapa(heroi.x, heroi.y, proximox, proximoy);
    heroi.x = proximox;
    heroi.y = proximoy;

}

int main() {
    setlocale(LC_ALL, "portuguese");

    lemapa();
    encontramapa(HEROI);

    do {

        imprimemapa();

        char comando;
        scanf(" %c", &comando);
        move(comando);
        fantasmas();

    } while(!acabou());

    liberamapa();
}
1 resposta

Olá Jean. Encontrei um ponto no seu código que pode estar gerando esse erro. Na função fantasmas() você cria uma cópia do mapa na variável copia, porem na função copiamapa você deve passar o endereço de memoria para conseguir que o mapa alocado fique salvo na variável. Para resolver isso precisamos fazer 4 modificações no seu código.

Primeiro na função fantasmas() devemos agora passar o endereço da variável copia.

copiamapa(&copia, m);

Segundo na função copiamapa(MAPA* destino, MAPA origem) devemos agora receber o ponteiro na variável destino e agora usamos o -> para acessar os atributos da variável destino.

void copiamapa(MAPA* destino, MAPA origem) {
    destino->linhas = origem.linhas;
    destino->colunas = origem.colunas;

    alocamapa(destino);
    for(int i = 0; i < origem.linhas; i++) {
        strcpy(destino->matriz[i], origem.matriz[i]);
    }
}

Terceiro na função alocamapa(MAPA * m) devemos receber o ponteiro da variável que queremos gravar o mapa e da mesma maneira devemos mudar para -> para acessar os atributos do MAPA

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

E por fim devemos mudar na função lemapa() como chamamos a função alocamapa(&m) já que agora ela espera um ponteiro.

alocamapa(&m);

Espero ter ajudado e qualquer duvida não deixe de perguntar. Bons estudos.