Problema con recursividad y buscaminas.

Iniciado por miguel0542, 5 Junio 2016, 23:27 PM

0 Miembros y 1 Visitante están viendo este tema.

miguel0542

Desde que tenia 13 (creo) no toco este foro xD. Hoy vengo a que me salve de nuevo. Estoy haciendo un buscaminas den c++ con funciones. El problema es que e la parte donde debo destapar todas las casillas adyacentes del cero utilizo una funcion recursiva. el programa crashea lo he hecho de mil y un maneras diferentes pero no me sale. Espero que alguien pueda ayudarme o almenos explicarme por que es que esto sucede. Saludos! :D


#include <iostream>
#include <cstdlib>
#include <ctime>
#include <stdio.h>

using namespace std;
//Variables publicas
int opc, num_mina, i, j, game_over, num1, num2, fil, col;
bool error;
string dificultad;
//Num 1 y Num 2 son variables random necesarias para evitar que se ponga una mina en el mismo lugar.
//Error va a definir cuando un usuario introduce un valor invalido.
//--------------------------------------------------------------------------------------------------
//Matrices
int matriz_log[10][10];
char matriz_user[10][10];
bool matriz_clop[10][10];
//-------------------------
//Funciones a utilizar
void menu();
void iniciar_arays();
void imprimir();
void inp_col();
void inp_fil();
void abrir_casilla();
void perdiste();
void despejar_casillas(int filI, int colJ);
//-----------------------
//Funciones Void desarrolladas
void menu(){
   do{
       system("cls");
       cout << endl << "       elige la dificultad:" << endl;
       cout << "-----------------------------------" << endl;
       cout << " 1-Facil." << endl << " 2-Intermedio" << endl << " 3-Dificil" << endl;
       cout << "-----------------------------------" << endl;
       cout << "                  ";
       cin >> opc;
       switch(opc){
           case 1:
               num_mina=10;
               error=false;
               dificultad="Facil";
               break;
           case 2:
               num_mina=20;
               error=false;
               dificultad="Intermedio";
               break;
           case 3:
               num_mina=50;
               error=false;
               dificultad="Dificil";
               break;
           default:
               error=true;
               break;
       }
   }while(error==true);
}
void iniciar_arrays(){
   //Se inician los valores de las matrices por defecto,
   for(i=0;i<10;i++){
       for(j=0;j<10;j++){
           matriz_clop[i][j]=false;
           matriz_log[i][j]=0;
           matriz_user[i][j]=' ';
       }
   }
   //Se pone las minas al azar y se evita que se repita la casilla.
   srand((unsigned)time(0));
   for(i=0;i<num_mina;i++){
       num1=rand()%9;
       num2=rand()%9;
       if(matriz_log[num1][num2]==9){
           i--;
       }else{
           matriz_log[num1][num2]=9;
       }
   }
   //Las minas pondran un +1 al rededor de ellos.
   for(i=0;i<10;i++){
       for(j=0;j<10;j++){
           if(matriz_log[i][j]==9){
               if(i-1>=0 && matriz_log[i-1][j]!=9){
                   matriz_log[i-1][j]++;
               }
               if(i-1>=0 && j-1>=0 && matriz_log[i-1][j-1]!=9){
                   matriz_log[i-1][j-1]++;
               }
               if(i-1>=0 && j+1<=9 && matriz_log[i-1][j+1]!=9){
                   matriz_log[i-1][j+1]++;
               }
               if(j-1>=0 && matriz_log[i][j-1]!=9){
                   matriz_log[i][j-1]++;
               }
               if(j+1<=9 && matriz_log[i][j+1]!=9){
                   matriz_log[i][j+1]++;
               }
               if(i+1<=9 && matriz_log[i+1][j]!=9){
                   matriz_log[i+1][j]++;
               }
               if(i+1<=9 && j-1>=0 && matriz_log[i+1][j-1]!=9){
                   matriz_log[i+1][j-1]++;
               }
               if(i+1<=9 && j+1<=9 && matriz_log[i+1][j+1]!=9){
                   matriz_log[i+1][j+1]++;
               }
           }
       }
   }
}
void imprimir(){
   //Se imprime la matriz del usuario
   cout << " ";
   for(i=0;i<10;i++){
       cout << "("  << i << ")";
   }
   cout << "                   ";
   for(i=0;i<10;i++){
       cout << "("  << i << ")";
   }
   cout << "                   ";
   for(i=0;i<10;i++){
       cout << "("  << i << ")";
   }
   cout << endl;
   for(i=0;i<10;i++){
       cout << " ";
       for(j=0; j<10;j++){
           cout << "[" << matriz_user[i][j] << "]";
       }
       cout << "(" << i << ")                ";
       for(int y=0; y<10;y++){
           cout << "[" << matriz_log[i][y] << "]";
       }
       cout << "(" << i << ")                ";
       for(int z=0; z<10; z++){
           cout << "[" << matriz_clop[i][z] << "]";
       }
       cout << "(" << i << ")" << endl;
   }

}
void inp_fil(){
   do{
       system("cls");
       cout << endl << "   Buscaminas " << dificultad << ". Minas: " << num_mina << endl;
       cout << "-----------------------------------" << endl;
       imprimir();
       cout << " Fila: ";
       cin>> fil;
       if(fil>9 || fil<0){
           error=0;
       }else{
           error=1;
       }
   }while(error==0);
}
void inp_col(){
   do{
       system("cls");
       cout << endl << "   Buscaminas " << dificultad << ". Minas: " << num_mina << endl;
       cout << "-----------------------------------" << endl;
       imprimir();
       cout << " Fila: " << fil << endl << " Columna: ";
       cin>> col;
       if(col>9 || col<0){
           error=0;
       }else{
           error=1;
       }
   }while(error==0);
}
void abrir_casilla(){
   if(matriz_log[fil][col]==9){
       for(i=0;i<10;i++){
           for(j=0;j<10;j++){
               if(matriz_log[i][j]==9){
                   matriz_user[i][j]='*';
               }
               matriz_user[fil][col]='X';
           }
       }
       game_over=1;
   }else{
       matriz_user[fil][col]='0'+matriz_log[fil][col];
       matriz_clop[fil][col]=true;
       if(matriz_log[fil][col]==0){
           despejar_casillas(fil,col);
       }
   }
}
void perdiste(){
   system("color 4F");
   system("cls");
   cout << endl << "   Buscaminas " << dificultad << ". Minas: " << num_mina << endl;
   cout << "-----------------------------------" << endl;
   imprimir();
   cout << "Fila: " << fil << endl << "Columna: " << col << endl;;
   cout << "-----------------------------------" << endl;
   cout << "               Perdiste." << endl;
   cout << "-----------------------------------" << endl;
}
void despejar_casillas(int filI, int colJ){
   //destapar
   if(filI-1>=0 && matriz_clop[filI-1][colJ]==false){
       matriz_user[filI-1][colJ]='0'+matriz_log[filI-1][colJ];
       matriz_clop[filI-1][colJ]=true;
   }
   if(filI-1>=0 && colJ-1>=0 && matriz_clop[fil-1][colJ-1]==false){
       matriz_user[filI-1][colJ-1]='0'+matriz_log[filI-1][colJ-1];
       matriz_clop[filI-1][colJ-1]=true;
   }
   if(filI-1>=0 && colJ+1<=9 && matriz_clop[fil-1][colJ+1]==false){
       matriz_user[filI-1][colJ+1]='0'+matriz_log[filI-1][colJ+1];
       matriz_clop[filI-1][colJ+1]=true;
   }
   if(colJ-1>=0 && matriz_clop[fil][colJ-1]==false){
       matriz_user[filI][colJ-1]='0'+matriz_log[filI][colJ-1];
       matriz_clop[filI][colJ-1]=true;
   }
   if(colJ+1<=9 && matriz_clop[fil][colJ+1]==false){
       matriz_user[filI][colJ+1]='0'+matriz_log[filI][colJ+1];
       matriz_clop[filI][colJ+1]=true;
   }
   if(filI+1<=9 && matriz_clop[fil+1][colJ]==false){
       matriz_user[filI+1][colJ]='0'+matriz_log[filI+1][colJ];
       matriz_clop[filI+1][colJ]=true;
   }
   if(filI+1<=9 && colJ-1>=0 && matriz_clop[fil+1][colJ-1]==false){
       matriz_user[filI+1][colJ-1]='0'+matriz_log[filI+1][colJ-1];
       matriz_clop[filI+1][colJ-1]=true;
   }
   if(filI+1<=9 && colJ+1<=9 && matriz_clop[fil+1][colJ+1]==false){
       matriz_user[filI+1][colJ+1]='0'+matriz_log[filI+1][colJ+1];
       matriz_clop[filI+1][colJ+1]=true;
   }
   //Recursividad
   if(matriz_log[filI-1][colJ]==0 && filI-1>=0){
       despejar_casillas(filI-1, colJ);
   }
   if(matriz_log[filI+1][colJ]==0 && filI+1<=9){
       despejar_casillas(filI+1, colJ);
   }

}
//-----------------------------------------------
int main()
{
   system("color F0");
   menu();
   iniciar_arrays();
   game_over=0;
   do{
       inp_fil();
       inp_col();
       abrir_casilla();
   }while(game_over==0);
   switch(game_over){
       case 1:
           perdiste();
   }
   return 0;
}


