Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: xuhipoint en 8 Marzo 2014, 04:43 am



Título: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: xuhipoint en 8 Marzo 2014, 04:43 am
Buenas noches mi nombre es Maria y soy nueva en este foro y en el mundo de la programación, así que discúlpenme si comento algún error. Tengo un problema con mi matriz dinámica, necesito crear un buscaminas pero primero debe crear una matriz dinámica, ya que el usuario va a crear la matriz aleatoriamente, luego el usuario debe ingresar unas coordenadas donde se debe colocar una mina "*". Lo que no se es como hacer para que en la coordenada que ingrese el usuario se coloque la mina, lo que he creado hasta el momento es este código (también me restringen a las librerías iostream y string:
#include<iostream>
#include<string>
using namespace std;

int main()
{
int i,j,matriz;


cin>>matriz;

// creamos la matriz !
double **M = new double* [matriz];
for (i = 0; i < matriz; i++)
M = new double[matriz];

//mostrar matriz
for (i = 0; i < matriz; i++)
{
for (j = 0; j < matriz; j++)
cout << M[j] << " ";
cout << endl;
}
delete [] M;

return 0;
}


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: rir3760 en 8 Marzo 2014, 05:35 am
Cuando publiques código fuente por favor utiliza las etiquetas de código. Estas se agregan mediante el cuadro desplegable con el texto "GeSHi" en la pagina de composición de mensajes, solo tienes que seleccionar ahí el lenguaje (C, C++, etc.).

----

* Lo primero que debes hacer es cambiar el tipo de los elementos de la matriz de double a char ya que en ella almacenaras caracteres.

* Debes liberar primero todas las filas y solo entonces el bloque principal.

* Para almacenar un carácter solo tienes que verificar que los indices sean validos y a continuación utilizar el operador de asignación "M[ f ][ c ] = algun_valor".

Mas o menos así:
Código
  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7.   int matriz;
  8.   cin >> matriz;
  9.  
  10.   // creamos la matriz !
  11.   char **M = new char *[matriz];
  12.   for (int i = 0; i != matriz; i++)
  13.      M[i] = new char [matriz];
  14.  
  15.   // Asignacion, solo un ejemplo
  16.   for (int i = 0; i != matriz; i++)
  17.      for (int j = 0; j != matriz; j++)
  18.         M[i][j] = '*';
  19.  
  20.   //mostrar matriz
  21.   for (int i = 0; i != matriz; i++){
  22.      for (int j = 0; j != matriz; j++)
  23.         cout << " " << M[i][j];
  24.  
  25.      cout << endl;
  26.   }
  27.  
  28.   for (int i = 0; i != matriz; i++)
  29.      delete[] M[i];
  30.   delete[] M;
  31.  
  32.   return 0;
  33. }

Y si estas aprendiendo C++ puedes utilizar las clases vector y string para implementar la matriz.

Un saludo


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: xuhipoint en 8 Marzo 2014, 12:54 pm
Pero si cambio la matriz a char que pasara con los numeros, porque en una cordenada especifica es donde se debe asignar el asterisco. Y gracias por responder


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: xaps en 8 Marzo 2014, 13:59 pm
Pero si cambio la matriz a char que pasara con los números, porque en una cordenada especifica es donde se debe asignar el asterisco. Y gracias por responder
En una matriz de char puedes almacenar cualquier carácter que exista en la tabla ASCII, por lo tanto también puedes almacenar caracteres numéricos.

Saludos


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: leosansan en 8 Marzo 2014, 15:41 pm

Pero si cambio la matriz a char que pasara con los numeros, porque en una cordenada especifica es donde se debe asignar el asterisco. Y gracias por responder


Como te indicó xaps ello no representa mayor problema.

Para que tengas una variante he usado la matriz "cont" como int, así tienes otra variante.

Todo está en saber "jugar" entre char y entero, sumando o restando '0' o su equivalente ascii 48. Te dejo las dos formas para que lo veas.

He aquí una muestra con la matriz donde se han introducido las minas, otra con las sumas de los que le rodean y otra en que me he permitido la licencia de "ocultar" determinadas posiciones. Vamos lo que es el juego del buscaminas:


(http://i1280.photobucket.com/albums/a497/leosansan/buscaminas_zpsab31791a.jpg)

Código
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <time.h>
  4.  
  5. using namespace std;
  6.  
  7. void imprimir (char **Matriz,int dim);
  8. void colocar_minas (char **Matriz,int dim);
  9. void borrar (int **M,int dim);
  10. void borrar_char (char **M,int dim);
  11.  
  12. int main(void) {
  13.  srand((unsigned) time(NULL));
  14.  int dim,n;
  15.  char ch=219;
  16.  
  17.  cout << "Introduzca la dimension de la matriz: ";
  18.  cin >> dim;
  19.  char **Matriz = new char *[dim];
  20.  for (int j = 0; j < dim; j++)
  21.    Matriz[j] = new char [dim];
  22.  for (int i = 0; i < dim; i++)
  23.    for (int j = 0; j < dim; j++)
  24.      Matriz[i][j]='0';
  25.  colocar_minas  (Matriz,dim);
  26.  imprimir (Matriz,dim);
  27.  
  28.  for (int i = 0; i < dim; i++)
  29.    for (int j = 0; j < dim; j++){
  30.      n = rand() % 5 ;
  31.      if (n<2 && Matriz[i][j]=='0')
  32.        Matriz[i][j]=ch;
  33.      else if (n==2 || n==3)
  34.        Matriz[i][j]='*';
  35.    }
  36.  imprimir (Matriz,dim);
  37.  
  38.  borrar_char (Matriz,dim);
  39.  return EXIT_SUCCESS;
  40. }
  41.  
  42. void imprimir (char **Matriz,int dim) {
  43.    for (int i = 0; i < dim; i++) {
  44.      cout << "\t\t" ;
  45.      for (int j = 0; j < dim; j++){
  46.        cout << ' '  << Matriz[i][j] << ' ' ;
  47.      }
  48.      cout << "\n\n";
  49.    }
  50.    cout << "\n\n";
  51. }
  52.  
  53.  
  54. void colocar_minas (char **Matriz,int dim){
  55.  int **cont;
  56.  cont = new int *[dim];
  57.  for (int j = 0; j < dim; j++)
  58.    cont[j] = new int [dim];
  59.  for (int i = 0; i < dim; i++)
  60.    for (int j = 0; j < dim; j++)
  61.      cont[i][j]=0;
  62.  int numero,fil,col,k,l,contador=0;
  63.  cout << "\nIntroduzca numero de minas (numero):";
  64.  cin >> numero;
  65.  for (int i = 0; i < numero; i++){
  66.    cout << "\nColocando la mina : "<<i+1<<endl;
  67.    do{
  68.      cout << "Introduzca fila (1-numero): ";
  69.      cin >> fil;
  70.    }while(fil<1 || fil>dim);
  71.    fil=fil-1;
  72.  
  73.    do{
  74.      cout << "Introduzca columna (1-numero): ";
  75.      cin >> col;
  76.    }while(col<1 || col>dim);
  77.    col=col-1;
  78.    Matriz[fil][col]='1';
  79.    cout<<"\tM["<<fil+1<<","<<col+1<<"]="<<Matriz[fil][col]<< "\n\n";
  80.  }
  81.  imprimir (Matriz,dim);
  82.  
  83.  for ( fil = 0 ;fil < dim; fil++) {
  84.    for ( col = 0; col < dim; col++){
  85.    contador=0;
  86.      for ( k = -1; k < 2; k++) {
  87.        for ( l = -1; l < 2; l++){
  88.          if (fil+k < 0 || col+l < 0 || fil+k > dim-1 || col+l > dim-1)
  89.            continue;
  90.          else{
  91.            contador+=(Matriz[fil+k][col+l]-'0');
  92.          }
  93.        }
  94.      }
  95.      cont[fil][col]=contador;
  96.    }
  97.  }
  98.  for ( fil = 0 ;fil < dim; fil++)
  99.    for ( col = 0; col < dim; col++)
  100.      Matriz[fil][col]=cont[fil][col]+48;
  101.  borrar (cont,dim);
  102. }
  103.  
  104. void borrar_char (char **M,int dim) {
  105.  for (int i = 0; i < dim; i++)
  106.    delete[] M[i];
  107.  delete[] M;
  108. }
  109.  
  110. void borrar (int **M,int dim) {
  111.  for (int i = 0; i < dim; i++)
  112.    delete[] M[i];
  113.  delete[] M;
  114. }

Y, como ya te comentarom,  para cuando postees el código elige las etiquetas GeSHi y toma la C++ y en medio de las etiquetas Code que aparecen "pegas" tu código. Al no hacerlo de esta manera parte del código no sale correcta, especialmente las matrices.


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: xuhipoint en 8 Marzo 2014, 23:57 pm
Hola soy yo, otra vez, de verdad disculpenme si soy un poco ignorante es solo que soy de Venezuela y mi pais no vive un buen momento, por lo que se me ha dificultado ir a la universidad y recien estoy aprendiendo. Tengo este proyecto y lo poco que he aprendido ha sido por youtube o libros, asi que tenganme un poquito de paciencia si no entiendo. Hasta el momento he hecho este codigo pero en vez de pedirme solo una coordenada, me las pide toda y no me sale los ceros y los asteriscos sino solo astericos. Este es el codigo que hice hasta el momento, quizas ustedes puedan ver en que me he equivocado. Y MUCHAS GRACIAS A TODOS LOS QUE ME HAN RESPONDIDO ME HAN AYUDADO A AVANZAR UN POCO MAS EN MI PROYECTO.


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: xuhipoint en 8 Marzo 2014, 23:58 pm
Código
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7.   int matriz,bomba='*',valor;
  8.   cin >> matriz;
  9.  
  10.   // creamos la matriz !
  11.   char **M = new char *[matriz];
  12.   for (int i = 0; i != matriz; i++)
  13.      M[i] = new char [matriz];
  14.  
  15.  
  16.   for (int i = 0; i != matriz; i++){
  17.      for (int j = 0; j != matriz; j++)
  18.         M[i][j] = '0';
  19.  
  20.         for (int a=0; a<matriz; a++)
  21. {
  22.    for (int b=0; b<matriz; b++)
  23.    {
  24.        cout << endl << "Posicion [ " << a << " ] [ " << b << " ]" << endl;
  25.        cout <<  "Ingrese un valor : ";
  26.        cin >> valor;
  27.        M[a][b] = bomba;
  28.    }
  29. }
  30.  
  31.   //mostrar matriz
  32.   for (int i = 0; i != matriz; i++){
  33.      for (int j = 0; j != matriz; j++)
  34.         cout << " " << M[i][j];
  35.  
  36.      cout << endl;
  37.   }
  38. }
  39.   for (int i = 0; i != matriz; i++)
  40.      delete[] M[i];
  41.   delete[] M;
  42.  
  43.   return 0;
  44. }


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: leosansan en 9 Marzo 2014, 04:14 am

