Ir ao conteúdo
  • Cadastre-se

Ajuda Campo Minado em C


karkaroffy

Posts recomendados

Eu tenho que fazer um campo minado em c para a faculdade. Preciso representar o tabuleiro com 'F' onde está fechado, 'B' onde tem bombas (caso exploda) e caso o lugar não tenha bomba devo mostrar quantas bombas existem na oito casas em volta do lugar, e mais, se nessas oito casas em volta não houver bombas tenho que abrir as casas em volta de cada uma dessas oito casas.

#include <stdio.h>

#define LIN 102
#define COL 102
#define BOMBA 100

/* Definicao dos tipos */
typedef struct {
int lin, col;
}pos;

typedef struct
{
int revelada, nbombas;
}celula;

/* Declaracao das funcoes */
void le_bombas(int k, pos bombas[]);
void inicializa_campo(pos bombas[], int k, celula campo[LIN][COL], int n, int m);

int main()
{
/* Declaracao das variaveis */
celula campo[LIN][COL];
pos bombas[BOMBA];
pos verifica[LIN * COL];
pos jogar;
int c, n, m, k, l, i;
int fechadas;

/* Leitura do numero de casos de teste */
scanf("%d", &c);

while(c > 0) {

/* Leitura do tamanho do tabuleiro */
scanf("%d %d", &n, &m);

/* Leitura da quantidade de bombas */
scanf("%d", &k);

/* Leitura das posições das bombas */
le_bombas(k, bombas);

/* Inicializa o campo de minas */
inicializa_campo(bombas, k, campo, n, m);

/* Inicializa a quantidade de posições fechadas */
fechadas = n * m;

/* Leitura do numero de jogadas */
scanf("%d", &l);

while(l > 0) {
/* Leitura da linha e da coluna a ser aberta no jogo */
scanf("%d %d", &jogar.lin, &jogar.col);

/* Aqui devem ser colocadas mais funcoes que executam a jogada e
imprime o tabuleiro */
l--;
}
printf("\n");
c--;
}
return 0;
}

/* Esta funcao recebe o vetor de bombas vazio e devolve o numero de
bombas e o vetor de bombas preenchido */
void le_bombas(int k, pos bombas[])
{
int i;

for(i = 0; i < k; i++) {
scanf("%d", &bombas[i].lin);
scanf("%d", &bombas[i].col);
}
}

/* Esta funcao recebe a posicao de cada uma das bombas e o campo de
batalha e inicializa todos com este valor */
void inicializa_campo(pos bombas[], int k, celula campo[LIN][COL], int n,
int m)
{
int i, j;

for(i = 0; i < n+2; i++) {
for(j = 0; j < m+2; j++) {
campo[i][j].nbombas = 0;
if(i == 0 || i == n+1 || j == 0 || j == m+1)
campo[i][j].revelada = -1;
else
campo[i][j].revelada = 0;
}
}

/* Coloca as bombas no campo de batalha */
for(i = 0; i < k; i++) {
campo[bombas[i].lin][bombas[i].col].nbombas = 9;
}

/* Calcula quantas bombas existem ao lado de cada uma das posições
do tabuleiro */
for(i = 1; i <= n; i++) {
for(j = 1; j <= m; j++) {
if(campo[i][j].nbombas != 9) {
if(campo[i-1][j-1].nbombas == 9)
campo[i][j].nbombas++;
if(campo[i-1][j].nbombas == 9)
campo[i][j].nbombas++;
if(campo[i-1][j+1].nbombas == 9)
campo[i][j].nbombas++;
if(campo[i][j-1].nbombas == 9)
campo[i][j].nbombas++;
if(campo[i][j+1].nbombas == 9)
campo[i][j].nbombas++;
if(campo[i+1][j-1].nbombas == 9)
campo[i][j].nbombas++;
if(campo[i+1][j].nbombas == 9)
campo[i][j].nbombas++;
if(campo[i+1][j+1].nbombas == 9)
campo[i][j].nbombas++;
}
}
}
}

Minha dúvida é nessa ultima parte de abrir casas que não possuem bombas.

Se alguem puder me ajudar fico agradecido o/

Link para o comentário
Compartilhar em outros sites

Bom, quando a pessoa dissesse qual casa ela quer "selecionar", você deve ter isso em mente :

0 0 0

0 1 0

0 0 0