do-while

#1
¡Buenas!

No he leído el código completo porque como no lo he escrito yo me parecía un coñazo, pero el algoritmo que buscas sería el siguiente:


void despejar(int fila, int columna, tabla)
{
   si(coordenadas_correctas(fila,columna))
   {
       si(condicion para despejar tabla[i,j])
       {
           marcar tabla[fila,columna] como despejada;
           //dejamos la casilla marcada para no entrar en una recursion infinita

           despejar(fila - 1 , columna); //arriba
           despejar(fila + 1 , columna); //abajo
           despejar(fila , columna + 1); //derecha
           despejar(fila , columna - 1); //izquierda
       }
       //sino no se dan las condiciones para seguir y volvemos
       return;
   }

   //sino las coordenadas no son correctas
   return;
}


¡Saludos!

Te dejo un código que, aunque no hace lo que pides, maneja el mismo concepto. La función que te interesa empieza en la línea 18:

#include <stdio.h>

#define FILAS 21

void mostrar_tabla(char tabla[][FILAS + 1], int filas)
{
   int i;

   for(i = 0 ; i < filas ; i++)
       printf("%s\n",tabla[i]);
}

int coordenadas_correctas(int fila, int columna)
{
   return fila>= 0 && columna >= 0 && fila < FILAS && columna < FILAS;
}

