Matriz Dinamica en c++. Como rellenarla en coordenadas especificas?

Iniciado por xuhipoint, 8 Marzo 2014, 04:43 AM

0 Miembros y 2 Visitantes están viendo este tema.

xuhipoint

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;
}

rir3760

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 (cpp) [Seleccionar]
#include <iostream>
#include <string>
using namespace std;

int main()
{
   int matriz;
   cin >> matriz;
   
   // creamos la matriz !
   char **M = new char *[matriz];
   for (int i = 0; i != matriz; i++)
      M[i] = new char [matriz];
   
   // Asignacion, solo un ejemplo
   for (int i = 0; i != matriz; i++)
      for (int j = 0; j != matriz; j++)
         M[i][j] = '*';
   
   //mostrar matriz
   for (int i = 0; i != matriz; i++){
      for (int j = 0; j != matriz; j++)
         cout << " " << M[i][j];
   
      cout << endl;
   }
   
   for (int i = 0; i != matriz; i++)
      delete[] M[i];
   delete[] M;
   
   return 0;
}


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

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

xuhipoint

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

xaps

Cita de: xuhipoint en  8 Marzo 2014, 12:54 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
"The programmers of tomorrow are the wizards of the future" - Gave Newel

leosansan

#4
Cita de: 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


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:



Código (cpp) [Seleccionar]

#include <iostream>
#include <cstdlib>
#include <time.h>

using namespace std;

void imprimir (char **Matriz,int dim);
void colocar_minas (char **Matriz,int dim);
void borrar (int **M,int dim);
void borrar_char (char **M,int dim);

int main(void) {
 srand((unsigned) time(NULL));
 int dim,n;
 char ch=219;

 cout << "Introduzca la dimension de la matriz: ";
 cin >> dim;
 char **Matriz = new char *[dim];
 for (int j = 0; j < dim; j++)
   Matriz[j] = new char [dim];
 for (int i = 0; i < dim; i++)
   for (int j = 0; j < dim; j++)
     Matriz[i][j]='0';
 colocar_minas  (Matriz,dim);
 imprimir (Matriz,dim);

 for (int i = 0; i < dim; i++)
   for (int j = 0; j < dim; j++){
     n = rand() % 5 ;
     if (n<2 && Matriz[i][j]=='0')
       Matriz[i][j]=ch;
     else if (n==2 || n==3)
       Matriz[i][j]='*';
   }
 imprimir (Matriz,dim);

 borrar_char (Matriz,dim);
 return EXIT_SUCCESS;
}

void imprimir (char **Matriz,int dim) {
   for (int i = 0; i < dim; i++) {
     cout << "\t\t" ;
     for (int j = 0; j < dim; j++){
       cout << ' '  << Matriz[i][j] << ' ' ;
     }
     cout << "\n\n";
   }
   cout << "\n\n";
}


void colocar_minas (char **Matriz,int dim){
 int **cont;
 cont = new int *[dim];
 for (int j = 0; j < dim; j++)
   cont[j] = new int [dim];
 for (int i = 0; i < dim; i++)
   for (int j = 0; j < dim; j++)
     cont[i][j]=0;
 int numero,fil,col,k,l,contador=0;
 cout << "\nIntroduzca numero de minas (numero):";
 cin >> numero;
 for (int i = 0; i < numero; i++){
   cout << "\nColocando la mina : "<<i+1<<endl;
   do{
     cout << "Introduzca fila (1-numero): ";
     cin >> fil;
   }while(fil<1 || fil>dim);
   fil=fil-1;

   do{
     cout << "Introduzca columna (1-numero): ";
     cin >> col;
   }while(col<1 || col>dim);
   col=col-1;
   Matriz[fil][col]='1';
   cout<<"\tM["<<fil+1<<","<<col+1<<"]="<<Matriz[fil][col]<< "\n\n";
 }
 imprimir (Matriz,dim);

 for ( fil = 0 ;fil < dim; fil++) {
   for ( col = 0; col < dim; col++){
   contador=0;
     for ( k = -1; k < 2; k++) {
       for ( l = -1; l < 2; l++){
         if (fil+k < 0 || col+l < 0 || fil+k > dim-1 || col+l > dim-1)
           continue;
         else{
           contador+=(Matriz[fil+k][col+l]-'0');
         }
       }
     }
     cont[fil][col]=contador;
   }
 }
 for ( fil = 0 ;fil < dim; fil++)
   for ( col = 0; col < dim; col++)
     Matriz[fil][col]=cont[fil][col]+48;
 borrar (cont,dim);
}

