Está en la página 1de 7

#include #include #include #include #include #include

<stdio.h> <stdlib.h> <time.h> <ctype.h> <conio.h> <string.h>

#define _filas 10 #define _columnas 10 #define _oculta 1 #define _levantada 2 tados que pueden tener cada una de las celdas #define _mina_marcada 3 #define _mina_reventada 4 #define _mina 0x7FFF #define _seleccion_levantar_celda 1 os las dos opciones que tiene el usuario a la #define _seleccion_marcar_mina 2 #define _explosion 1 #define _juego_terminado 2 l juego continua o no despues de cada accion #define _juego_en_marcha 3 typedef struct la celda o el estado de esta(levantada o no) { short int valor_celda; short int estado_celda; }celda;

// creamos mediante define los es

// valor para una mina // otra vez mediante define cream hora de usar una celda // variables para determinar si e // tipo de dato para el valor de

void inicializartablero(short fil, short col,short dificultad, celda tablero[fil ][col]); void pintartablero(short fil, short col, celda tablero[fil][col]); void eliminarcerosadyacentes(short f, short c, short fil, short col, celda table ro[fil][col]); short analizarentrada(short op, short f, short c, short fil, short col, celda ta blero[fil][col]); short nuevaentrada(short* pf, short* pc, short fil, short col, celda tablero[fil ][col]); void resultado(short fil, short col); short escanearnumero(void); short f, c; // creo una variable para filas y otra para columas que tendran ambito en todas las funciones short z; // creo un valor para iniciar el juego short *pf = &f; // creo punteros a las variables antes crea das para poder modificarlas si hiciera falta short *pc = &c; celda tablero[_filas][_columnas]; // por el tipo de dato anterior hemos c reado dos tableros uno para el valor de celda y otro para el estado de celda int main(void) { printf(" Bienvenido al buscaminas, introduzca un valor para iniciar el j uego...\ny recuerde que para introducir numeros debe pulsar la tecla intro\n"); scanf( "%hd", &z); short dificultad; printf("\nSeleccione la dificultad del juego...\n[1]=Facil\n[2]=Media\n[ 3]=Dificil\n[4]=Mortal");

scanf(" %hd", &dificultad); //valor de la variable dificultad para dterminar el numero de minas if(dificultad==1)dificultad=7; if(dificultad==2)dificultad=14; if(dificultad==3)dificultad=30; if(dificultad==4)dificultad=50; short test; short reiniciar; // variable que almacena el valor de analizar entrada para saber si ha terminado el juego do{ inicializartablero(_filas, _columnas,dificultad, tablero); pintartablero( _filas, _columnas, tablero); do { if(nuevaentrada(pf, pc, _filas, _columnas, tablero) == _selecci on_marcar_mina) { test = analizarentrada(_seleccion_marcar_mina ,f, c, _fi las, _columnas, tablero); pintartablero( _filas, _columnas, tablero); } else { test = analizarentrada(_seleccion_levantar_celda ,f, c, _filas, _columnas, tablero); pintartablero( _filas, _columnas, tablero); } }while(test == _juego_en_marcha); resultado(_filas, _columnas); printf(" pulse una tecla para ver la posicion de las minas\n"); // pon emos los getchar para parar el programa mientras calcula si has perdido de otra forma levanta todas las celdas y no funciona la funcion getchar(); getchar(); for(f = 0; f < _filas; f++) { for(c = 0; c < _columnas; c++) { tablero[f][c].estado_celda = _levantada; } } pintartablero( _filas, _columnas, tablero); //system("pause"); printf("\nPara reiniciar el juego pulse 0 y seguidamente la tecla intro\n\n\n "); reiniciar = escanearnumero(); }while(reiniciar == 0);

return 0; } void inicializartablero(short fil, short col,short dificultad, celda tablero[fil ][col]) { short numerominas; short contadorminas; short f, c; to srand(time(NULL)); rios //determinamos de forma aleatoria el numero de minas que se van a insert ar en el tablero //dentro de unos limites establecidos en la dificultad propuesta al usua rio numerominas = dificultad + (rand() % (fil * col) / 20 + 1); // inicializamos el tablero : todas las celdas ocultas y con valor = 0 for(f = 0; f < fil; f++) { for(c = 0; c < col; c++) { tablero[f][c].estado_celda = _oculta; tablero[f][c].valor_celda = 0; } } // comienza la insercion de minas for(contadorminas = 0; contadorminas < numerominas; ) { f = rand() % fil; // fila aleatoria c = rand() % col; // columna aleatoria // debemos verificar que en esa posicion no hay ninguna mina ya // si no hay mina tendremos que realizar dos operaciones if(tablero[f][c].valor_celda != _mina) { short ff, cc; // 1. insercion de una nueva mina tablero[f][c].valor_celda = _mina; contadorminas ++; //2. incrementar en 1 todas las celdas adyacentes for(ff = f - 1; ff <= f + 1 ; ff++) { for(cc = c - 1; cc <= c + 1; cc++) { if((ff >= 0) && (cc >= 0) && (ff < fil) && (cc < col)) { // iniciamos la semilla para generar numeros aleato //minas a insertar //contador de las minas ya insertadas //fila y columna determinada en cada momen

= _mina) lda++;

