Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: sebastian1114 en 10 Julio 2014, 10:58 am



Título: Alguién que por favor me ayude :O
Publicado por: sebastian1114 en 10 Julio 2014, 10:58 am
Buenos días compañeros !

Tengo un problema gigante , estoy haciendo un proyecto y llegué al punto en el que no sé como bajar las filas

Es algo así como un candy crush lo que no puedo hacer la función para eliminar las coincidencias que en este caso sería el resultado de cruz_abajo y que caigan las demás ; y que luego de que caigan todas se creen más aleatorios con este código

Código:
char dulces[]= "8O"; //tipos de dulces

int numdedulces=sizeof(dulces)/sizeof(dulces[0])-1;


void  iniciar(){
 
   srand(time(0));//numeros Aleatorios en funcion del tiempo
    for (int i=0;i<9;i++)//para desplazarse  por las columnas
    {
        for (int j=0;j<9;j++)//para desplazarse por las filas
        {
           tablero[i][j]=dulces[rand()%numdedulces];//Agrega numero aleatorio a la posicion ij de la matriz
            printf("\t%c",tablero[i][j]);//imprime elemento de la matriz en pantalla
        }
      cout << endl << endl << endl;//para dejar espacios entre filas.
    }
}


Código:

#include <iostream>
#include <utility>//swap posicion
using namespace std;

int tablero [8][4] = {{0,4,5,9},{0,4,5,9},{0,4,5,9},{0,0,2,1},{0,0,5,1}, {1,1,2,3},{1,2,0,2},{1,3,2,3}};

void imprimir () {
for (int i= 0;i<8; i++){
for (int j= 0; j<4; j++){
cout<<tablero[i][j]<<"\t";
}
cout << endl;
}
}

int cruz_abajo(int x, int y){
int contador = 1;
for (int indice = 1; indice < 8; indice++){

if ((tablero[x][y] == tablero[x+indice][y]) && ((x+indice) <=8) ){
contador++;
}
else{
indice = 8;
}
}
return contador;
}


void barrido_y_borrado(int i, int j){  ///// elimina !
if(cruz_abajo(i,j)>=3){
int coincidencia = cruz_abajo(i,j);
int bajar = 0;
for(int elemento = i; bajar < coincidencia  ;elemento++){// veces
        for (bajar=0; i-1-bajar >= 0 ; bajar ++){//Limite
 swap (tablero[i+coincidencia-1-bajar][j],tablero[i-1-bajar][j] );
}
}
}
}
int main(int argc, char *argv[]) {
    int i,j;
imprimir();
cin>>i>>j;
cout<<cruz_abajo(i,j);
barrido_y_borrado(i,j);
cout<<endl;
imprimir();
system("PAUSE");
return 0;

}





No se si me hice entender :C
necesito ayuda urgente :C
Gracias por leer :)
y más gracias aún si me puedes ayudar !   :huh:


Título: Re: Alguién que por favor me ayude :O
Publicado por: eferion en 10 Julio 2014, 12:04 pm
Nota: code=c o code=cpp para que el código se coloree según el lenguaje que corresponda.

Código
  1. if ((tablero[x][y] == tablero[x+indice][y]) && ((x+indice) <=8) )

Si "tablero" tiene 8 columnas, la comprobación "((x+indice) <=8)" es peligrosa por necesidad... ya que si "x+indice==8" entonces estarás accediendo a una posición de memoria incorrecta y puede que hasta no válida.

Dicho esto, no entiendo el nombre de la función "cruz_abajo" (soy quisquilloso en el tema de los nombres porque la misma función puede ser la cosa más simple o la más complicada simplemente cambiando los nombres de la función y sus variables). ¿Qué debería hacer exactamente? Entiendo, viendo el código, que encontrar 3 elementos iguales, no?

Si esto es así tienes que tener en cuenta que si tu mueves el elemento posicionado en (x,y), deberías buscar en los rangos (x-2,y)-(x+2,y) y (x,y-2)-(x,y+2). Tu actualmente estás buscando únicamente en el rango (x,y)-(x+8,y)... se parecen los rangos como un sacapuntas a un coche.

Obviamente los rangos indicados son teóricos, luego tienes que asegurar que no "lees" fuera del tablero. Las comprobaciones para el primer rango podrían ser algo tal que:

Código
  1. #define MAXCOLUMNAS 8
  2. #define MAXFILAS 4
  3.  
  4. int tablero [MAXCOLUMNAS][MAXFILAS] = //...
  5.  
  6. // ...
  7.  
  8. int indice;
  9. for ( indice = x-2; indice <= x+2; ++indice )
  10. {
  11.  if ( indice >= 0 && indice < MAXCOLUMNAS )
  12.  {
  13.    if ( tablero[ indice ][ y ] == tablero[ x ][ y ] )
  14.      contador++;
  15.    else
  16.      contador = 0;
  17.  }
  18. }

La definición de "tablero" la he cambiado porque no es buena idea tener valores puestos "a pelo" en el código... sobretodo si son referentes a límites impuestos (como el tamaño de la matriz "tablero").

Bueno, al caso. Con ese código, al finalizar el bucle, "contador" tendrá el tamaño del grupo. Fíjate en que si me encuentro un elemento que no es el buscado reseteo "contador". Esto es para evitar que cuente mal secuencias del tipo "808808". En el ejemplo, si no resetease "contador", éste acabaría con valor 4, cuando obviamente no es cierto.

Lo que sucede es que con este código no sabrás dónde empieza y dónde termina el grupo, por lo que quizás es buena idea almacenar las coordenadas inicial y final del grupo para poder hacer la limpieza de los elementos:

Código
  1. int buscarGrupoHorizontal( int x, int y, int* inicio, int* final )
  2. {
  3.  int contador = 0;
  4.  int indice;
  5.  for ( indice = x-2; indice <= x+2; ++indice )
  6.  {
  7.     if ( indice >= 0 && indice < MAXCOLUMNAS )
  8.    {
  9.      *final = indice;
  10.  
  11.      if ( tablero[ indice ][ y ] == tablero[ x ][ y ] )
  12.      {
  13.        if ( contador == 0 ) *inicio = indice;
  14.        contador++;
  15.      }
  16.      else
  17.      {
  18.        // Dado que comprobamos 5 posiciones, si tenemos un grupo de 3 o superior no tenemos que seguir buscando.
  19.        if ( contador >= 3 )
  20.          break;
  21.  
  22.        contador = 0;
  23.      }
  24.    }
  25.  }
  26.  
  27.  return contador;
  28. }

De esta forma, si "contador >= 3", tendrás en "inicio" y "fin" las coordenadas "x" que delimitan el grupo. Esta información es importante para poder eliminar el grupo, bajar los elementos de esas columnas y generar elementos nuevos para la parte superior.

Te tocaría, eso si, implementar el buscador vertical.

Un saludo.