Tienes mal la introducción de los puntos.Tienes que"captar" las coordenadas a y b donde colocas las bombas, no darle valor a M[a] ya que sabes que es '*'.

Algo parecido a lo que te propuse en mi código:


Código
  1. ................
  2. cout << "\nIntroduzca numero de minas (numero):";
  3.  cin >> numero;
  4.  for (int i = 0; i < numero; i++){
  5.    cout << "\nColocando la mina : "<<i+1<<endl;
  6.    do{
  7.      cout << "Introduzca fila (1-numero): ";
  8.      cin >> fil;
  9.    }while(fil<1 || fil>dim);
  10.    fil=fil-1;
  11.  
  12.    do{
  13.      cout << "Introduzca columna (1-numero): ";
  14.      cin >> col;
  15.    }while(col<1 || col>dim);
  16.    col=col-1;
  17.    Matriz[fil][col]='*';
  18.    cout<<"\tM["<<fil+1<<","<<col+1<<"]="<<Matriz[fil][col]<< "\n\n";
  19. ...............................................
  20.  

donde fil=a y col=b. Ya sabes que Matriz[fil][col]='*'.



¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)



Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: Yoel Alejandro en 9 Marzo 2014, 21:27 pm
Hola María. Compatriota!!!, entiendo tu situación pues también soy de Vzla y es triste la situación que vivimos. Los poderosos explotando a los débiles  >:(, no importa el lado político en que se midan.

Ok, vamos por partes. Una primera recomendación sería declarar las variables contador i, j al principio del main(), y no dentro de cada ciclo. Así:

int i, j;

y de este modo ya puedes escribir

for (i = 0; i < dim; i++)

sin tener que poner "int" dentro del for. Me tomé el atrevimiento de cambiar el nombre "matriz" por "dim" porque me pareció más acorde con el significado o intención de esa variable, que es representar la dimensión de la matriz.

En esta primera parte del programa pides al usuario el tamaño o dimensión del tablero, y luego creas la matriz dinámicamente. Al principio la matriz se rellena toda con ceros, luego el programa te va pidiendo que le indiques dónde van las minas. Le indicas un '1' para decir que hay una mina en la posición indicada, o un '0' para decir que no hay mina.

Ahora creo que señalaste el problema de que es muy fastidioso preguntar por todas las casilla si sólo van 2 ó 3 bombas. Primero recuerda que el programa te tiene que pedir todas las coordenadas, ya que las minas podrían en cualquier parte. Sin embargo, si terminaste de declarar las minas antes de recorrer toda la matriz, introduce un 'x' ó un 'q' para terminar el ciclo. Eso se hace con la parte:

else if ( c == 'q' || c == 'Q' || c == 'x' || c == 'Q' )
   listo = 1;

La otra forma de trabajar sería que el programa no te pregunte por todas y cada de una de las casillas sino que te pida coordenada i, coordenada j, y valor. Ahora, yo creo que esta segunda opción sería incluso más fastidiosa (!?).

Otra manera más sería que el programa rellenara las minas aleatoriamente, también podemos hacerlo así, depende de los requerimientos de diseño, de cómo lo quieres hacer y si profesor ha puesto alguna clase de límites o condiciones.

La siguiente parte del código es donde se imprime la matriz, indicando con '*' donde hay bomba, y '0' donde no hay.

Ahora, por otra parte el programa de leosansan está muy completo, aunque no se si lo has leído, si quieres basarte en él, o si lo pudiste entender.

Unas preguntas o comentarios:
  • ¿Trabajas en Windows o Linux?
  • ¿Te permiten usar getch()?
  • Si es en Windows, ¿te permiten usar la biblioteca conio?
  • ¿Se puede usar simplemente C en lugar de C++? Me parece que la complejidad del programa no exige C++ (no lleva clases)
  • Finalmente quiero comentar que para mí la matriz puede ser de char, o de int, indistintamente. Al fin y al cabo almacena números (ceros o unos).

Aquí el código de la primera parte, que es simplemente la correción de unos pequeños detalles del que hiciste:
Código
  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8.   int dim, bomba='*', valor;
  9.   int i, j;      /* <-- declara aqui, no dentro del ciclo */
  10.   char c;
  11.   char listo;
  12.  
  13.   cout << time(NULL);
  14.   return 0;
  15.  
  16.   cout << "Tamano de la matriz: ";
  17.   cin >> dim;
  18.   cout << endl;
  19.  
  20.   /* creamos la matriz, y rellenamos con ceros */
  21.   char **M = new char *[dim];
  22.   for (i = 0; i != dim; i++)
  23.      M[i] = new char [dim];
  24.  
  25.   for (i = 0; i < dim; i++)
  26.      for (j = 0; j < dim; j++)
  27.         M[i][j] = '0';
  28.  
  29.   /* poniendo posiciones de las minas */
  30.   listo = 0;
  31.   for (i = 0; i < dim && listo == 0; i++) {
  32.      for (j = 0; j < dim && listo == 0; j++) {
  33.         cout << endl << "Posicion [ " << i << " ] [ " << j << " ]: ";
  34.         cin >> c;
  35.         if ( c == '1' )
  36.            M[i][j] = '1';
  37.         else if ( c == 'q' || c == 'Q' || c == 'x' || c == 'Q' )
  38.            listo = 1;
  39.      }
  40.   }
  41.  
  42.   // mostrar matriz
  43.   cout << endl << "La matriz es:" << endl;
  44.   for (i = 0; i != dim; i++) {
  45.      for (j = 0; j != dim; j++)
  46.         if ( M[i][j] == '1')
  47.            cout << "*\t";
  48.         else
  49.            cout << "0\t";
  50.      cout << endl;
  51.   }
  52.  
  53.   // destruye la matriz
  54.   for (i = 0; i != dim; i++)
  55.     delete[] M[i];
  56.   delete[] M;
  57.  
  58.   return 0;
  59. }


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: leosansan en 9 Marzo 2014, 22:35 pm
Hola María. Compatriota!!!, entiendo tu situación pues también soy de Vzla y es triste la situación que vivimos. Los poderosos explotando a los débiles  >:(, no importa el lado político en que se midan.


Soy CANARION, o sea de GRAN CANARIA, hermanos de ustedes los venezolanos.

Para empezar, prefiero personalmente usar la asignación dinámica de memoria para otras situaciones y usar, como en este caso, arrrays de longitud variable. Yo en este caso usaría:


Código
  1. ..........................
  2. /* creamos la matriz, y rellenamos con ceros */
  3. char M[dim][dim];
  4. for (i = 0; i < dim; i++)
  5. for (j = 0; j < dim; j++)
  6. M[i][j] = '0';
  7. ................................
  8.  

Y me dejaría de tantas historias, asignación, borrado de memoria.......

Pero, sólo un pero, busca "buscaminas" en google y así entenderás el por qué de mi código, lo de las bombas y demás.


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: Yoel Alejandro en 10 Marzo 2014, 01:29 am
Hola María. Compatriota!!!, entiendo tu situación pues también soy de Vzla y es triste la situación que vivimos. Los poderosos explotando a los débiles  >:(, no importa el lado político en que se midan.

Leo, lo que quiero decir más específicamente es que el totalitarismo de derecha (Pinochet, Franco, Mussolini) y el de izquierda (Stalin, Fidel, Chávez) son lo mismo; al final sólo pisotear y explotar al pueblo. Robar a manos llenas, porque TODOS sin importar su lado político se hacen ricos y amasan enormes fortunas en el exterior, mientras el pueblo pasa trabajo. Aunque seas un profesional, igual no te alcanza para vivir. En Venezuela estamos mal, mal, mal .... la GN reprime y maltrata a la gente, a algunos los han lesionado, quemado, golpeado, secuestrado, perdido un ojo, y otros han perdido la vida. No hay comida. No se puede salir del país porque no hay Aerolíneas (el gobierno les debe una fortuna y suspendieron el servicio) y es un problema para otorgar los dólares o euros. Así que ni soñar con visitar un días las Canarias. Por cierto, ¿cómo es la situación allá? Espero que mejor que aquí, y si pensabas venir algún día a Vzla no lo hagas en este momento porque al saber que eres extranjero capaz y te acusan de agente de la CIA y te llevan preso.

Y agradezco la solidaridad de ustedes los Canarios, yo creo que la cultura Hispana, Canaria y Latinoamericana se parece mucho. Por cierto, ¿Canarios y Españoles peninsulares se llevan bien o mal entre sí?

Respecto al buscaminas pareces adivinar porque justamente tuve que buscar en google ya que se me había olvidado como se jugaba, jaja. Corrí tu programa y perfecto!!!, ahora sólo hace falta la parte dónde se desarrolla el juego en sí, o sea, se van descubriendo las minas. Por eso le pregunté a María si se puede usar getch() ya que en ese caso el juego sería más interactivo y nos podemos ir  desplazando por directamente por las casillas en lugar que estar preguntando coordenadas  :huh:


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: xuhipoint en 10 Marzo 2014, 02:11 am
hola yoe, querido compatriota, pues si la situación de Venezuela no esta facil, creo que estamos en el peor momento. Yo solo rezo porque todo termina bien y no sigan aumentando los números de muertos, que aunque no los conozca me duelen porque son mis hermanos. Y bueno referente al proyecto solo puedo utilizar iostream y string, tengo que crear una matriz dinamica, luego ingresar el numero de minas y las coordenadas donde estaran las mismas, cubrir mi matriz y luego destaparla segun la posicion del usuario, hasta el momento este es mi codigo pero no logro poner
Código
  1. #include <iostream>
  2.  
  3.  
  4. using namespace std;
  5.  
  6. void imprimir (char **Matriz,int dim);
  7. void colocar_minas (char **Matriz,int dim);
  8.  
  9.  
  10. int main(void) {
  11.  
  12.  int dim,n;
  13.  char ch=35,sin_bomba=48;
  14.  
  15.  cout << "Introduzca la dimension de la matriz: ";
  16.  cin >> dim;
  17.  char **Matriz = new char *[dim];
  18.  for (int j = 0; j < dim; j++)
  19.    Matriz[j] = new char [dim];
  20.  for (int i = 0; i < dim; i++)
  21.    for (int j = 0; j < dim; j++)
  22.      Matriz[i][j]=sin_bomba;
  23.  
  24.  colocar_minas  (Matriz,dim);
  25.  
  26.  
  27. for (int i = 0; i < dim; i++)
  28.    for (int j = 0; j < dim; j++){
  29.      n = 1 ;
  30.      if (n<2 && Matriz[i][j]=='0')
  31.        Matriz[i][j]=ch;
  32.      else if (n==2 || n==3)
  33.        Matriz[i][j]='*';
  34.    }
  35.  
  36. }
  37.  
  38. void imprimir (char **Matriz,int dim) {
  39.  
  40.    for (int i = 0; i < dim; i++) {
  41.      cout << "\t\t" ;
  42.      for (int j = 0; j < dim; j++){
  43.        cout << ' '  << Matriz[i][j] << ' ' ;
  44.      }
  45.      cout << "\n\n";
  46.    }
  47.    cout << "\n\n";
  48. }
  49.  
  50.  
  51. void colocar_minas (char **Matriz,int dim){
  52.  int **cont,bomba=42;
  53.  cont = new int *[dim];
  54.  for (int j = 0; j < dim; j++)
  55.    cont[j] = new int [dim];
  56.  for (int i = 0; i < dim; i++)
  57.    for (int j = 0; j < dim; j++)
  58.      cont[i][j]=0;
  59.  int numero,fil,col,k,l,contador=0;
  60.  cout << "minas:";
  61.  cin >> numero;
  62.  for (int i = 0; i < numero; i++){
  63.  
  64.    do{
  65.      cout << "Introduzca fila ";
  66.      cin >> fil;
  67.    }while(fil<1 || fil>dim);
  68.    fil=fil-1;
  69.  
  70.    do{
  71.      cout << "Introduzca columna ";
  72.      cin >> col;
  73.    }while(col<1 || col>dim);
  74.    col=col-1;
  75.    Matriz[fil][col]=bomba;
  76.  
  77.    cout<<"\tM["<<fil+1<<","<<col+1<<"]="<<Matriz[fil][col]<< "\n\n";
  78.  }
  79.  imprimir (Matriz,dim);
  80.  
  81.  for ( fil = 0 ;fil < dim; fil++) {
  82.    for ( col = 0; col < dim; col++){
  83.    contador=0;
  84.      for ( k = -1; k < 2; k++) {
  85.        for ( l = -1; l < 2; l++){
  86.          if (fil+k < 0 || col+l < 0 || fil+k > dim-1 || col+l > dim-1)
  87.            continue;
  88.          else{
  89.            contador+=(Matriz[fil+k][col+l]-'0');
  90.          }
  91.        }
  92.      }
  93.      cont[fil][col]=contador;
  94.    }
  95.  }
  96.  
  97. }


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: leosansan en 10 Marzo 2014, 04:51 am
...........................................................
hasta el momento este es mi codigo pero no logro poner
.................................................

¿Qué no logras poner?.

Sabemos algo de C e incluso de C++ pero no somos pitonisos.............

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: xuhipoint en 10 Marzo 2014, 13:13 pm
Ya he modificado un poco el codigo, pero donde esta colocada la mina en vez de salir unos a su alrededor siguen saliendo asteriscos.
Código
  1. #include <iostream>
  2.  
  3.  
  4. using namespace std;
  5.  
  6. void imprimir (char **Matriz,int dim);
  7. void colocar_minas (char **Matriz,int dim);
  8.  
  9.  
  10. int main(void) {
  11.  
  12.  int dim;
  13.  char ch=35;
  14.  
  15.  cout << "Introduzca la dimension de la matriz: ";
  16.  cin >> dim;
  17.  char **Matriz = new char *[dim];
  18.  for (int j = 0; j < dim; j++)
  19.    Matriz[j] = new char [dim];
  20.  for (int i = 0; i < dim; i++)
  21.    for (int j = 0; j < dim; j++)
  22.      Matriz[i][j]='0';
  23.  colocar_minas  (Matriz,dim);
  24.  imprimir (Matriz,dim);
  25.  
  26.  for (int i = 0; i < dim; i++)
  27.    for (int j = 0; j < dim; j++){
  28.  
  29.      if (Matriz[i][j]=='0')
  30.        Matriz[i][j]=ch;
  31.      if (Matriz[i][j]=='*' )
  32.        Matriz[i][j]=ch;
  33.    }
  34. imprimir (Matriz,dim);
  35.  
  36. }
  37.  
  38. void imprimir (char **Matriz,int dim) {
  39.    for (int i = 0; i < dim; i++) {
  40.      cout << "\t\t" ;
  41.      for (int j = 0; j < dim; j++){
  42.        cout << ' '  << Matriz[i][j] << ' ' ;
  43.      }
  44.      cout << "\n\n";
  45.    }
  46.    cout << "\n\n";
  47. }
  48.  
  49.  
  50. void colocar_minas (char **Matriz,int dim){
  51.  int **cont;
  52.  cont = new int *[dim];
  53.  for (int j = 0; j < dim; j++)
  54.    cont[j] = new int [dim];
  55.  for (int i = 0; i < dim; i++)
  56.    for (int j = 0; j < dim; j++)
  57.      cont[i][j]=0;
  58.  int numero,fil,col,k,l,contador=0;
  59.  cout << "Ingrese minas:";
  60.  cin >> numero;
  61.  for (int i = 0; i < numero; i++){
  62.  
  63.    do{
  64.      cout << "Introduzca fila: ";
  65.      cin >> fil;
  66.    }while(fil<1 || fil>dim);
  67.    fil=fil-1;
  68.  
  69.    do{
  70.      cout << "Introduzca columna: ";
  71.      cin >> col;
  72.    }while(col<1 || col>dim);
  73.    col=col-1;
  74.    Matriz[fil][col]='*';
  75.  
  76.    cout<<Matriz[fil][col]<< "\n\n";
  77.  }
  78.  imprimir (Matriz,dim);
  79.  
  80.  for ( fil = 0 ;fil < dim; fil++) {
  81.    for ( col = 0; col < dim; col++){
  82.    contador=0;
  83.      for ( k = -1; k < 2; k++) {
  84.        for ( l = -1; l < 2; l++){
  85.          if (fil+k < 0 || col+l < 0 || fil+k > dim-1 || col+l > dim-1)
  86.            continue;
  87.          else{
  88.            contador+=(Matriz[fil+k][col+l]-'0');
  89.          }
  90.        }
  91.      }
  92.      cont[fil][col]=contador;
  93.    }
  94.  }
  95.  for ( fil = 0 ;fil < dim; fil++)
  96.    for ( col = 0; col < dim; col++)
  97.      Matriz[fil][col]=cont[fil][col]+48;
  98.  
  99. }
  100.  


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: eferion en 10 Marzo 2014, 13:27 pm
Código
  1.  Matriz[fil][col]='*';
  2.  
  3.  // ...
  4.  
  5.  for ( fil = 0 ;fil < dim; fil++)
  6.    for ( col = 0; col < dim; col++)
  7.      Matriz[fil][col]=cont[fil][col]+48;
  8.  

Ese bucle borra, literalmente, la posición de las minas. Deberías comprobar, antes de machacar el valor de Matriz, que la posición no contiene una mina.

Código
  1. cout << "\n\n";

Hay una constante definida en el espacio de nombres std que es endl. Tiene la ventaja de que es portable, ya que la STL en linux implementa su versión de endl y Windows hace lo propio.

Es más portable usar lo siguiente:

Código
  1. cout << endl << endl;

Más cosas...

Código
  1. for ( fil = 0 ;fil < dim; fil++) {
  2.    for ( col = 0; col < dim; col++){
  3.    contador=0;
  4.      for ( k = -1; k < 2; k++) {
  5.        for ( l = -1; l < 2; l++){
  6.          if (fil+k < 0 || col+l < 0 || fil+k > dim-1 || col+l > dim-1)
  7.            continue;
  8.          else{
  9.            contador+=(Matriz[fil+k][col+l]-'0');
  10.          }
  11.        }
  12.      }
  13.      cont[fil][col]=contador;
  14.    }
  15.  }

contador += ¿¿que??
A ver, si en Matriz las minas se representan con asteriscos... por qué no buscas asteriscos para contarlos?? la transformación que estás haciendo ahí no tiene ningún sentido. Dicho de otra forma:

Código:
'*'-'0' == '#'

¿Te suena el caracter '#' si solo pones una mina? Ya sabes de dónde sale.


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: leosansan en 10 Marzo 2014, 13:43 pm
Se te fue un gazapo en el código:

Código
  1. do{
  2.      cout << "Introduzca columna: ";
  3.      cin >> col;
  4.    }while(col<1 || col>dim);
  5.    col=col-1;
  6.    Matriz[fil][col]='*'; /* <==AQUI */ /*ES ==>  */Matriz[fil][col]='1';
  7.  
  8.    cout<<Matriz[fil][col]<< "\n\n";
  9.  


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)



Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: eferion en 10 Marzo 2014, 13:58 pm
Se te fue un gazapo en el código:

Código
  1. do{
  2.      cout << "Introduzca columna: ";
  3.      cin >> col;
  4.    }while(col<1 || col>dim);
  5.    col=col-1;
  6.    Matriz[fil][col]='*'; /* <==AQUI */ /*ES ==>  */Matriz[fil][col]='1';
  7.  
  8.    cout<<Matriz[fil][col]<< "\n\n";
  9.  


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)