Se ela selecionar o 1, supondo que o 1 esteja no indice (linha, coluna), essas casas devem ser abertas : (linha-1, coluna-1), (linha-1,coluna), (linha-1, coluna+1), (linha, coluna-1), (linha,coluna+1), (linha+1, coluna-1), (linha+1, coluna) e finalmente (linha+1, coluna+1)

É sempre assim EXCETO quando a casa selecionada estiver num dos cantos, nessa situação aqui :

1 0 0

0 0 0

0 0 0

Nesse caso, caso o usuario selecione o 1, você deve verificar a celula que está na mesma linha, uma coluna a frente e as que estão na linha de baixo, na mesma coluna e na coluna a frente.

Existe só mais uma possibilidade :

0 0 0

1 0 0

0 0 0

Nesse caso, você deve ver as celulas da linha de cima, mesma coluna e coluna a frente, a celula de mesma linha e coluna a frente, e as celulas da linha de baixo, na mesma coluna e na coluna a frente.

Pronto. E sempre faça testes pra verificar limites, pra saber quando vão cair cada uma dessas três possibilidades

Link para o comentário
Compartilhar em outros sites

Valeu Petrolifero,

eu andei mexendo no meu algoritmo e deu nisso que está abaixo, porém ele

- Não para o jogo quando abre uma bomba;

- Dá como Vitória na primeira casa aberta;

- E não está contando o numero de bombas nas casas vizinhas;

segue o código:

#include <stdio.h>

#define LIN 102
#define COL 102
#define BOMBA 100
#define MINA 9
#define FECHADA -3
#define ABERTA -2
#define BORDA -1
#define BOMBABERTA -4
#define VITORIA -5

/* Definicao dos tipos */
typedef struct {
int lin, col;
}pos;


/* Declaracao das funcoes */
void le_bombas(int k, pos bombas[]);
void inicializa_campo(pos bombas[], int k, int campo[][COL], int revelada[][COL], int n, int m);
void escreve_matriz_jogo_tela(int jogo[][COL],int revelada[][COL],int num_lin,int num_col);
void simula_jogo(int campo[][COL],int revelada[][COL],int num_lin,int num_col,int num_minas,pos jogar);
void abre_casas_adjacentes(int campo[][COL],int revelada[][COL],int n,int m, int *sem_minas);


int main()
{
/* Declaracao das variaveis */
int campo[LIN][COL];
int revelada[LIN][COL];
pos bombas[BOMBA];
pos verifica[LIN * COL];
pos jogar;
int c, n, m, k, l, i;
int fechadas;

/* Leitura do numero de casos de teste */
scanf("%d", &c);

while(c > 0) {

/* Leitura do tamanho do tabuleiro */
scanf("%d %d", &n, &m);

/* Leitura da quantidade de bombas */
scanf("%d", &k);

/* Leitura das posições das bombas */
le_bombas(k, bombas);

/* Inicializa o campo de minas */
inicializa_campo(bombas, k, campo, revelada, n, m);

escreve_matriz_jogo_tela(campo, revelada, n, m);

/* Inicializa a quantidade de posições fechadas */
/*fechadas = n * m;*/

/* Leitura do numero de jogadas */
scanf("%d", &l);

while(l > 0) {
/* Leitura da linha e da coluna a ser aberta no jogo */
scanf("%d %d", &jogar.lin, &jogar.col);

/* Aqui devem ser colocadas duas ou mais funcoes que executam a jogada e imprime o tabuleiro */
simula_jogo(campo, revelada, n, m, k, jogar);
escreve_matriz_jogo_tela(campo, revelada, n, m);


l--;
}
printf("\n");
c--;
}
return 0;
}



/* Esta funcao recebe o vetor de bombas vazio e devolve o numero de bombas e o vetor de bombas preenchido */
void le_bombas(int k, pos bombas[])
{
int i;

for(i = 0; i < k; i++) {
scanf("%d", &bombas[i].lin);
scanf("%d", &bombas[i].col);
}
}

