#include <stdio.h>
#include <stdlib.h>
typedef int TipoChave;
typedef struct {
int Chave;
/* outros componentes */
} TipoItem;
typedef struct Celula_str *Apontador;
typedef struct Celula_str {
TipoItem Item;
Apontador Prox;
} Celula;
typedef struct {
Apontador Primeiro, Ultimo;
} TipoLista;
/*
a função sorteia as bombas dada uma matriz de tamanho nL x nC e com nB numero de bombas
*/
char ** sorteiaBombas(int nL, int nC, int nB, int semente)
{
int a, b, nB2=-1;
char ** B = dynchar((nL+4),(nC+4));
while (nB2<nB) {
a = rand() %nL;
b = rand() %nC;
/* +1 para o resto ficar entre 1 e nL e +1 pela matriz ser maior pra contar as bombas*/
/*+2 pelo aumento da matriz para facilitar fechar posicoes*/
if (B[a+4][b+4]!='B') {
B[a+4][b+4]='B';
nB2++;
}
}
return B;
}
/*função que conta e coloca um caractere de de acordo com número de bombas adjacentes a o local*/
void contaBombas(int nL, int nC, char **Bombas)
{
int i,j,k,l;
for (i = 3; i < nL; i++)
for (j = 3; j < nC; j++){
if (Bombas[i][j]!='B') {Bombas[i][j]=='0';}
if (Bombas[i][j]=='B') {
for (k=i+1; k < i; k++)
for (l=j+1; l < j; l++){
if(Bombas[k][l]!='B') {Bombas[k][l]++;}
}
}
}
}
/*função para imprimir o campo minado*/
void imprimeCampoMinado (int nL, int nC, char **Campo)
{
int i, j;
printf (" |");
for (j=3; j<nC ; j++)
printf (" j");
printf("\n---");
for (j=3; j<nC ; j++)
printf (" -");
for (i=3; i<nL ; i++){
printf ("%d |",i);
for (j=3; j<nC ; j++){
printf (" %c",Campo[i][j]);
}
}
}
/*função que abre a posição de acordo com a regra do jogo e a jogada feita*/
int abrePosicao(int nL, int nC, char **Bombas, char **Campo, int lin, int col)
{
int i, j, N;
for (i=0; i<nL+4; i=i+nL+3)
Bombas[i][j]='1';
for(i=0; i<nC+4; i=i+nC+3)
Bombas[i][j]='1';
if (Bombas[lin+3][col+3]=='B'){
if (Campo[lin+3][col+3]!='B') {
Campo[lin+3][col+3]='B';
N++;
return 0;
}
}
if (Bombas[lin+3][col+3]>'0' && Bombas[lin+3][col+3]<'8' ) {
char b = Bombas[lin+3][col+3];
if (Campo[lin+3][col+3]!=b){
Campo[lin+3][col+3]=b;
N++;
}
}
if (Bombas[lin+3][col+3]=='0') {
if (Campo[lin+3][col+3]!=' ') {
Campo[lin+3][col+3]=' ';
N++;
}
/*+1-1=0+2=2 +1+1=2+2=4*/
for (i=lin+2; i< lin+4 ; i++)
for (j=col+2; j< col+4 ; j++)
return abrePosicao(nL, nC, Bombas, Campo, i, j); }
return N;
}
/*função que fecha as posições, necessária para a volta de jogadas*/
int fechaPosicao(int nL, int nC, char **Campo, int lin, int col)
{
int i, j, g=0,A=0;
if (Campo[lin+3][col+3]!='*'){
Campo[lin+3][col+3]='*';
A++;
}
for (i=0; i<nL+4; i=i+nL+3)
Campo[lin][col]='1';
for(i=0; i<nC+4; i=i+nC+3)
Campo[lin][col]='1';
for (i=1; i<nL+3; i=i+nL+2)
Campo[lin][col]=' ';
for(i=1; i<nC+3; i=i+nC+2)
Campo[lin][col]=' ';
/*+1-1=0+2=2 +1+1=2+2=4*/
for (i=lin+2; i< lin+4 ; i++)
for (j=col+2; j< col+4 ; j++)
if (Campo[i][j]!=' '){g++;}
if (g!=0){
for (i=lin+2; i< lin+4 ; i++)
for (j=col+2; j< col+4 ; j++)
return fechaPosicao(nL, nC, Campo, i, j);
}
for (i=1; i<nL+3; i=i+nL+2){
if(Campo[lin][col]=='*') {A--;}
}
for(i=1; i<nC+3; i=i+nC+2){
if (Campo[lin][col]=='*') {A--;}
}
return A;
}
/*criação de lista*/
void FLVazia(TipoLista *Lista)
{
Lista->Primeiro = (Apontador) malloc(sizeof(Celula));
Lista->Ultimo = Lista->Primeiro;
Lista->Primeiro->Prox = NULL;
}
/*uma maneira de verificar se a lista eh vazia*/
int Vazia(TipoLista Lista)
{
return (Lista.Primeiro == Lista.Ultimo);
}
/*função que insere no inicio uma nova informação*/
void Insere(TipoItem x, TipoLista *Lista)
{
Lista->Ultimo->Prox = (Apontador) malloc(sizeof(Celula));
Lista->Ultimo = Lista->Ultimo->Prox;
Lista->Ultimo->Item = x;
Lista->Ultimo->Prox = NULL;
}
/*função que retira um elemento*/
void Retira(Apontador p, TipoLista *Lista, TipoItem *Item)
{
/* --- Obs.: o item a ser retirado e o seguinte ao apontado por p --- */
Apontador q;
if (Vazia(*Lista) || p == NULL || p->Prox == NULL)
{ printf(" Erro - Lista vazia ou posicao nao existe\n");
return;
}
q = p->Prox;
*Item = q->Item;
p->Prox = q->Prox;
if (p->Prox == NULL) Lista->Ultimo = p;
free(q);
}
/*função para pega o primeiro numero da lista*/
int peganumero(TipoLista Lista)
{
int a;
Apontador Aux;
Aux = Lista.Primeiro->Prox;
a =Aux->Item.Chave;
return a;
}
/*funcao para criar um array bidimensional de char dinamicamente*/
char ** dynchar (int l, int c)
{
int i,j;
char ** m;
m = (char **) malloc (l * sizeof (char *));
if (m==NULL) return m;
for(i=0; i<l; i++)
m[i]= (char *) malloc (c * sizeof (char));
if (m[i] == NULL){
for (j=0; j<i ; j++) free (m[i]);
free (m);
return NULL;
}
return m;
}
int main (int argc, char *argv[])
{
int Tn=0, li, co, nL, nC, nB, semente, i, j, c, d,A,N;
int atoi(const char *nptr);
char t='b';
char ** Bombas;
char ** Campo;
srandom(semente); /*usada para o sorteio das bombas*/
nL = atoi(argv[1]); /* coloca no in o valor digitado no comando*/
nC = atoi(argv[2]); /* coloca no in o valor digitado no comando*/
nB = atoi(argv[3]); /* coloca no in o valor digitado no comando*/
semente = atoi(argv[4]); /* coloca no in o valor digitado no comando*/
Campo = dynchar ((nL+4),(nC+4));
Bombas= sorteiaBombas(nL, nC, nB, semente);
contaBombas(nL, nC, Bombas);
for (i=3; i<nL; i++)
for (j=3; j<nC; j++)
Campo[nL][nC]='*';
/*se houver algum problema na execucao do comando volta*/
if(argc < 4) {
printf("Uso: %s <nL> <nC> <nB> <semente>\n",argv[0]);
return 1;
}
/*comandos necessaris para lista*/
TipoLista lista;
TipoItem item;
TipoItem oi,ja;
Apontador p;
FLVazia(&lista);
/*enquanto o jogador nao digitar f o jogo continua*/
while(t!='f')
{
printf ("Faça sua jogada deste modo para abrir uma posicao faça a linha coluna, para voltar uma jogada digite v e para finalizar o programa digite f");
scanf("%c",t);
/*se a jogada for de abrir uma posicao esta eh inserida na lista e as posições abertas */
if (t=='a'){
scanf ("%d %d",c,d);
oi.Chave=c;
ja.Chave=d;
Insere(ja, &lista);
Insere(oi, &lista);
N= abrePosicao(nL, nC, Bombas, Campo, c, d);
Tn=Tn+N;
printf ("posicoes abertas nesta jogada: %d",N);
printf ("total de posicoes abertas: %d",Tn);
}
/*se voltar a jogada é pego na lista o ultimo abre e fechada a posicao*/
if (t=='v'){
li= peganumero (lista);
Retira(p, &lista, &item);;
co= peganumero (lista);
Retira(p, &lista, &item);;
A = fechaPosicao(nL, nC, Campo, li, co);
Tn=Tn-A;
printf ("posicoes fechadas nesta jogada: %d",A);
printf ("total de posicoes abertas: %d",Tn);
}
imprimeCampoMinado (nL, nC, Campo); /*imprime o campo minado*/
}
/*da free na lista*/
while (Vazia(lista)!='1' || p == NULL!='1' || p->Prox == NULL!='1') {
Retira(p, &lista, &item);;
}
free (Bombas);
free(Campo);
return 0;
}