Pero ese cambio tiene un problema... que luego cuando vaya a contar... cómo identifica la posición original de la mina??

Pongamos el caso:

Código:
1 1 0
0 0 0
0 0 0
0 0 0

Después de calcular las minas se tiene

Código:
1 1 1
1 1 1
0 0 0

Eso es incorrecto porque lo lógico es que la salida fuese

Código:
1 * 1 
1 1 1
0 0 0

Si no marcas dónde están las minas mal vamos.


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: leosansan en 10 Marzo 2014, 14:11 pm
Amigo eferion habrá que repasar el juego del buscaminas y, por favor, no tergiversar o copiar bien el código que cuelgo.

De acuerdo a mi código, un par de mensajes anteriores a este, una salida sería:


Citar
Introduzca la dimension de la matriz: 3

Introduzca numero de minas (numero):2

Colocando la mina : 1
Introduzca fila (1-numero): 1
Introduzca columna (1-numero): 1
        M[1,1]=1


Colocando la mina : 2
Introduzca fila (1-numero): 1
Introduzca columna (1-numero): 2
        M[1,2]=1

                 1  1  0

                 0  0  0

                 0  0  0

 

                 2  2  1

                 2  2  1

                 0  0  0


                
                2  *  1

                2  2  *

                █  *  *
