Título: Problema con recursividad y buscaminas.
Publicado por: miguel0542 en 5 Junio 2016, 23:27 pm
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; }
Título: Re: Problema con recursividad y buscaminas.
Publicado por: do-while en 5 Junio 2016, 23:49 pm
¡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++) } 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..."); //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..."); return 0; }
|