if(tablero[ff][cc].valor_celda ! // verificamos en cada celda adyacente que no hay una mina { tablero[ff][cc].valor_ce } } } } }

} return; } void pintartablero(short fil, short col, celda tablero[fil][col]) { short f, c; // // // // limpiamos la pantalla. Para ello invocamos a la funcion system, que ejecuta una orden desde el sistema operativo. la orden "cls" limpia la pantalla de comandos en windows. la orden "clear" limpia la pantalla de comandos en linux y mac.

system("cls"); printf("\n\t\t"); // mostramos por pantalla la numeracion de cada columna... for(c = 0; c < col; c++) { printf(" c%02hd ", c); } //mostramos ahora una a una todas las filas... for(f = 0; f < fil; f++) { //primero el numero de la fila... printf(" \n\n\tf%02hd\t", f); // ahora todas las columnas de la fila actual... for(c = 0; c < col; c++) { // si la celda esta oculta no la mostramos if(tablero[f][c].estado_celda == _oculta) { printf(" - "); } // si la celda esta leventada la mostramos... // puede ser que tengamos que mostrar una mina o un valo r numerico else if(tablero[f][c].estado_celda == _levantada) { // si hay una mina(opcion imposible, pero hay va ) if(tablero[f][c].valor_celda == _mina) {

printf(" M }

");

// Hay un valor numerico distinto de 0 else if(tablero[f][c].valor_celda != 0) { printf(" %hd ", tablero[f][c].valor_ce lda); } // hay un valor numerico igual a 0 else { printf(" "); } } // si la celda esta marcada como mina buscamos una seal else if(tablero[f][c].estado_celda == _mina_marcada) { printf("<?> "); } // si la celda es una mina que hemos pisado else if(tablero[f][c].estado_celda == _mina_reventada) { printf("BUM! "); } } } printf("\n\n\n"); return; } void eliminarcerosadyacentes(short f, short c, short fil, short col, celda table ro[fil][col]) { // esta funcion es invocada cuando la celda marcada // por la fila f y la columna c tiene valor 0 // f, c: fila y columna de la celda de valor 0 con la que trabajamos // fil, col: dimensiones del tablero short ff, cc; // para recorrer las filas y columnas del tablero // levantamos la celda seleccionada indicada por f y por c // esta operacion es importante para evitar concurrencia infinita tablero[f][c].estado_celda = _levantada; // y ahora levantamos sus adyacentes, todas ellas sin mina. // ademas si en estas adyacentes encontramos una celda con valor 0 de nuevo la invocamos para volver a levantar las de // alrededor for(ff = f - 1 ; ff <= f + 1 ; ff++) { for(cc = c - 1; cc <= c + 1; cc++)

{ // verificamos que la celda existe if((ff >= 0) && (cc >= 0) && (ff < fil) && (cc < col) && ((ff != f) || (cc != c))) { // si la celda ya ha sido levantada antes, entonces no // hay que volver a procesarla if(tablero[ff][cc].estado_celda != _levantada) { // levantamos la celda tablero[ff][cc].estado_celda = _levantada; // y si la celda vale 0 volvemos a invocar a l a funcion recursiva o recurrente if(tablero[ff][cc].valor_celda == 0) { eliminarcerosadyacentes(ff, cc, fil, c ol, tablero); } } } } } return; } short analizarentrada(short op, short f, short c, short fil, short col, celda ta blero[fil][col]) { short ff, cc; switch(op) { case _seleccion_marcar_mina: tablero[f][c].estado_celda = _mina_marcada; break; case _seleccion_levantar_celda: if(tablero[f][c].valor_celda == 0) { eliminarcerosadyacentes(f, c, fil, col, tablero); } else if(tablero[f][c].valor_celda == _mina) { tablero[f][c].estado_celda = _mina_reventada; return _explosion; } else { tablero[f][c].estado_celda = _levantada ; } } for(ff = 0 ; ff < fil ; ff++) { for(cc = 0 ; cc < col ; cc++) { if(tablero[ff][cc].valor_celda != _mina && tablero[ff][cc].esta do_celda != _levantada) { return _juego_en_marcha;

} } } return _juego_terminado; } short nuevaentrada(short*pf, short*pc, short fil, short col, celda tablero[fil][ col]) { short respuesta; short fila, columna; do { printf("fila---->"); fila = escanearnumero(); printf("columna---->"); columna = escanearnumero(); }while(columna < 0 || fila < 0 || columna >= _columnas || fila > = _filas); *pf = fila; *pc = columna; do { printf(" para levantar celda pulse 1, para marcar mina pulse 2...."); respuesta = escanearnumero(); }while(respuesta < 1 || respuesta > 2); return respuesta == _seleccion_levantar_celda ? _seleccion_levantar_cel da : _seleccion_marcar_mina; } void resultado(short fil, short col) { short ff, cc; short contador; contador = 0; //contador de explosiones for(ff = 0 ; ff < fil ; ff++) { for(cc = 0 ; cc < col ; cc++) { if(tablero[ff][cc].estado_celda == _mina_reventada) { contador ++; } } } contador == 0 ? printf(" Enhorabuena nene has triunfado\n") : printf(" El objet ivo del juego es no detonar las minas... ponte a estudiar anda\n") ; return; } short escanearnumero(void) {short a; scanf(" %hd",&a);//funcion que escanea un numero return a; }