*



Otro ejemplo:


 1  0  0  0  0

 1  0  0  0  0

 0  0  0  0  1

 0  0  0  0  0

 0  0  0  0  0



 2  2  0  0  0

 2  2  0  1  1

 1  1  0  1  1

 0  0  0  1  1

 0  0  0  0  0



 2  2  █  █  █

 *  2  *  *  *

 *  1  █  1  1

 *  *  *  *  1

 *  █  █  *  █




En la matriz del juego cada casilla se obtiene sumando las minas que tiene alrededor.

La primera matriz anterior es donde están colocadas las minas, la segunda matriz es la que resulta de sumar a cada casilla las ocho, como máximo, que le rodean y la tercera fue una improvisación de ocultar algunas de las casillas. Como ves las matrices tienen toda su lógica con arreglo a las reglas del juego.



¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)

REEDITADIDO:

.................................................................
contador += ¿¿que??
A ver, si en Matriz las minas se representan con asteriscos... por qué no buscas asteriscos para contarlos?? la transformación que estás haciendo ahí no tiene ningún sentido. Dicho de otra forma:

Código:
'*'-'0' == '#'

¿Te suena el caracter '#' si solo pones una mina? Ya sabes de dónde sale.[/size]

* Los asteriscos no representan las minas sino los 1 de la matriz inicial. Los asteriscos son para ocultar información.

