1
resposta

Finalizando o jogo

//fogefoge.c

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

MAPA m;
POSICAO heroi;
int tempilula = 0;

int praondeofantasmavai(int xatual, int yatual, int* xdestino, int* ydestino) {
    int opcoes[4][2] = {
        { xatual   , yatual+1 }, 
        { xatual+1 , yatual   },  
        { xatual   , yatual-1 }, 
        { xatual-1 , yatual   }
    };
    
    for(int i = 0; i < 10; i++) {
        int posicao = rand() % 4;

        if(podeandar(&m, FANTASMA, opcoes[posicao][0], opcoes[posicao][1])) {
            *xdestino = opcoes[posicao][0];
            *ydestino = opcoes[posicao][1];

            return 1;
        }
    }

    return 0;
}

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) {

                int xdestino;
                int ydestino;

                int encontrou = praondeofantasmavai(i, j, &xdestino, &ydestino);

                if(encontrou) {
                    andanomapa(&m, i, j, xdestino, ydestino);
                }
            }

        }
    }
    liberamapa(&copia);
}

int acabou() {
    POSICAO pos;

    int perdeu = !encontramapa(&m, &pos, HEROI);
    int ganhou = !encontramapa(&m, &pos, FANTASMA);

    return ganhou || perdeu;		
}

int ehdirecao(char direcao) {
    return
        direcao == 'a' || 
        direcao == 'w' ||
        direcao == 's' ||
        direcao == 'd';
}

void move(char direcao) {
    int x;
    int y;
    
    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(!podeandar(&m, HEROI, proximox, proximoy))
        return;

    if(ehpersonagem(&m, PILULA, proximox, proximoy)) {
        tempilula = 1;
    }
    
    andanomapa(&m, heroi.x, heroi.y, proximox, proximoy);
    heroi.x = proximox;
    heroi.y = proximoy;
}

void explodepilula() {

    if(!tempilula) return;

    explodepilula2(heroi.x, heroi.y, 0, 1, 3);
    explodepilula2(heroi.x, heroi.y, 0, -1, 3);
    explodepilula2(heroi.x, heroi.y, 1, 0, 3);
    explodepilula2(heroi.x, heroi.y, -1, 0, 3);

    tempilula = 0;
}

void explodepilula2(int x, int y, int somax, int somay, int qtd) {

    if(qtd == 0) return;

    int novox = x + somax;
    int novoy = y + somay;

    if(!ehvalida(&m, novox, novoy)) return;
    if(ehparede(&m, novox, novoy)) return;

    m.matriz[novox][novoy] = VAZIO; 
    explodepilula2(novox, novoy, somax, somay, qtd - 1);
}

int main() {
    srand(time(0));

    lemapa(&m);
    encontramapa(&m, &heroi, HEROI);

    do {

    printf("Tem pílula: %s\n", (tempilula ? "SIM" : "NÃO"));
    imprimemapa(&m);

    char comando;
    scanf(" %c", &comando);
    move(comando);
    if(comando == BOMBA) explodepilula(heroi.x, heroi.y, 3);
    fantasmas();

    } while (!acabou());

    
    liberamapa(&m);
}

Garanta sua matrícula hoje e ganhe + 2 meses grátis

Continue sua jornada tech com ainda mais tempo para aprender e evoluir

Quero aproveitar agora
1 resposta

Oi, Guilherme. Como vai?

Gostei de como você usou uma cópia do mapa em fantasmas() para evitar mover o mesmo inimigo duas vezes. Do jeito que você explicou o jogo, o que chamou atenção foi a chamada explodepilula(heroi.x, heroi.y, 3) no main(), enquanto a assinatura está como void explodepilula().

Resolva fazendo o seguinte: troque no main() para if (comando == BOMBA) explodepilula();. E, para evitar aviso/erro de protótipo, inclua a declaração void explodepilula2(int x, int y, int somax, int somay, int qtd); antes de explodepilula() (ou no header). Sua ideia faz sentido, veja como ajustar essas duas partes e o loop de 10 tentativas em praondeofantasmavai() segue ok para aleatoriedade simples.

Uma dica interessante para o futuro é normalizar a entrada do usuário com tolower, aceitando WASD maiúsculo/minúsculo. Veja este exemplo:


#include <ctype.h>

char comando;
scanf(" %c", &comando);
comando = tolower((unsigned char)comando);

/* agora seu switch continua igual */
switch (comando) {
  case 'a': /* ESQUERDA */ break;
  case 'w': /* CIMA */     break;
  case 's': /* BAIXO */    break;
  case 'd': /* DIREITA */  break;
}

Esse código converte a tecla para minuscula e reduz erros de digitação.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!