/* Esta funcao recebe a posicao de cada uma das bombas e o campo de batalha e inicializa todos com este valor */
void inicializa_campo(pos bombas[], int k, int campo[][COL], int revelada[][COL], int n, int m)
{
int i, j;
for(i = 0; i < n+2; i++) {
for(j = 0; j < m+2; j++) {
campo[i][j] = 0;
if(i == 0 || i == n+1 || j == 0 || j == m+1)
revelada[i][j] = -1;
else
revelada[i][j] = -3;
}
}

/* Coloca as bombas no campo de batalha */
for(i = 0; i < k; i++) {
campo[bombas[i].lin][bombas[i].col] = 9;
}

/* Calcula quantas bombas existem ao lado de cada uma das posições do tabuleiro */
for(i = 1; i <= n; i++) {
for(j = 1; j <= m; j++) {
if(campo[i][j] != 9) {
if(campo[i-1][j-1] == 9)
campo[i][j]++;
if(campo[i-1][j] == 9)
campo[i][j]++;
if(campo[i-1][j+1] == 9)
campo[i][j]++;
if(campo[i][j-1] == 9)
campo[i][j]++;
if(campo[i][j+1] == 9)
campo[i][j]++;
if(campo[i+1][j-1] == 9)
campo[i][j]++;
if(campo[i+1][j] == 9)
campo[i][j]++;
if(campo[i+1][j+1] == 9)
campo[i][j]++;
}
}
}
}


void escreve_matriz_jogo_tela(int jogo[][COL],int revelada[][COL],int num_lin,int num_col)
{
int i, j;
for(i=1;i<=num_lin;i++){
for(j=1;j<=num_col;j++){
if(revelada[i][j] == -3)
printf("F ");
else if(revelada[i][j] == -2)
printf("%d ", jogo[i][j]);
else if(revelada[i][j] == -4)
printf("B ");
else if(revelada[i][j] == -5)
printf("V ");
}
printf("\n");
}

/*(marca[i][j] == FECHADA) ? printf("%3c",FECHADA) : printf("%3d",jogo[i][j]);
printf("\n");*/

}

void simula_jogo(int campo[][COL],int revelada[][COL],int n,int m,int num_minas,pos jogar)
{
int i, j,
acabou, /*Variavel booleana (verdadeiro/falso) que indica se o jogo acabou o nao. */
sem_minas;

acabou = 0;

sem_minas = n*m-num_minas;


while(!(acabou)) /*Enquanto o jogo nao acabou... continuamos */
{
/*Se o numero de casas sem minas for 0... então nao tem mais casas para o usuario *
*descobrir e então ele ganhou o jogo. */
if(sem_minas == 0)
{
for (i=1; i<n; i++) {
for (j=1; j<m; j++) {
if(revelada[i][j] == -3)
revelada[i][j] = VITORIA;
}
}

/*escreve_matriz_jogo_tela(campo, revelada, n, m);*/
acabou = 1;
}
else
{
/*Se a posicao que o jogador escolheu nao for uma mina... marcamos a casa como aberta *
*diminuimos o numero de casas sem minas em um, e ainda, se o valor da casa aberto for*
*0... ou seja, se nao ha nenhuma mina nos seus arredores, mandamos verificar e abrir *
*as casas adjacentes que nao tem minas. */
if(campo[jogar.lin][jogar.col] != MINA)
{
revelada[jogar.lin][jogar.col] = ABERTA;
sem_minas--;
if(campo[jogar.lin][jogar.col] == 0)
abre_casas_adjacentes(campo,revelada,n, m,&sem_minas);
}

/*Se o usuario pisou numa mina... acabamos o jogo. */
else
{
revelada[jogar.lin][jogar.col] = BOMBABERTA;
for (i=1; i<n; i++) {
for (j=1; j<m; j++) {
if(campo[i][j] == 9)
revelada[i][j] = BOMBABERTA;
}
}
acabou = 1;
}
}
}
}

void abre_casas_adjacentes(int campo[][COL],int revelada[][COL],int n,int m, int *sem_minas)
{
int i, /*Contadores para as iteracoes... */
j;
for(i=n-1;i<n+2;i++)
for(j=m-1;j<m+2;j++)
{
/*Se nao houver uma mina na posicao... se a posicao nao for uma borda... se a posicao *
*ainda nao estiver aberta... e se por fim a posicao nao for a propria [i][j], abrimos*
*e diminuimos *num_minas... */
if((campo[i][j] != MINA) && (revelada[i][j] != BORDA) && (revelada[i][j] != ABERTA) && (i!=n && j!=m))
{
revelada[i][j] = ABERTA;
(*sem_minas)--;
}
}
}

Se alguém puder ajudar agradeço o/

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!