* El cuadrado que sale es porque en el juego parte del tablero no es seleccionable.

* contador+= él más los que tiene alrededor.

*  '#' no es '*'-'0' sino el caracter '35' que xuhipoint estimó coger, no sé por qué diablos lo hizo.


Observar la siguiente captura de un juego del buscaminas:

(http://i1280.photobucket.com/albums/a497/leosansan/buscaminasgame_zps709cb97b.jpg)

Se ve que en ciertas casillas salen números, las minas totales de él y los que le rodean, otras casillas están levantadas y serían el equivalente a los ateriscos, hay que seleccionar y que no te estalle una mina y, por último, hay otras casillas que son planas, las que no intervienen en el juego, no se puede picar en ellas, o sí se puede pero no aportan nada.



Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: eferion en 10 Marzo 2014, 15:06 pm
Se ve que en ciertas casillas salen números, las minas totales de él y los que le rodean, ...

Dudo mucho que en el buscaminas puedas encontrar una casilla con el número 9 ( 8 que le rodean más la mina de la propia casilla )


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: leosansan en 10 Marzo 2014, 16:21 pm
Dudo mucho que en el buscaminas puedas encontrar una casilla con el número 9 ( 8 que le rodean más la mina de la propia casilla )



Fíjate en los ejemplos, los números son más bien bajos.

Es un juego y si lo haces entrando a mano las minas "puede" darse el caso, aunque sería tonto ya que declaras a todas las que le rodean como minas. Por eso se eligen las minas más separadas, lo que da como resultado números  bajos para crear mayor incertidumbre.



¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/simba2.gif)



Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: eferion en 10 Marzo 2014, 17:11 pm
En un buscaminas, si abres una mina el programa sabe que ahí hay mina y termina el juego... no te sale un número.

La versión que propones incapacita al juego para detectar las minas y las sustituye por números.

No digo que esté mal... es otro enfoque... pero yo diría que lo suyo es que el programa conociese en todo momento la ubicación de las minas.

O eso o me estoy perdiendo algo.


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: leosansan en 10 Marzo 2014, 20:41 pm
1 En un buscaminas, si abres una mina el programa sabe que ahí hay mina y termina el juego... no te sale un número.

2 La versión que propones incapacita al juego para detectar las minas y las sustituye por números.

3 No digo que esté mal... es otro enfoque... pero yo diría que lo suyo es que el programa conociese en todo momento la ubicación de las minas.

O eso o me estoy perdiendo algo.


Efectivamente, de acuerdo en el primer punto. Por ejemplo en esta situación:

Citar


       *  2  1  *  0

       *  2  *  2  1

       *  1  *  2  *

       1  *  2  1  1

       *  *  *  0  *



si el jugador elige la posición (2,3) ¡¡¡BOOMMM!!!!, salta una mina. Y por qué lo sé, porrque tengo previamente la matriz de las posiciones de las minas, lo que responde a tu segundo punto:

Citar

        1  0  0  0  0

        0  0  1  0  0

        0  0  0  1  0

        0  0  0  0  0

        0  1  0  0  0





Fíjate en la imagen de la respuesta anterior del juego que salen números, como en el mío, casillas levantadas=asteriscos y casillas planas=cuadraditos. Pero lo que yo propongo es un camino para que él termine la tarea, no hacerlo yo todo.

Como ves mi enfoque no está descaminado. como alegas en tu tercer punto.

Pero lo que no iba yo es a hacerle toda la tarea. Quedaba para él guardar la primera matriz, para no perder la situación de las minas originalmente, y usar otra para el engaño, así como el tema de pedir las coordenadas para el juego propiamente.

Tan sólo es un esbozo del juego, aunque creo que me animaré a terminarlo para el nietillo.

Y no, no te estabas perdiendo nada. Era un inicio de la tarea que tenía que realizar xuhipoint , yo sólo pretendía desatascarle el arranque.




¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: Yoel Alejandro en 11 Marzo 2014, 02:42 am
Ojo, leosansan, no había leído bien los mensajes previos tuyos y de eferion, sin embargo para que no haya confusión aclaro que en el juego que diseñé los asteriscos son MINAS.

Es más, voy a tener que usar unos #defines para especificar los distintos símbolos, así se pueden cambiar facílito de una versión a otra, jajaja

Yo no tengo en el mío casillas bloqueadas (inseleccionables), aunque esa funcionalidad se puede añadir.

En todo lo demás que has dicho sobre las características del juego buscaminas real, estoy de acuerdo!


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: Yoel Alejandro en 11 Marzo 2014, 08:08 am
María, llega un momento en que la complejidad de un programa crece hasta que termina enredándose uno mismo en su propio trabajo, jeje. Para evitar eso debes trabajar de manera modular, es decir, divide el programa en pequeñas partes funcionales que puedan integrarse entre sí.