void borrar_char (char **M,int dim) {
 for (int i = 0; i < dim; i++)
   delete[] M[i];
 delete[] M;
}

void borrar (int **M,int dim) {
 for (int i = 0; i < dim; i++)
   delete[] M[i];
 delete[] M;
}


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! ..... !!!!



xuhipoint

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.

xuhipoint

Código (cpp) [Seleccionar]
#include<iostream>
#include<string>
using namespace std;

int main()
{
   int matriz,bomba='*',valor;
   cin >> matriz;

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

   
   for (int i = 0; i != matriz; i++){
      for (int j = 0; j != matriz; j++)
         M[i][j] = '0';
         
         for (int a=0; a<matriz; a++)
{
    for (int b=0; b<matriz; b++)
    {
        cout << endl << "Posicion [ " << a << " ] [ " << b << " ]" << endl;
        cout <<  "Ingrese un valor : ";
        cin >> valor;
        M[a][b] = bomba;
    }
}

   //mostrar matriz
   for (int i = 0; i != matriz; i++){
      for (int j = 0; j != matriz; j++)
         cout << " " << M[i][j];

      cout << endl;
   }
}
   for (int i = 0; i != matriz; i++)
      delete[] M[i];
   delete[] M;

   return 0;
}

leosansan


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 (cpp) [Seleccionar]

................
cout << "\nIntroduzca numero de minas (numero):";
  cin >> numero;
  for (int i = 0; i < numero; i++){
    cout << "\nColocando la mina : "<<i+1<<endl;
    do{
      cout << "Introduzca fila (1-numero): ";
      cin >> fil;
    }while(fil<1 || fil>dim);
    fil=fil-1;

    do{
      cout << "Introduzca columna (1-numero): ";
      cin >> col;
    }while(col<1 || col>dim);
    col=col-1;
    Matriz[fil][col]='*';
    cout<<"\tM["<<fil+1<<","<<col+1<<"]="<<Matriz[fil][col]<< "\n\n";
...............................................


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



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




Yoel Alejandro

#8
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 (cpp) [Seleccionar]

#include <iostream>
#include <string>

using namespace std;

int main()
{
   int dim, bomba='*', valor;
   int i, j;      /* <-- declara aqui, no dentro del ciclo */
   char c;
   char listo;
   
   cout << time(NULL);
   return 0;
   
   cout << "Tamano de la matriz: ";
   cin >> dim;
   cout << endl;

   /* creamos la matriz, y rellenamos con ceros */
   char **M = new char *[dim];
   for (i = 0; i != dim; i++)
      M[i] = new char [dim];

   for (i = 0; i < dim; i++)
      for (j = 0; j < dim; j++)
         M[i][j] = '0';
   
   /* poniendo posiciones de las minas */
   listo = 0;
   for (i = 0; i < dim && listo == 0; i++) {
      for (j = 0; j < dim && listo == 0; j++) {
         cout << endl << "Posicion [ " << i << " ] [ " << j << " ]: ";
         cin >> c;
         if ( c == '1' )
            M[i][j] = '1';
         else if ( c == 'q' || c == 'Q' || c == 'x' || c == 'Q' )
            listo = 1;
      }
   }

   // mostrar matriz
   cout << endl << "La matriz es:" << endl;
   for (i = 0; i != dim; i++) {
      for (j = 0; j != dim; j++)
         if ( M[i][j] == '1')
            cout << "*\t";
         else
            cout << "0\t";
      cout << endl;
   }
   
   // destruye la matriz
   for (i = 0; i != dim; i++)
     delete[] M[i];
   delete[] M;

   return 0;
}
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

leosansan

Cita de: 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.


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 (cpp) [Seleccionar]

..........................
/* creamos la matriz, y rellenamos con ceros */
char M[dim][dim];
for (i = 0; i < dim; i++)
for (j = 0; j < dim; j++)
M[i][j] = '0';
................................


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! ..... !!!!