void rellenar(char tabla[][FILAS + 1], int fila, int columna, char relleno)
{
   char caracter_actual;

   //nos aseguramos de que en la primera llamada estamos dentro de la tabla
   if(coordenadas_correctas(fila,columna))
   {
       //guardamos el caracter que hay en la posicion dada antes de sobreescribirlo con el de relleno
       caracter_actual = tabla[fila][columna];
       tabla[fila][columna] = relleno;

       //si las coordenadas hacia arriba son correctas y el caracter es el mismo que el actual
       if(coordenadas_correctas(fila - 1,columna) && tabla[fila - 1][columna] == caracter_actual)
           rellenar(tabla, fila - 1, columna, relleno); //rellenamos

       //...
       if(coordenadas_correctas(fila + 1,columna) && tabla[fila + 1][columna] == caracter_actual)
           rellenar(tabla, fila + 1, columna, relleno);

       if(coordenadas_correctas(fila, columna + 1) && tabla[fila][columna + 1] == caracter_actual)
           rellenar(tabla, fila, columna + 1, relleno);

       if(coordenadas_correctas(fila, columna - 1) && tabla[fila][columna - 1] == caracter_actual)
           rellenar(tabla, fila, columna - 1, relleno);
   }

   return;
}

int main(int argc, char *argv[])
{
   char tabla[FILAS][FILAS + 1];
   int i,j;

   //rellenamos la tabla con oes
   for(i = 0 ; i < FILAS ; i++)
   {
       for(j = 0 ; j < FILAS ; j++)
           tabla[i][j] = 'o';

       tabla[i][j] = '\0';
   }

   //hacemos una cruz con cruces
   for(i = 0 ; i < FILAS ; i++)
       tabla[FILAS / 2][i] = tabla[i][FILAS / 2] = '+';

   mostrar_tabla(tabla,FILAS);

   printf("Pulsar intro para continuar...");
   while(getchar() != '\n');

   //dibujamos rayas hacia el origen en cada cuadrante
   rellenar(tabla, FILAS / 4, FILAS / 4, '\\'); //segundo cuadrante
   rellenar(tabla, 3 * FILAS / 4, FILAS / 4, '/'); //tercer cuadrante
   rellenar(tabla, FILAS / 4, 3 * FILAS / 4, '/'); //primer cuadrante
   rellenar(tabla, 3 * FILAS / 4, 3 * FILAS / 4, '\\'); //cuarto cuadrante

   mostrar_tabla(tabla,FILAS);

   printf("Pulsar intro para continuar...");
   while(getchar() != '\n');

   return 0;
}
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!