Ahora hago unos comentarios. Es muy válida la recomendación de eferion, si estás en C++ usa endl en lugar de '\n'. Por otra parte perdón a los que puedan discrepar pero me parece más lógico que la matriz sea considerada de enteros y no de char, pues al fin y al cabo contendrá números (1 si hay bomba, 0 si no hay). Soy partidario de que una función auxiliar sea la encargada de decidir qué caracteres se van a mostrar en pantalla, en lugar de que dichos caracteres sean almacenados directamente en la matriz. Y como verás, este enfoque te evitar tener que hacer conversiones y operaciones complicadas como:

Matriz[fil][col]=cont[fil][col]+48;   (????????)


Tomando como base el código que presentaste, y depurándolo eliminé unas cuántas líneas redundantes por aquí y por allá, también como te dije sacar del main() rutinas que pueden definirse aparte, hasta quedar un procedimiento principal breve, limpio y sencillo (como debe ser):
Código
  1. int main(void) {
  2.  
  3.   int dim;
  4.   int i, j;
  5.  
  6.   cout << "Introduzca la dimension de la matriz: ";
  7.   cin >> dim;
  8.  
  9.   int **A = new int *[dim];
  10.   for (i = 0; i < dim; i++)
  11.      A[i] = new int [dim];
  12.   for (i = 0; i < dim; i++)
  13.      for (int j = 0; j < dim; j++)
  14.         A[i][j] = 0;
  15.  
  16.   /* indicar donde van las minas, e imprimir */      
  17.   colocar_minas( A, dim);
  18.   imprimir( A, dim, 1);
  19.  
  20.   /* descubrir las casillas */
  21.   descubrir_casillas( A, dim);
  22. }
donde me tomé el atrevimiento de cambiar el nombre "Matriz" por simplemente "A".

Ahora, la función auxuliar de colocar las minas se encarga de rellenar la matriz (en lugar de hacerlo el main()). En lo particular me pareció un poco pesado e innecesario que el usuario tenga que decir de antemano cuántas bombas hay. En lugar de ello lo modifiqué para que él te vaya preguntando si quieres meter otra mina, y sigue hasta que respondas 'n'. El código:
Código
  1. void colocar_minas (int **A, int dim) {
  2.  
  3.   int i, fil, col;
  4.   char op;
  5.  
  6.   cout << endl << "*** Colocando las minas ***" << endl << endl;
  7.  
  8.   op = 's';
  9.   do {
  10.      do {
  11.         cout << "Introduzca fila: ";
  12.         cin >> fil;
  13.      } while (fil < 1 || fil > dim);
  14.      fil = fil - 1;
  15.  
  16.      do {
  17.         cout << "Introduzca columna: ";
  18.         cin >> col;
  19.      } while (col < 1 || col > dim);
  20.      col = col - 1;
  21.  
  22.      A[fil][col] = 1;
  23.  
  24.      /* imprimimos, para que el usuario vea como va quedando */
  25.      imprimir( A, dim, 0);
  26.  
  27.      do {
  28.         cout << "Otro? s/n: ";
  29.         cin >> op;
  30.      } while ( op != 's' && op != 'S' && op != 'n' && op != 'N' );
  31.  
  32.   } while ( op == 's' || op == 'S' );
  33. }

También me pareció más adecuado separar la utilidad de contar las minas que rodean una casilla en una función aparte int contar_minas( int **A, int dim, int i, int j ).

Ahora vamos a la parte delicada, y lo que creó el meollo: si en la matriz reemplazas el valor de cada casilla (1 si hay bomba y 0 si no hay) por la suma de las casillas adyacentes, entonces pierdes el valor original. ¿Cómo hacer? Una solución sería crear dos matrices, pero desperdicia espacio de memoria. Otra alternativa es modificar la función:

imprimir(int **A, int dim, int estilo)

que recibe una matriz A de 1's y 0's, pero donde el tercer argumento estilo permite definir tres modos posibles de funcionamiento:
  • estilo = 0, hace que se imprima '*' donde hay bomba y '0' donde no hay
  • estilo = 1, hace que se impriman las sumas de las casillas circundantes, en lugar de bomba/no-moba
  • estilo = 2, es para cuando el usuario va descubriendo las casillas. Imprime la suma circundante si la casilla no ha sido destapada, '0' si ha sido destapada y no hay bomba, y '*' si se destapó y hay una bomba (el juego termina).
La idea es usar el estilo 0 cuando estás rellenando la matriz, el 1 cuando terminaste de llenar, y el 2 cuando vas destapando las casillas. Pero resumes los tres en una sola función, de un modo sintético y elegante.

Sin embargo surge un problema delicado. Si una casilla no tiene bomba y no ha sido destapada se representa por la suma circundante. Pero si no tiene bomba y ha sido destapada, se representa por un '0'. ¿Cómo distinguir un caso de otro? Como dije antes una solución (ineficiente) es crear una segunda matriz que se vaya actualizando según las casillas que el usuario vaya descubriendo.
Mejor es apelar a un "truco" que usamos los programadores. Si miras bien, hasta ahora hemos usado 2 valores posibles para cada celda de la matriz A, esto es, 0 y 1. Quedan otros valores disponibles, con los que podemos representar otros significados. Podríamos asignar el valor -1 para la casilla que tenga una bomba que ha sido descubierta (boom!!, termina el juego), y el 2 para la casilla que ha sido destapada y no tiene bomba. Así quedaría:
  • A[ i][j] = -1, si hay una bomba y fue destapada (termina el juego)
  • A[ i][j] = 0, si no hay bomba, y no ha sido destapada
  • A[ i][j]) = 1, si hay bomba, pero no ha sido destapada
  • A[ i][j] = 2, si no hay bomba, y fue destapada
La función de imprimir, con las tres posibilidades quedaría:
Código
  1. void imprimir( int **A, int dim, int estilo) {
  2.  
  3.   int i, j;
  4.  
  5.   for (i = 0; i < dim; i++) {
  6.   cout << "\t\t" ;
  7.      for (j = 0; j < dim; j++) {
  8.         /* aqui decidimos como queremos imprimir */
  9.         switch (estilo) {
  10.            /* solo mina / no-mina */
  11.            case 0:
  12.               if ( A[i][j] == 1 )
  13.                  cout << " * ";
  14.               else
  15.                  cout << " 0 ";
  16.               break;
  17.            /* contar las minas que rodean */
  18.            case 1:
  19.               cout << ' ' << contar_minas( A, dim, i, j ) << ' ';
  20.               break;
  21.            /* a medida se van descubriendo las minas */
  22.            case 2:
  23.               if ( A[i][j] == -1 )
  24.                  cout << " * ";      /* boom, jeje */
  25.               else if ( A[i][j] == 0 || A[i][j] == 1 )  
  26.                  cout << ' ' << contar_minas( A, dim, i, j ) << ' ';
  27.               else if ( A[i][j] == 2 )
  28.                  cout << " 0 ";
  29.            break;
  30.         }
  31.      }
  32.      cout << endl << endl;
  33.   }
  34.   cout << endl << endl;
  35. }

Ahora, hay que tener cuidado cuando codificamos la función de sumar los adyacentes. Recuerda que se debe sumar cualquier bomba (destapada o no) o sea, el valor 1 ó -1 en la matriz. Por lo tanto:
Código
  1. /* Cuenta la cantidad de minas que rodean a una posicion dada de la matriz,
  2.  * incluyendo al elemento propio */
  3. int contar_minas( int **A, int dim, int i, int j ) {
  4.  
  5.   int k, l, contador;
  6.  
  7.   contador = 0;
  8.   for ( k = -1; k < 2; k++) {
  9.      for ( l = -1; l < 2; l++) {
  10.         if (i+k >= 0 && j+l >= 0 && i+k < dim && j+l < dim)
  11.            if ( A[i+k][j+l] == 1 || A[i+k][j+l] == -1)
  12.               contador ++;
  13.      }
  14.   }
  15.  
  16.   return contador;
  17. }

Ya lo que quedaría sería definir la función que permite al usuario ir destapando las casillas a su gusto. Si destapa una bomba, pierde. De lo contrario, el juego continúa hasta que destapa todas las que no tienen bomba en cuyo caso gana. Este código te lo muestro al final, junto con el programa completo.

El código a continuación ya es funcional, está listo para copiar, compilar y ejecutar.

NOTA. Téngase en cuenta que en el juego buscaminas real hay características que nuestro programa aún no posee.

Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. void imprimir (int **A, int dim, int estilo);
  6. void colocar_minas (int **A, int dim);
  7. int contar_minas (int **A, int dim, int i, int j);
  8. void descubrir_casillas (int **A, int dim);
  9.  
  10. int main(void) {
  11.  
  12.   int dim;
  13.   int i, j;
  14.  
  15.   cout << "Introduzca la dimension de la matriz: ";
  16.   cin >> dim;
  17.  
  18.   int **A = new int *[dim];
  19.   for (i = 0; i < dim; i++)
  20.      A[i] = new int [dim];
  21.   for (i = 0; i < dim; i++)
  22.      for (int j = 0; j < dim; j++)
  23.         A[i][j] = 0;
  24.  
  25.   /* indicar donde van las minas, e imprimir */      
  26.   colocar_minas( A, dim);
  27.   imprimir( A, dim, 1);
  28.  
  29.   /* descubrir las casillas */
  30.   descubrir_casillas( A, dim);
  31. }
  32.  
  33. /* Permite al usuario ir colocando las minas. Para seguir colocando,
  34.  * responder 's' al final, de lo contrario termina. */
  35. void colocar_minas (int **A, int dim){
  36.  
  37.   int i, fil, col;
  38.   char op;
  39.  
  40.   cout << endl << "*** Colocando las minas ***" << endl << endl;
  41.  
  42.   op = 's';
  43.   do {
  44.      do {
  45.         cout << "Introduzca fila: ";
  46.         cin >> fil;
  47.      } while (fil < 1 || fil > dim);
  48.      fil = fil - 1;
  49.  
  50.      do {
  51.         cout << "Introduzca columna: ";
  52.         cin >> col;
  53.      } while (col < 1 || col > dim);
  54.      col = col - 1;
  55.  
  56.      A[fil][col] = 1;
  57.  
  58.      /* imprimimos, para que el usuario vea como va quedando */
  59.      imprimir( A, dim, 0);
  60.  
  61.      do {
  62.         cout << "Otro? s/n: ";
  63.         cin >> op;
  64.      } while ( op != 's' && op != 'S' && op != 'n' && op != 'N' );
  65.  
  66.   } while ( op == 's' || op == 'S' );
  67. }
  68.  
  69. /* Imprime la matriz en varios estilos:
  70.  *
  71.  *  0: Indican simplemente donde hay minas y donde no.
  72.  *  1: Indica cuantas minas rodean a cada casilla (incluyendo a si misma)
  73.  *  2: Como se muestra a medida que se descubren las casillas.
  74.  *     El valor -1 imprime una bomba, para los valores entre 0 y 9 imprimen
  75.  *     la suma circundante, y el 10 se imprime como 0.
  76.  */
  77. void imprimir( int **A, int dim, int estilo) {
  78.  
  79.   int i, j;
  80.  
  81.   for (i = 0; i < dim; i++) {
  82.   cout << "\t\t" ;
  83.      for (j = 0; j < dim; j++) {
  84.         /* aqui decidimos como queremos imprimir */
  85.         switch (estilo) {
  86.            /* solo mina / no-mina */
  87.            case 0:
  88.               if ( A[i][j] == 1 )
  89.                  cout << " * ";
  90.               else
  91.                  cout << " 0 ";
  92.               break;
  93.            /* contar las minas que rodean */
  94.            case 1:
  95.               cout << ' ' << contar_minas( A, dim, i, j ) << ' ';
  96.               break;
  97.            /* a medida se van descubriendo las minas */
  98.            case 2:
  99.               if ( A[i][j] == -1 )
  100.                  cout << " * ";      /* boom, jeje */
  101.               else if ( A[i][j] == 0 || A[i][j] == 1 )  
  102.                  cout << ' ' << contar_minas( A, dim, i, j ) << ' ';
  103.               else if ( A[i][j] == 2 )
  104.                  cout << " 0 ";
  105.            break;
  106.         }
  107.      }
  108.      cout << endl << endl;
  109.   }
  110.   cout << endl << endl;
  111. }
  112.  
  113. /* Cuenta la cantidad de minas que rodean a una posicion dada de la matriz,
  114.  * incluyendo al elemento propio */
  115. int contar_minas( int **A, int dim, int i, int j ) {
  116.  
  117.   int k, l, contador;
  118.  
  119.   contador = 0;
  120.   for ( k = -1; k < 2; k++) {
  121.      for ( l = -1; l < 2; l++) {
  122.         if (i+k >= 0 && j+l >= 0 && i+k < dim && j+l < dim)
  123.            if ( A[i+k][j+l] == 1 || A[i+k][j+l] == -1)
  124.               contador ++;
  125.      }
  126.   }
  127.  
  128.   return contador;
  129. }
  130.  
  131. /* Permite al usuario ir descubriendo casillas del tablero, y si se
  132.  * encuentra una mina, pierde !!! */
  133. void descubrir_casillas( int **A, int dim ) {
  134.  
  135.   int i, j;
  136.   char terminar;
  137.  
  138.   cout << endl << "*** Ahora descubriendo las casillas ***" << endl << endl;
  139.  
  140.   imprimir( A, dim, 2);
  141.  
  142.   terminar = 'n';
  143.   do {
  144.      do {
  145.         cout << "Introduzca fila: ";
  146.         cin >> i;
  147.      } while (i < 1 || i > dim);
  148.      i = i - 1;
  149.  
  150.      do {
  151.         cout << "Introduzca columna: ";
  152.         cin >> j;
  153.      } while (j < 1 || j > dim);
  154.      j = j - 1;
  155.  
  156.      if ( A[i][j] == 1) {
  157.         /* encuentra mina: pierde !!! */
  158.         A[i][j] = -1;
  159.         imprimir( A, dim, 2 );
  160.         cout << endl << "Boom!!!, ha perdido" << endl;
  161.         terminar = 's';
  162.      }
  163.      else {
  164.         /* sigue jugando */
  165.         A[i][j] = 2;
  166.         imprimir( A, dim, 2 );
  167.      }
  168.  
  169.      /* Nota: 0 significa casilla sin bomba y sin descubrir.
  170.        *       2 significa casilla sin bomba y ya descubierta.
  171.       /* El programa termina si no quedan por descubrir casillas
  172.        * sin bombas (casillas con el valor 0) */
  173.      if ( terminar == 'n' ) {
  174.         terminar = 's';
  175.         for (i = 0; terminar == 's' && i < dim; i++)
  176.            for (j = 0; terminar == 's' && j < dim; j++)
  177.               if ( A[i][j] == 0 ) terminar = 'n';
  178.  
  179.         if ( terminar == 's' ) {
  180.            cout << endl << "Felicitaciones, ha ganado !!!" << endl;
  181.            imprimir( A, dim, 0);
  182.         }
  183.      }
  184.  
  185.   } while ( terminar == 'n' );
  186. }


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: leosansan en 11 Marzo 2014, 11:25 am
Sólo un detalle, el autor del tema quería que el usuario introdujera las minas, de ahí mi propuesta.

Y te recuerdo lo que le comenté a eferion, no se trata de hacerle la tarea al que inició el tema sino de resolverle dudas y orientarlo. Ya luego él debe elegir el camino correcto, de ahí que mis códigos sean casi iguales al de los autores del tema pero funcionales, es decir con los errores corregidos y aclaradas las dudas. Esa es una cosa que me diferencia de otros usuarios, yo suelo contestar con código en lugar de con orientaciones, que la mayor parte de las veces les deja en el limbo, o con enlaces. Como ya comenté una vez, lo que nos parece trivial para algunos, para otros les puede resultar un muro insalvable.

En ningún momento me plantearía resolverlo como propone el autor, ni siquiera tú que indirectamente has seguido mi estela, que era la del autor original, sería "otra cosa".

Otra cosa son las llamadas "aportaciones" que algunos usuario decidan hacer, como es tu caso. Ahí si hay un nivel de exigencia mayor ya que se trata de código propio y se espera de él que esté a la altura de nuestras expectativas.


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: eferion en 11 Marzo 2014, 11:29 am
Jejejeje.

A mí es que me da muchísima pereza ponerme a escribir código cuando veo que el que pregunta no ha puesto ni un mísero main :).

Cuando veo que el autor del hilo se lo ha currado un mínimo y no ha puesto código copiado ( a veces canta mucho ), la cosa cambia y me vuelco más.

Eso sí, hay veces que me levanto con mejor humor y no tengo problemas en escribir el quijote si hace falta. Pero por norma general...


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: xuhipoint en 12 Marzo 2014, 00:18 am
Haber primero quiero agradecer a todas las personas que me ayudaron aun sin conocerme o pedirme nada a cambio, ese fue uno de los motivos por los cuales elegí esta carrera me gusta como se ayudan entre si. Segundo yo jamas he sido de las personas que se copia un código, soy e las personas que les gusta hacer las cosas por ella misma, ser independiente. Tercero vine aquí por una asesoría, JAMAS DIJE HÁGANME LA TAREA,  y si eso fue lo que di a entender me disculpo. Cuarto, aunque parezca que no entiendo nada y casi piso lo ignorante, no es porque yo quiera ser así, solo esta tarea me fui enviada por un correo no he podido ni ver a mis profesores con la situación que vive mi país, no es porque yo me quede en mi casa sentada viendo televisión, he salido aun con bombas lagrimogenas a la universidad, para tener un mejor futuro y poderte ir porque la patria que te vio nacer hoy no puedes vivir en ella, y con el no saber si regresas a tu casa, porque por el solo hecho de ser estudiante te maltratan, los que se suponen deben defenderte. Y para finalizar quiero dejar claro que no tengo pensado utilizar el código envidado por yoel, me engañaría a mi misma, yo he ido creando mi propio código con las recomendaciones que me han escrito. Bueno con esto me despido de ustedes y nuevamente gracias a todas las personas que aportaron ideas.


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: Yoel Alejandro en 12 Marzo 2014, 01:04 am
Ok xuhipoint, pero por favor mantennos al tanto de lo que has hecho y cómo va funcionando. Es la manera de corresponder a los que nos hemos involucrado en este tema, y quisiéramos saber que lo has terminado y si te ha ido bien  :D.

Yo me uní a este foro porque precisamente rescata el espíritu anteriormente prevaleciente entre la comunidad de programadores, que era la solidaridad (bueno, hasta que llegó Microsoft y echó a perder todo, jaja). Es la misma filosofía GNU. Los programadores debemos ser personas sumamente humanitarias.

Ahora, pienso que un programa de esta complejidad, aunque para nosotros no parezca mucho, sí lo es para alguien que esté comenzando. Lleva asignación dinámica de memoria, manejo de matrices, elementos delicados donde si te pones a trabajar en "solitario" te vas a enredar y equivocar. No está mal que recibir ayuda.

Así que por favor ten en cuenta las recomendaciones generales que te hemos hecho. Todos hemos pasado por lo mismo y ya ganamos experiencia con ésto. En particular, yo señalaría con mucho énfasis:

  • Modulariza el código. De otro modo terminas teniendo lo que se llama "espagueti". Por ejemplo, en la función de asignar las minas tenías que ahí mismo calculabas cuántas minas rodeaban una casilla para mostrar las sumas. Así llegabas a tener cuatro (4) ciclos anidados, un for dentro de for, dentro de for, dentro de for, y empieza a volverse complicado. Debes tener una función exclusiva para colocar las minas, otra par sumar las minas adyacentes, otra para imprimir la matriz, etc. "Divide y vencerás".
  • El formato de declaración for (int i = 0 ....) donde el tipo de la variable contador está "auto-declarado" en lo particular me parece algo desaconsejable aquí. Tengo entendido (no se si me equivoco) que primero ésto es sólo válido en C99, y segundo al hacer ésto la "vida" o alcance de la variable es sólo dentro del bloque o ciclo en cuestión donde se declara, por lo que no puedes reutilizar el contador en otra parte del código. Declara las variables contador al inicio de la definición de la función.
  • Decide para los elementos de la matriz un tipo "consistente" de datos, que luego no tengas que estarlo cambiando o transformando. Si es char, que sea char. Si en entero, que sea entero. Pero no que sea char, el cual luego lo estás transformando a entero, y de nuevo a char, etc. Esto es fuente probable de errores, es inseguro, y por un pequeño descuido te puede echar a perder todo el programa.

Esto es en general lo que puedo comentar. Trabaja como quieras, pero sigue dichos consejos y no se si leosansan y eferion quieren añadir otros basados en su experiencia.


Título: Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?
Publicado por: Yoel Alejandro en 12 Marzo 2014, 01:17 am
... de ahí que mis códigos sean casi iguales al de los autores del tema pero funcionales, es decir con los errores corregidos y aclaradas las dudas. Esa es una cosa que me diferencia de otros usuarios, yo suelo contestar con código en lugar de con orientaciones, que la mayor parte de las veces les deja en el limbo, o con enlaces. Como ya comenté una vez, lo que nos parece trivial para algunos, para otros les puede resultar un muro insalvable.

Totalmente de acuerdo leosansan, pienso que hay que ser respetuoso con la línea original trazada por el usuario, y no procurar cambiársela sino mejorársela. Esto implica un compromiso delicado, pues a veces si por nosotros fuera le añadiríamos las mil y una cosas pero el autor no va a entender nada, jaja. Hay que agregar las mejoras pero siempre al alcance de la comprensión del usuario, y no de una forma que desnaturalice por completo la idea original del autor.

Y sí, a veces como "una imagen vale más que mil palabras", se tiene que "una línea de código vale más que mil palabras". Uno se da a entender mejor de esta manera en lugar de que te digan "anda a tal página web" y cuando vas no tiene la menor relación con lo que buscas  >:( >:(, o al menos a mí me ha pasado eso.

Yo creo que se trata de hacer a los demás como harías contigo mismo. Muchas veces me he beneficiado de los aportes de otras personas en la web, y lo que estoy haciendo aquí es básicamente agradecer esa ayuda que he recibido. De eso se trata la solidaridad humana, y es la ÚNICA vía que mejorará al planeta, sólo que la gente no tiene fe y a veces son muy pocos los que están dispuestos a dar su grano de arena por otra persona, .... pero no importa, ánimo y a seguir trabajando  :D

===============================

POR CIERTO, se han dado cuenta que el tema ha sido veces 693 veces hasta el momento ?. Se está haciendo popular !!!