Why my program is drawing "twice" ?

I have tried to figure out where the problem is… but I haven’t had any luck…

the in.dat have this format:


N_alto	500
M_ancho	500
PGEL	5
PMET	5
PP20	5
PP31	5
PP40	5
PPGM21	5
PPGM31	5
PPGM41	5
PPGM51	5
maxiter	100
maxpart	5
ardent	entrada.dat

and the main program is (kinda large):

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<string.h>
#include <GL/gl.h>
#include <GL/glut.h>



//Para todo proposito entiendase MET como METacrilato.
// Y GELatina como un polimero distinto al metacrilato y/o polisacario
// que sirve de base para la preparación del primero

char sele[15];
char sal;
char salida[15];
unsigned int punt=0;
                  //    N-1---->M-1xN-1
                  //      |    |
unsigned int N=0; //ancho |    |
unsigned int M=0; //alto  0---->M-1 

double PGEL=0.0; //Porcentaje de gelatina
double PMET=0.0; //Porcentaje de Metacrilato


double PP20=0.0; //Porcentaje de Metacrilato en choque binario(2)y no quede mov.
double PP31=0.0; //Porcentaje de Polimero en choque terciario(3)y quede 1en mov.
double PP40=0.0; //Porcentaje de Polimero en choque tetrario(4) y no quede mov
double PPGM21=0.0; //Porcentaje de Probabilidad en choque Binario Gel-Met no quede mov.(particula absorvida)
double PPGM31=0.0; //Porcentaje de Probabilidad en choque Ternario Gel-Met no quede mov.
double PPGM41=0.0; //Porcentaje de Probabilidad en choque Tetrario Gel-Met no quede mov.
double PPGM51=0.0; //Porcentaje de Probabilidad en choque Pentario Gel-Met no quede mov.


unsigned int maxiter=0;
unsigned int maxpart=0;// numero de particulas en casilla desde 0 hasta maxpart (INCLUIDO)

// *******************************************************************
// ****************************FUNCIONES******************************
// *******************************************************************

//FUNCIONES GENERADORAS DE NUMEROS ALEATORIOS
void random01(double *a){ //aleatorio entre 0-1
  *a=rand();
  *a/=RAND_MAX;
}

void random0N(double *a, double S){ //numero aleatorio entre 0 y N
  *a=rand();    //genero # entre 0 ->RAND_MXA
  *a/=RAND_MAX; //normalizo //normalizo (# entre 0 y 1)
  *a*=S; //amplifico //(ahora es un # entre 0 y N);
}

//FUNCIONES PROPIAS DEL PROGRAMA   TRASLACION Y COLISIONES
//pantalla desde 0 hasta N-1en X  y desde 0 hasta M-1  en Y "RECORDARRRR"!!!!
void traslaciones(unsigned int **IN, unsigned int **OUT){
  unsigned int i,j;


  // Limites periodicos en X           N-1---->M-1xN-1
  //hilera x=0 -> x-1 = M-1              |    | 
  //hilera x=M-1 -> x+1 = 0              |    |
  //                                     |    |
  // Limites Periodicos en Y             0---->M-1 
  //hilera y=0 -> y-1 = N-1
  //hilera y=N-1 -> y+1 = 0
  
  //si el valor de la matriz es 16 entonces es gelatina y no se pde mover alla.
  
  for(j=0;j<N;j++){
    for(i=0;i<M;i++){
      switch(IN[i][j]){
      case 1:
	//cambia X (0,M-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	break;
	
      case 2:
	//cambia Y (0,N-1)
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	break;
	
      case 3:
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	break;
	
      case 4:
	//cambia X (0,M-1)
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	break;
	
      case 5:
	//cambia X (0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	break;

      case 6:
	//cambia X (0,M-1) e Y:(0,N-1)
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}

	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	
	break;
      case 7:
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}

	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}

	break;
      case 8:
	//cambia Y (0,N-1)
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
	
      case 9:
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
      case 10:

	//cambia Y (0,N-1)
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
      case 11:
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}

	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}

	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}

	break;
      case 12:
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
	
      case 13:
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
      case 14:
	//cambia X (0,M-1) e Y:(0,N-1)
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
      case 15:
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
	
      case 16:
	OUT[i][j]+=16;
	break;
	
      case 17: //16+1
	OUT[i][j]+=16;
	//cambia X (0,M-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	break;
	
      case 18: //16+2
	OUT[i][j]+=16;
	//cambia Y (0,N-1)
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	break;
	
      case 19: //16+3
	OUT[i][j]+=16;
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	break;
	
      case 20: //16+4
	OUT[i][j]+=16;
	//cambia X (0,M-1)
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	break;
	
      case 21: //16+5
	OUT[i][j]+=16;
	//cambia X (0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	break;
	
      case 22: //16+6
	OUT[i][j]+=16;
	//cambia X (0,M-1) e Y:(0,N-1)
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}

	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	break;
	
      case 23: //16+7
	OUT[i][j]+=16;
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}

	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	break;
	
      case 24: //16+8
	OUT[i][j]+=16;
	//cambia Y (0,N-1)
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
	
      case 25: //16+9
	OUT[i][j]+=16;
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
	
      case 26: //16+10
	
	OUT[i][j]+=16;
	//cambia Y (0,N-1)
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
	
      case 27: //16+11
	OUT[i][j]+=16;
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
	
      case 28: //16+12
	OUT[i][j]+=16;
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
	
      case 29: //16+13
	OUT[i][j]+=16;
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
      case 30://16+14
	OUT[i][j]+=16;
	//cambia X (0,M-1) e Y:(0,N-1)
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
      case 31: //16+15
	OUT[i][j]+=16;
	//cambia X (0,M-1) e Y:(0,N-1)
	if(i==0){
	  OUT[M-1][j]+=1;
	}
	else{
	  OUT[i-1][j]+=1;
	}
	
	if(j==0){
	  OUT[i][N-1]+=2;
	}
	else{
	  OUT[i][j-1]+=2;
	}
	
	if(i==M-1){
	  OUT[0][j]+=4;
	}
	else{
	  OUT[i+1][j]+=4;
	}
	
	if(j==N-1){
	  OUT[i][0]+=8;
	}
	else{
	  OUT[i][j+1]+=8;
	}
	break;
      }
    }
  }
}


void colisiones(unsigned int **F, unsigned int **P){ //P->T(en program) //da el # de particulas en cada casilla
  unsigned int xm=0,ym=0;
  double selector=0.0;

  
  //ternarios 1+2          0 1  2  3
  //unsigned int caso28[]={16,17,18,19};
  //unsigned int caso25[]={16,18,20,22};
  //unsigned int caso19[]={16,20,24,28};
  //unsigned int caso22[]={16,17,24,25};
  //unsigned int caso21[]={16,17,20,21,26};
  //unsigned int caso26[]={16,18,21,24,26};
  //tetrarios 1+3        0  1   2  3  4  5 6  7
  //unsigned int caso23[]={16,17,20,21,24,25,28,29};
  //unsigned int caso27[]={16,18,20,22,24,26,28,30};
  //unsigned int caso29[]={16,17,18,19,20,21,22,23};
  //unsigned int caso30[]={16,17,18,19,24,25,26,27};
  //pentario              0  1  2  3  4 5  6   7  8  9 10 11 12 13 14 15
  //unsigned int caso31[]={16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
 
 

  
  for(ym=0;ym<N;ym++){
    for(xm=0;xm<M;xm++){
      switch(F[xm][ym]){
	//////////////////////////////////////-----MET-MET-----////////////////////////////////////
	//binarios
      case 5: //el 5 cambia a 0 o a 10
	random01(&selector);              
	if(P[xm][ym]<maxpart-1){ //(Si maxpart=10 ->  Pxy < 9 (o sea 8) asi le pde sumar 2)
	  if(selector <= PP20){ 
	    F[xm][ym]=0;
	    P[xm][ym]+=2;//agregar 2 al contador xm ym
	  }
	}
	else{
	  F[xm][ym]=10; 
	}
	
	break;
	
      case 10: //el 10 cambia a 0 o a 5
	random01(&selector);
	if(P[xm][ym]<maxpart-1){
	  if(selector <= PP20){
	    F[xm][ym]=0;
	    P[xm][ym]+=2;//agregar 2 al contador xm ym
	  }
	}
	else{
	  F[xm][ym]=5;
	}
	break;
	
	//ternarios
      case 7: //cambia a 2 o queda =
	random01(&selector);
	if(P[xm][ym]<maxpart-1){
	  if(selector <= PP31){  //(Si maxpart=10 ->  Pxy < 9 (o sea 8) asi le pde sumar 2)
	    F[xm][ym]=2;
	    P[xm][ym]+=2; //agregar 2 al contador xm ym
	  }
	}
	break;
	
      case 11: //cambia a 1 o queda =
	random01(&selector);
	if(P[xm][ym]<maxpart-1){
	  if(selector <= PP31){ //(Si maxpart=10 ->  Pxy < 9 (o sea 8) asi le pde sumar 2)
	    F[xm][ym]=1;
	    P[xm][ym]+=2; //agregar 2 al contador xm ym
	  }
	}
	break;
	
      case 13: //cambia a 8 o queda =
	random01(&selector);
	if(P[xm][ym]<maxpart-1){//(Si maxpart=10 ->  Pxy < 9 (o sea 8) asi le pde sumar 2)
	  if(selector <= PP31){
	    F[xm][ym]=8;
	    P[xm][ym]+=2; //agregar 2 al contador xm ym
	  }
	}
	break;
	
      case 14://cambia a 4 o queda =
	random01(&selector);
	if(P[xm][ym]<maxpart-1){ //(Si maxpart=10 ->  Pxy < 9 (o sea 8) asi le pde sumar 2)
	  if(selector <= PP31){
	    F[xm][ym]=4;
	    P[xm][ym]+=2; //agregar 2 al contador xm ym
	  }
	}
	break;
	
	//tetrarios
      case 15: //cambia a 0 o queda =
	random01(&selector);
	if(P[xm][ym]<maxpart-3){
	  if(selector <= PP40){ //(Si maxpart=10 ->  Pxy < 7 (o sea 6) asi le pde sumar 4)
	    F[xm][ym]=0;
	    P[xm][ym]+=4; //agregar 4 al contador xm ym
	  }
	}
	break;
	
	//////////////////////////////////////////////////////////////////////
	//////////Choques Gelatina-Metacrilatos Binarios (1+1)////////////////
	//////////////////////////////////////////////////////////////////////
	// case 16: //esto es una gelatina
	
      case 17:
	random01(&selector);
	if(P[xm][ym]<maxpart){
	  if(selector <=  PPGM21){ //(Si maxpart=10 ->  Pxy < 10 (o sea 9) asi le pde sumar 1)
	    F[xm][ym]=16; //deja la particula de gelatina
	    P[xm][ym]+=1; //agregar 1 al contador xm ym
	  }
	}
	else{
	  F[xm][ym]=20;
	}
	break;
	
      case 18:
	random01(&selector);
	if(P[xm][ym]<maxpart){
	  if(selector <=  PPGM21){
	    F[xm][ym]=16; //deja la particula de gelatina
	    P[xm][ym]+=1; //agregar 1 al contador xm ym
	  }
	}
	else{
	  F[xm][ym]=24;
	}
	break;
	
      case 20:
	random01(&selector);
	if(P[xm][ym]<maxpart){
	  if(selector <= PPGM21){ 
	    F[xm][ym]=16; //deja la particula de gelatina
	    P[xm][ym]+=1; //agregar 1 al contador xm ym
	  }
	}
	else{
	  F[xm][ym]=17;
	}
	break;
	
      case 24:
	random01(&selector);
	if(P[xm][ym]<maxpart){
	  if(selector <= PPGM21){ 
	    F[xm][ym]=16; //deja la particula de gelatina
	    P[xm][ym]+=1; //agregar 1 al contador xm ym
	  }
	}
	else{
	  F[xm][ym]=18;
	}
	break;
	
	/////////////////////////////////////////////////
	/////////////////////////////////////////////////
	//Choques Gelatina-Metacrilatos Ternarios (1+2)//
	/////////////////////////////////////////////////
	/////////////////////////////////////////////////
	
	
      case 19:
	//ternarios 1+2           0 1   2   3 
	//unsigned int caso19[]={16,20,24,28};
	for(;;){
	  random0N(&selector,4); //numero entre 0 y 4 xD
	  if((unsigned int)selector==4){ //si por casualidad da 4 que ponga 3 
	    selector=3.0;
	  }
	  if( (unsigned int)selector==0){ //si cae 0 que verifique q entran 2 las particulas y rompa el for infinito
	    if(P[xm][ym]<(maxpart-1)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){// si cae 1 que verifique q entra la particula y rompa el for infinito
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){// si cae 2 que verifique q entra la particula y rompa el for infinito
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==3 ){// si cae 3 q rompa el for infinito
	    break;
	  }
	}
	
	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=20; 
	  P[xm][ym]+=1; 
	  break;
	case 2:
	  F[xm][ym]=24;
	  P[xm][ym]+=1;
	  break;
	case 3:
	  F[xm][ym]=28;
	  break;
	}
	break;
	
	      
      case 21:
	//ternarios 1+2          0  1  2  3  4
	//unsigned int caso21[]={16,17,20,21,26};
	for(;;){
	  random0N(&selector,5); //numero entre 0 y 5 xD
	  if((unsigned int)selector==5){ //si cae 5 que ponga 4 xD
	    selector=4.0;
	  }
	  if( (unsigned int)selector==0){ //si cae 0 que verifique q le entran las 2 particulas y rompa el loop infinito
	    if(P[xm][ym]<(maxpart-1)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){//si cae 1 que verifique q le entra la particula y rompa el loop infinito
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){//si cae 2 q rompa el loop infinito
	    break;
	  }
	  if( (unsigned int)selector==3 ){//si cae 2 q rompa el loop infinito (no es necesario verificar maxiter.
	    break;
	  }
	}
	
	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=17;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=20; 
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=21; 
	  break;
	case 4:
	  F[xm][ym]=26; 
	  break;
	}
	break;
	

      case 22:
	//ternarios 1+2          0  1  2  3  
	//unsigned int caso22[]={16,17,24,25};
	for(;;){
	  random0N(&selector,4); //numero entre 0 y 4 xD
	  if((unsigned int)selector==4){ //si por casualidad da 4 que ponga 3 
	    selector=3.0;
	  }
	  if( (unsigned int)selector==0){ //si cae 0 que verifique q entran 2 las particulas y rompa el for infinito
	    if(P[xm][ym]<(maxpart-1)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){// si cae 1 que verifique q entra la particula y rompa el for infinito
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){// si cae 2 que verifique q entra la particula y rompa el for infinito
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==3 ){// si cae 3 q rompa el for infinito
	    break; //break del for(;;)
	  }
	}
	
	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=17;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=24; 
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=25; 
	  break; //break del case (selector)
	}
	break;
	
      case 25:
	//ternarios 1+2          0  1  2  3  
	//unsigned int caso25[]={16,18,20,22};
	for(;;){
	  random0N(&selector,4); //numero entre 0 y 4 xD
	  if((unsigned int)selector==4){ //si por casualidad da 4 que ponga 3 
	    selector=3.0;
	  }
	  if( (unsigned int)selector==0){ //si cae 0 que verifique q entran 2 las particulas y rompa el for infinito
	    if(P[xm][ym]<(maxpart-1)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){// si cae 1 que verifique q entra la particula y rompa el for infinito
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){// si cae 2 que verifique q entra la particula y rompa el for infinito
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==3 ){// si cae 3 q rompa el for infinito
	    break; //break del for(;;)
	  }
	}
	
	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=18;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=20; 
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=22; 
	  break;
	}
	break;
	
      case 26:
	//ternarios 1+2          0  1  2  3  4 
	//unsigned int caso26[]={16,18,21,24,26};
	for(;;){
	  random0N(&selector,5); //numero entre 0 y 5 xD
	  if((unsigned int)selector==5){ //si cae 5 que ponga 4 xD
	    selector=4.0;
	  }
	  if( (unsigned int)selector==0){ //si cae 0 que verifique q le entran las 2 particulas y rompa el loop infinito
	    if(P[xm][ym]<(maxpart-1)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){//si cae 1 que verifique q le entra la particula y rompa el loop infinito
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){//si cae 2 q rompa el loop infinito
	    break;
	  }
	  if( (unsigned int)selector==3 ){//si cae 2 q rompa el loop infinito (no es necesario verificar maxiter.
	    break;
	  }
	}
	
	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=18;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=24; 
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=26; 
	  break;
	case 4:
	  F[xm][ym]=21; 
	  break;	  
	}
	break;
	
      case 28:
	//ternarios 1+2          0  1  2  3   
	//unsigned int caso28[]={16,17,18,19};
	
	for(;;){
	  random0N(&selector,4); //numero entre 0 y 4 xD
	  if((unsigned int)selector==4){
	    selector=3.0;
	  }
	  if( (unsigned int)selector==0){
	    if(P[xm][ym]<(maxpart-1)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){
	    if(P[xm][ym]<(maxpart)){
	      break;
	    }
	  }
	  if( (unsigned int)selector==3 ){
	    break;
	  }
	}
	
	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=17;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=18; 
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=19;
	  break;
	}
	break;


	/* regla 25
	random01(&selector);
	if(P[xm][ym]<maxpart-1){
	  if(selector <=  PPGM31){ //(Si maxpart=10 ->  Pxy < 9 (o sea 8) asi le pde sumar 2)
	    F[xm][ym]=16; //deja la particula de gelatina
	    P[xm][ym]+=2; //agregar 2 al contador xm ym
	  }
	}
	else{
	  F[xm][ym]=22; //cambia direccion del movimiento
	}
	break;
	*/
	
	////////////////////////////////////////////////
	//Choques Gelatina-Metacrilatos Tetrarios (1+3)
	///////////////////////////////////////////////

      case 23:
	//tetrarios 1+3          0  1   2  3  4  5 6  7
	//unsigned int caso23[]={16,17,20,21,24,25,28,29};
	for(;;){
	  random0N(&selector,8); //numero entre 0 y 8 xD
	  if((unsigned int)selector==8){
	    selector=7.0;
	  }
	  
	  if( (unsigned int)selector==0){//0->16
	    if(P[xm][ym]<(maxpart-2)){//3
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){//1->17
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){//2->20
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  if( (unsigned int)selector==3 ){//3->21
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==4){//4->24
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==5 ){//5->25
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==6) {//6->28
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  if( (unsigned int)selector==7 ){//7->29
	    break;
	  }
	}

	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=3; //agregar 3 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=17;
	  P[xm][ym]+=2; //agregar 2 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=20; 
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=21;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	  
	case 4:
	  F[xm][ym]=24; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 5:
	  F[xm][ym]=25;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym 
	  break;
	case 6:
	  F[xm][ym]=28; 
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 7:
	  F[xm][ym]=29;
	  break;
	}	
	break;
	 
     
      case 27:
	//tetrarios 1+3          0  1  2  3  4  5  6  7
	//unsigned int caso27[]={16,18,20,22,24,26,28,30};
	for(;;){
	  random0N(&selector,8); //numero entre 0 y 8 xD
	  if((unsigned int)selector==8){
	    selector=7.0;
	  }
	  
	  if( (unsigned int)selector==0){//0->16
	    if(P[xm][ym]<(maxpart-2)){//3
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){//1->18
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){//2->20
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  if( (unsigned int)selector==3 ){//3->22
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==4){//4->24
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==5 ){//5->26
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==6) {//6->28
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  if( (unsigned int)selector==7 ){//7->30
	    break;
	  }
	}

	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=3; //agregar 3 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=18;
	  P[xm][ym]+=2; //agregar 2 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=20; 
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=22;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	  
	case 4:
	  F[xm][ym]=24; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 5:
	  F[xm][ym]=26;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym 
	  break;
	case 6:
	  F[xm][ym]=28; 
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 7:
	  F[xm][ym]=30;
	  break;
	}	
	break;

	
      case 29:
	//tetrarios 1+3          0  1  2  3  4  5  6  7
	//unsigned int caso29[]={16,17,18,19,20,21,22,23};
	for(;;){
	  random0N(&selector,8); //numero entre 0 y 8 xD
	  if((unsigned int)selector==8){
	    selector=7.0;
	  }
	  
	  if( (unsigned int)selector==0){//0->16
	    if(P[xm][ym]<(maxpart-2)){//3
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){//1->17
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){//2->18
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  if( (unsigned int)selector==3 ){//3->19
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==4){//4->20
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==5 ){//5->21
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==6) {//6->22
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  if( (unsigned int)selector==7 ){//7->23
	    break;
	  }
	}

	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=3; //agregar 3 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=17;
	  P[xm][ym]+=2; //agregar 2 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=18; 
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=19;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	  
	case 4:
	  F[xm][ym]=20; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 5:
	  F[xm][ym]=21;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym 
	  break;
	case 6:
	  F[xm][ym]=22; 
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 7:
	  F[xm][ym]=23;
	  break;
	}	
	break;
	
	
      case 30:
	//tetrarios 1+3          0  1  2  3  4  5  6  7
	//unsigned int caso30[]={16,17,18,19,24,25,26,27};
	for(;;){
	  random0N(&selector,8); //numero entre 0 y 8 xD
	  if((unsigned int)selector==8){
	    selector=7.0;
	  }
	  
	  if( (unsigned int)selector==0){//0->16
	    if(P[xm][ym]<(maxpart-2)){//3
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){//1->17
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){//2->18
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  if( (unsigned int)selector==3 ){//3->19
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==4){//4->24
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==5 ){//5->25
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==6) {//6->26
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  if( (unsigned int)selector==7 ){//7->27
	    break;
	  }
	}

	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=3; //agregar 3 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=17;
	  P[xm][ym]+=2; //agregar 2 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=18; 
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=19;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	  
	case 4:
	  F[xm][ym]=24; //deja la particula de gelatina
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 5:
	  F[xm][ym]=25;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym 
	  break;
	case 6:
	  F[xm][ym]=26; 
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 7:
	  F[xm][ym]=27;
	  break;
	}	
	break;
	
	////////////////////////////////////////////////
	//Choques Gelatina-Metacrilatos Pentarios (1+4)
	///////////////////////////////////////////////
	
      case 31:
	//pentario                0  1  2  3  4 5  6   7  8  9 10 11 12 13 14 15
	//unsigned int caso31[]={16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
	for(;;){
	  random0N(&selector,16); //numero entre 0 y 8 xD
	  if((unsigned int)selector==16){
	    selector=15.0;
	  }
	  //4 3 3 2 3 2 2 1 3 2 2 1 2 1 1 //orden de huecos para meter particulas
	  if( (unsigned int)selector==0){//0->16
	    if(P[xm][ym]<(maxpart-3)){//4
	      break;
	    }
	  }
	  if( (unsigned int)selector==1 ){//1->17
	    if(P[xm][ym]<(maxpart-2)){//3
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==2 ){//2->18
	    if(P[xm][ym]<(maxpart-2)){//3
	      break;
	    }
	  }
	  if( (unsigned int)selector==3 ){//3->19
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==4){//4->20
	    if(P[xm][ym]<(maxpart-2)){//3
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==5 ){//5->21
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==6) {//6->22
	    if(P[xm][ym]<(maxpart)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==7 ){//7->23
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==8){//8->24
	    if(P[xm][ym]<(maxpart-2)){//3
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==9 ){//9->25
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==10 ){//10->26
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }

	  if( (unsigned int)selector==11 ){//11->27
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==12){//12->28
	    if(P[xm][ym]<(maxpart-1)){//2
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==13){//13->29
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  
	  if( (unsigned int)selector==14) {//14->30
	    if(P[xm][ym]<(maxpart)){//1
	      break;
	    }
	  }
	  if( (unsigned int)selector==15 ){//15->31
	    break;
	  }
	}
	//pentario                0  1  2  3  4 5  6   7  8  9 10 11 12 13 14 15
	//unsigned int caso31[]={16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};	
	
	switch((unsigned int)selector){
	case 0:
	  F[xm][ym]=16; //deja la particula de gelatina
	  P[xm][ym]+=4; //agregar 4 al contador xm ym
	  break;
	case 1:
	  F[xm][ym]=17;
	  P[xm][ym]+=3; //agregar 2 al contador xm ym 
	  break;
	case 2:
	  F[xm][ym]=18; 
	  P[xm][ym]+=3; //agregar 2 al contador xm ym
	  break;
	case 3:
	  F[xm][ym]=19;
	  P[xm][ym]+=2; //agregar 1 al contador xm ym
	  break;
	case 4:
	  F[xm][ym]=20; //deja la particula de gelatina
	  P[xm][ym]+=3; //agregar 4 al contador xm ym
	  break;
	case 5:
	  F[xm][ym]=21;
	  P[xm][ym]+=2; //agregar 2 al contador xm ym 
	  break;
	case 6:
	  F[xm][ym]=22; 
	  P[xm][ym]+=2; //agregar 2 al contador xm ym
	  break;
	case 7:
	  F[xm][ym]=23;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 8:
	  F[xm][ym]=24; //deja la particula de gelatina
	  P[xm][ym]+=3; //agregar 2 al contador xm ym
	  break;
	case 9:
	  F[xm][ym]=25;
	  P[xm][ym]+=2; //agregar 1 al contador xm ym 
	  break;
	case 10:
	  F[xm][ym]=26; 
	  P[xm][ym]+=2; //agregar 1 al contador xm ym
	  break;
	case 11:
	  F[xm][ym]=27; //deja la particula de gelatina
	  P[xm][ym]+=1; //agregar 3 al contador xm ym
	  break;
	case 12:
	  F[xm][ym]=28;
	  P[xm][ym]+=2; //agregar 2 al contador xm ym 
	  break;
	case 13:
	  F[xm][ym]=29; 
	  P[xm][ym]+=1; //agregar 2 al contador xm ym
	  break;
	case 14:
	  F[xm][ym]=30;
	  P[xm][ym]+=1; //agregar 1 al contador xm ym
	  break;
	case 15:
	  F[xm][ym]=31; 
	  break;
	}
	break;
      }
    }
  }
}


//FUNCIONES CONTADORAS D PARTICULAS
//CONTADOR PARTICULAS dado ENTERO (PE) 
unsigned int contadorPE(unsigned int MMOV){ //
  unsigned int out=0;
  switch(MMOV){
  case 1:
    out=1;
    break;
    
  case 2:
    out=1;
    break;

  case 3:
    out=2;
    break;
    
  case 4:
    out=1;
    break;
    
  case 5:
    out=2;
    break;
    
  case 6:
    out=2;
    break;
    
  case 7:
    out=3;
    break;
    
  case 8:
    out=1;
    break;
    
  case 9:
    out=2;
    break;
    
  case 10:
    out=2;
    break;
    
  case 11:
    out=3;
    break;
    
  case 12:
    out=2;
    break;
    
  case 13:
    out=3;
    break;
    
  case 14:
    out=3;
    break;
  
  case 15:
    out=4;
    break;
    
  case 16:
    out=1;
    break;
    
  case 17:
    out=2;
    break;
    
  case 18:
    out=2;
    break;
    
  case 19:
    out=3;
    break;
    
  case 20:
    out=2;
    break;

  case 21:
    out=3;
    break;
    
  case 22:	
    out=3;	
    break;
    
  case 23:	
    out=4;	
    break;
    
  case 24:	
    out=2;	
    break;
    
  case 25:	
    out=3;	
    break;
    
  case 26:	
    out=3;	
    break;
    
  case 27:	
    out=4;	
    break;
    
  case 28:	
    out=3;	
    break;
    
  case 29:	
    out=4;	
    break;
    
  case 30:	
    out=4;	
    break;
    
  case 31:
    out=5;	
    break;
  }
  return out;
}


//PARTICULAS TOTALES(PT)
long unsigned int contadorPT(unsigned int **A){ 
  unsigned int ii,jj;
  long unsigned int nparticulas=0;
  
  for(jj=0;jj<N;jj++){
    for(ii=0;ii<M;ii++){
      switch(A[ii][jj]){
      case 1:
	nparticulas++;
	break;
      case 2:
	nparticulas++;
	break;	
      case 3:
	nparticulas+=2;
	break;
      case 4:
	nparticulas++;
	break;
      case 5:
	nparticulas+=2;
	break;
      case 6:
	nparticulas+=2;
	break;	
      case 7:
	nparticulas+=3;
	break;
      case 8:
	nparticulas++;
	break;
      case 9:
	nparticulas+=2;
	break;
      case 10:
	nparticulas+=2;
	break;	
      case 11:
	nparticulas+=3;
	break;
      case 12:
	nparticulas+=2;
	break;
      case 13:
	nparticulas+=3;
	break;
      case 14:
	nparticulas+=3;
	break;	
      case 15:
	nparticulas+=4;
	break;
      case 16:
	nparticulas+=1;	
	break;
      case 17:
	nparticulas+=2;	
	break;
      case 18:
	nparticulas+=2;	
	break;
      case 19:
	nparticulas+=3;	
	break;
      case 20:
	nparticulas+=2;	
	break;
      case 21:
	nparticulas+=3;	
	break;
      case 22:	
	nparticulas+=3;	
	break;
      case 23:	
	nparticulas+=4;	
	break;
      case 24:	
	nparticulas+=2;	
	break;
      case 25:	
	nparticulas+=3;	
	break;
      case 26:	
	nparticulas+=3;	
	break;
      case 27:	
	nparticulas+=4;	
	break;
      case 28:	
	nparticulas+=3;	
	break;
      case 29:	
	nparticulas+=4;	
	break;
      case 30:	
	nparticulas+=4;	
	break;
      case 31:
	nparticulas+=5;	
	break;
      }
    }
  }
  return nparticulas;
}

//PARTICULAS POR CASILLA (PPC)
void contadorPPC(unsigned int **MMOV, unsigned int **MDES){ 
  unsigned int ii,jj;
  
  for(jj=0;jj<N;jj++){
    for(ii=0;ii<M;ii++){
      switch(MMOV[ii][jj]){
      case 1:
	MDES[ii][jj]=1;
	break;
	
      case 2:
	MDES[ii][jj]=1;
	break;	
	
      case 3:
	MDES[ii][jj]=2;
	break;
	
      case 4:
	MDES[ii][jj]=1;
	break;
	
      case 5:
	MDES[ii][jj]=2;
	break;
	
      case 6:
	MDES[ii][jj]=2;
	break;	
	
      case 7:
	MDES[ii][jj]=3;
	break;
	
      case 8:
	MDES[ii][jj]=1;
	break;
	
      case 9:
	MDES[ii][jj]=2;
	break;
	
      case 10:
	MDES[ii][jj]=2;
	break;	
	
      case 11:
	MDES[ii][jj]=3;
	break;
	
      case 12:
       	MDES[ii][jj]=2;
	break;
	
      case 13:
	MDES[ii][jj]=3;	
	break;
	
      case 14:
	MDES[ii][jj]=3;
	break;	
	
      case 15:
	MDES[ii][jj]=4;
	break;
	
      case 16:
	MDES[ii][jj]=1;	
	break;
	
      case 17:
	MDES[ii][jj]=2;	
	break;
	
      case 18:
	MDES[ii][jj]=2;
	break;
	
      case 19:
	MDES[ii][jj]=3;	
	break;
	
      case 20:
	MDES[ii][jj]=2;	
	break;
	
      case 21:
	MDES[ii][jj]=3;	
	break;
	
      case 22:	
	MDES[ii][jj]=3;	
	break;
	
      case 23:	
	MDES[ii][jj]=4;	
	break;
	
      case 24:	
	MDES[ii][jj]=2;	
	break;
	
      case 25:	
	MDES[ii][jj]=3;	
	break;
	
      case 26:	
	MDES[ii][jj]=3;	
	break;
	
      case 27:	
	MDES[ii][jj]=4;	
	break;
	
      case 28:	
	MDES[ii][jj]=3;	
	break;
	
      case 29:	
	MDES[ii][jj]=4;	
	break;
	
      case 30:	
	MDES[ii][jj]=4;	
	break;
	
      case 31:
	MDES[ii][jj]=5;	
	break;
	
      }
    }
  }
}

//FUNCION LIMPIADORA DE MATRICES
void limpiaM(unsigned int **MO){
  unsigned int ii=0;
  unsigned int jj=0;
  
  for(jj=0;jj<N;jj++){
    for(ii=0;ii<M;ii++){
      MO[ii][jj]=0;
    }
  }
}


void copiarM(unsigned int **A,unsigned int **B){ // De A --> B
  unsigned int ii,jj;
  for(jj=0;jj<N;jj++)
    for(ii=0;ii<M;ii++)
      B[ii][jj]=A[ii][jj];
}

void muestraM(unsigned int **G){
  unsigned int i=0,j=0;
  for(j=0;j<N;j++){
    for(i=0;i<M;i++){
      printf("%u	",G[i][j]);
    }
    printf("
");
  }
  printf("

");
}

long unsigned int sumaMtotal(unsigned int **A, unsigned int **B){
  long unsigned int fff=0;
  fff+= contadorPT(A); 
  fff+= contadorPT(B); 
  return fff;
}

long unsigned int sumaElM(unsigned int **A){
  
  unsigned int x=0,y=0;
  long unsigned int pote=0;
  
  for(y=0;y<N;y++)
    for(x=0;x<M;x++)
      pote+=A[x][y];
  
  return pote;
}


void sumaM(unsigned int **A, unsigned int **B, unsigned int **C){
  unsigned int x=0,y=0;
  
  for(y=0;y<N;y++){
    for(x=0;x<M;x++){
      C[x][y]= A[x][y]+B[x][y];
    }
  }
}






void drawString (void *font, float x, float y, char *str) {
  /* Draws string â&#128;&#153;strâ&#128;&#153; in font â&#128;&#153;fontâ&#128;&#153;, at world (x,y,0) */
  char *ch;
  glRasterPos3f(x, y, 0.0);
  for (ch= str; *ch; ch++)
    glutBitmapCharacter(font, (int)*ch);
}

void init(void){
  glClearColor (0.0, 0.0, 0.0, 0.0);
  glShadeModel (GL_SMOOTH);
  //glShadeModel(GL_FLAT);
  glEnable(GL_DEPTH_TEST);
  glShadeModel(GL_SMOOTH);
}


void display(void){
   
  unsigned int i=0,j=0; //contadores de matrices i,j
  //  long unsigned int fu=0;    //verificador de numero de particulas
  unsigned int g=0,p=0; //g contador de gelatina, p de polimeros
  int k=0;            //contador auxiliar
  long unsigned int  iterator=0; //contador de tiempo
  time_t  tpo;       //variable temporal para la semilla de rand()
  srand( (unsigned)(&tpo)); //inicializo la semilla rand()
    
  double aux=0.0; //variable auxiliar para generar numeros aleatorios

  unsigned int **I;  //matriz inicial 1->Gelatina y 2->Polimero
  unsigned int **IM; //matriz inicial de movimiento #s 0-15
  unsigned int **DM; //matriz destino de movimiento (de IM ->Traslaciones ->DM)
  unsigned int **CM; //matriz destino de colisiones (de DM ->Colisiones ->CM)
  unsigned int **T;  //matriz de numero de particulas tragadas
  unsigned int **TN; //matriz de numero de particulas en casillas en iteracion N
  double totalE=0.0; //total de espacios en la red NxM
  unsigned int Mgel=0; // total espacios * % gel
  unsigned int Mpol=0; // total espacios * % pol
 
 
 
  


  //unsigned long int retrazador=0;
  totalE= ( (double)N*(double)M);
  Mgel =(unsigned int) (totalE *PGEL);
  Mpol =(unsigned int) (totalE *PMET);
  printf("total espacios(N x M)*maxpart=%.0lf
",totalE);
  printf("Total gelatina=%u
",Mgel);
  printf("total polimeros=%u
",Mpol);

 
  //GL COMANDOS
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();
  glColor3f(1.0,1.0,1.0);
  
  // ************* VISTAS ******************
  gluLookAt(M/2, N/2, 150.0 , M/2,N/2,0.0,  0.0,1.0,0.0); 

 //Inicializo las matrices
  I=calloc(M,sizeof(I));
  if (!I) {
    perror("Error de memoria en I");
    abort();
  }
  for (i=0;i<M;i++) {
    I[i]=calloc(N,sizeof(*I));
    if (!I[i]) {
      for (k=i-1; k>=0; k--) free(I[k]);
      free(I);
      perror("Error de memoria en I[i]");
      abort();
    }
  }
  //listo matriz I voy por matriz IM
  
  IM=calloc(M,sizeof(IM));
  if (!IM) {
    for (k=M; k>=0; k--) free(I[k]);
    free(I);
    perror("Error de memoria en IM");
    abort();
  }
  for (i=0;i<M;i++){
    IM[i]=calloc(N,sizeof(*IM));
    if (!IM[i]) {
      for (k=i-1; k>=0; k--) free(IM[k]);
      free(IM);
      for (k=M; k>=0; k--) free(I[k]);
      free(I);
      perror("Error de memoria en IM[i]");
      abort();
    }
  }
  //listo matriz I,IM ahora por matriz DM
  DM=calloc(M,sizeof(DM));
  if (!DM) {
    for (k=M; k>=0; k--) {
      free(I[k]);
      free(IM[k]);
    }
    free(I);
    free(IM);
    perror("Error de memoria en DM");
    abort();
  }
  for(i=0;i<M;i++){
    DM[i]=calloc(N,sizeof(*DM));
    if (!DM[i]) {
      for (k=i-1; k>=0; k--) free(DM[k]);
      free(DM);
      for (k=M; k>=0; k--) {
        free(I[k]);
        free(IM[k]);          
      }
      free(I);
      free(IM);
      perror("Error de memoria en DM[i]");
      abort();
    }
  }
  
  //listo I,IM,DM termino voy por CM
  CM=calloc(M,sizeof(CM));
  if (!CM) {
    for (k=M; k>=0; k--) {
      free(I[k]);
      free(IM[k]);
      free(DM[k]);
    }
    free(I);
    free(IM);
    free(DM);
    perror("Error de memoria en CM");
    abort();
  }

  for (i=0;i<M;i++){
    CM[i]=calloc(N,sizeof(*CM));
    if (!CM[i]) {
      for (k=i-1; k>=0; k--) free(CM[k]);
      free(CM);
      for (k=M; k>=0; k--) {
        free(I[k]);
        free(IM[k]);
        free(DM[k]);
      }
      free(I);
      free(IM);
      free(DM);
      free(CM);
      perror("Error de memoria en CM[i]");
      abort();
    }
  }
  
  T=calloc(M,sizeof(T));
  if (!T) {
    for (k=M; k>=0; k--) {
      free(I[k]);
      free(IM[k]);
      free(DM[k]);
      free(CM[k]);
    }
    free(I);
    free(IM);
    free(DM);
    free(CM);
    perror("Error de memoria en T");
    abort();
  }
  for (i=0;i<M;i++){
    T[i]=calloc(N,sizeof(*T));
    if (!T[i]) {
      for (k=i-1; k>=0; k--) free(T[k]);
      free(T);
      for (k=M; k>=0; k--) {
        free(I[k]);
        free(IM[k]);
        free(DM[k]);
	free(CM[k]);
	
      }
      free(I);
      free(IM);
      free(DM);
      free(CM);
      free(T);
      perror("Error de memoria en T[i]");
      abort();
    }
  }

 TN=calloc(M,sizeof(TN));
  if (!TN) {
    for (k=M; k>=0; k--) {
      free(I[k]);
      free(IM[k]);
      free(DM[k]);
      free(CM[k]);
      free(T[k]);
    }
    free(I);
    free(IM);
    free(DM);
    free(CM);
    free(T);
    perror("Error de memoria en TN");
    abort();
  }
  for (i=0;i<M;i++){
    TN[i]=calloc(N,sizeof(*TN));
    if (!TN[i]) {
      for (k=i-1; k>=0; k--) free(TN[k]);
      free(TN);
      for (k=M; k>=0; k--) {
        free(I[k]);
        free(IM[k]);
        free(DM[k]);
	free(CM[k]);
	free(T[k]);
      }
      free(I);
      free(IM);
      free(DM);
      free(CM);
      free(T);
      free(TN);
      perror("Error de memoria en TN[i]");
      abort();
    }
  }
  


  // *****************RELLENO LA MATRIZ INICIAL DE DIBUJO "I" Y LA DE MOVIMIENTO IM ************ 
  //relleno metacrilatos
  while (p<Mpol){
    random0N(&aux,(double)M);
    i=(unsigned int)aux;
    random0N(&aux,(double)N);
    j=(unsigned int)aux;
    
    
    if( I[i][j]== 0){
      I[i][j]= 2; // valor 2 es METACRILATO
      if( (Mpol-p) >4 ){
	for(;;){
	  random0N(&aux,(double)15); //asigno movimiento a todo monomero.
	  if( (unsigned int)aux!=0){
	    break;
	  }
	}
	IM[i][j]=(unsigned int)aux;
	p+=contadorPE((unsigned int)aux);
	//	printf("Mpol=%u	 p=%u
",Mpol,p);
      }
      else if( (Mpol-p)>=4 ){
	IM[i][j]=15;
	p+=4;
	//printf(">=4:Mpol=%u	 p=%u
",Mpol,p);
      }
      else if( (Mpol-p)>=3 ){
	for(;;){
	  random0N(&aux,(double)15); //asigno movimiento a todo monomero.
	  if( (unsigned int)aux!=0){
	    if( contadorPE( (unsigned int)aux)==3)
	      break;
	  }
	}
	IM[i][j]=(unsigned int)aux;
	p+=contadorPE((unsigned int)aux);
	//printf(">=3:Mpol=%u	 p=%u
",Mpol,p);	
      }
      else if( (Mpol-p)>=2 ){
	for(;;){
	  random0N(&aux,(double)15); //asigno movimiento a todo monomero.
	  if( (unsigned int)aux!=0){
	    if( contadorPE( (unsigned int)aux)==2)
	      break;
	  }
	}
	IM[i][j]=(unsigned int)aux;
	p+=contadorPE((unsigned int)aux);
	//printf(">=2:Mpol=%u	 p=%u
",Mpol,p);	
      }
      else{
	for(;;){
	  random0N(&aux,(double)15); //asigno movimiento a todo monomero.
	  if( (unsigned int)aux!=0){
	    if( contadorPE( (unsigned int)aux)==1)
	      break;	  
	  }
	}
	IM[i][j]=(unsigned int)aux;
	p+=contadorPE((unsigned int)aux);
	//printf(">=1:Mpol=%u	 p=%u
",Mpol,p);	
      }
    }
  }
  
  //relleno la gelatina;
  while (g<Mgel){
    random0N(&aux,(double)M);
    i=(unsigned int)aux;
    random0N(&aux,(double)N);
    j=(unsigned int)aux;
    
    if( I[i][j]!= 1 && I[i][j]!= 2 ){
      I[i][j]= 1; // valor 1 es GELATINA
      IM[i][j]=(unsigned int)16;
      g++;
    }
  }
  
  
  
   
  //Verificacion inicial de Matriz de dibujo y movimiento (aparte de funciones contador de particulas  PT y PPC.
  //desarrollado en el programa segun el numero de la iteración para verificacion sucesiva...
  //   printf("Matriz inicial de dibujo
");
  //   muestraM(I);
  //   printf("Matriz inicial de Movimiento
");
  //   muestraM(IM);
  //   printf("Cantidad de particulas en matriz inicial= %lu
",contadorPT(IM));
  //   printf("En detalle:
");
  //   contadorPPC(IM,T);
  //   muestraM(T);
  
  limpiaM(T);
 
  
  
  for(iterator=0;iterator<maxiter;iterator++){
    
    limpiaM(TN);
    
    //printf("ANTES DE CONTAR: Matriz inicial de distribucion de velocidades 'IM' en iteracion %lu
",iterator+1);
    //muestraM(IM);
    //printf("ANTES DE CONTAR: Matriz inicial de distribucion de particulas 'TN' en iteracion %lu
",iterator+1);
    //muestraM(TN);
    
    contadorPPC(IM,TN); //cuenta particulas en cada iteración por casilla
      
    //printf("LUEGO DE CONTAR: Matriz inicial de distribucion de velocidades 'IM' en iteracion %lu
",iterator+1);
    //muestraM(IM);
    //printf("LUEGO DE CONTAR: Matriz inicial de distribucion de particulas 'TN' en iteracion %lu (IM)
",iterator+1);
    //muestraM(TN);
    // printf("Son un total de (IM)-->%lu	(TN)-->%lu  particulas
",contadorPT(IM), sumaElM(TN));
   
   

    //dibujo
    for(j=0;j<N;j++){
      for(i=0;i<M;i++){
	

	switch(I[i][j]){
	case 0:// agua
	  glColor3f(0.0,0.0,0.0); 
	  glPointSize(2.0);
	  //  glPointSize(T[i][j]); 
	  glPushMatrix();
	  glBegin(GL_POINTS);
	  glVertex2f((double)i,(double)j); 
	  glEnd();
	  glPopMatrix();
	  break;
	case 1: //gelatina BLANCO
	  glColor3f(1.0,1.0,1.0); 
	  glPointSize(2.0); 
	  //glPointSize(T[i][j]); 
	  glPushMatrix();
	  glBegin(GL_POINTS);
	  glVertex2f((double)i,(double)j); 
	  glEnd();
	  glPopMatrix();
	  break;
	case 2: //Metacrilato ROJO
	  glColor3f(1.0,0.5,0.5); 
	  glPointSize(1.0); 
	  //glPointSize(T[i][j]); 
	  glPushMatrix();
	  glBegin(GL_POINTS);
	  glVertex2f((double)i,(double)j); 
	  glEnd();
	  glPopMatrix();
	  break;
	case 3: //Metacrilato+gelatina NARANJA
	  //  glColor3f(1.0,0.69019,0.26274); 
	  glColor3f(0.0,1.0,0.0); 
	  glPointSize(2.0); 
	  //glPointSize(T[i][j]); 
	  glBegin(GL_POINTS);
	  glVertex2f((double)i,(double)j); 
	  glEnd();
	  break;
	}
      }
    }
    //glFlush();
    glutSwapBuffers();
    
    //muestraM(I);
    limpiaM(I); //para no dibujarle encima tengo q colocar la matriz de dibujo en 0
    
    
    ////////////////////////////////////////////////////////////////////////////////////////
    // **********************************  TRASLACIONES ******************************* ////
    ////////////////////////////////////////////////////////////////////////////////////////
    
    //printf("ANTES DE TRASLADAR: Matriz 'IM' en iteracion %lu
",iterator+1);
    //muestraM(IM);
    //printf("ANTES DE TRASLADAR: Matriz 'DM' en iteracion %lu
",iterator+1);
    //muestraM(DM);

    //printf("Iteracion: %lu
", iterator+1);
    //printf("Antes de trasladar: Son un total de (IM)-->%lu	(TN)-->%lu	(DM)-->%lu  particulas
",contadorPT(IM), sumaElM(TN),contadorPT(DM));
    //printf("A: %lu	%lu	%lu	%lu
",iterator+1,contadorPT(IM),contadorPT(DM),contadorPT(IM)-contadorPT(DM));
    traslaciones(IM,DM); //traslada de IM->DM
    
    //limpiaM(TN);
    //contadorPPC(DM,TN);
    //printf("LUEGO DE TRASLADAR: Matriz inicial de distribucion de particulas 'TN' en iteracion %lu (DM)
",iterator+1);
    //muestraM(TN);
    
    //printf("%lu	%lu	%lu	%lu
",iterator+1,contadorPT(IM),contadorPT(DM),contadorPT(IM)-contadorPT(DM));
    //printf("Despues de trasladar: Son un total de (IM)-->%lu	(TN)-->%lu (DM)-->%lu  particulas
",contadorPT(IM), sumaElM(TN),contadorPT(DM));
    
    //printf("DESPUES DE TRASLADAR: Matriz 'IM' en iteracion %lu
",iterator+1);
    //muestraM(IM);
    
    //printf("DESPUES DE TRASLADAR: Matriz 'DM' en iteracion %lu
",iterator+1);
    //muestraM(DM);
    //printf("%lu	IM->%lu	DM->%lu
",iterator+1,contadorPT(IM),contadorPT(DM));


    // ---------------------------  VERIFICACION 2 ---------------------------------------
    // printf("Son un total de (DM)-->%lu	(TN)-->%lu  particulas
",contadorPT(DM), sumaElM(TN));
    
   

    ////////////////////////////////////////////////////////////////////////////////////////
    // **********************************  COLISIONES ********************************* ////
    ////////////////////////////////////////////////////////////////////////////////////////
    copiarM(DM,CM); //COPIO DM a CM
    
    
    // printf("%lu	%lu	%lu
",iterator+1,contadorPT(DM),contadorPT(CM));
    // ---------------------------  VERIFICACION 3 ---------------------------------------
    //printf("Antes de colisionar: Son un total de (CM)-->%lu	(TN)-->%lu  particulas
",contadorPT(CM), sumaElM(TN));
    
    //printf("Resultado de copia de DM a CM(deben ser =) en iteracion %lu
",iterator+1);
    //muestraM(CM);
    
    //printf("ANTES DE COLISIONAR: Matriz 'DM' en iteracion %lu
",iterator+1);
    //muestraM(DM);
    //printf("ANTES DE COLISIONAR: Matriz 'CM' en iteracion %lu
",iterator+1);
    //muestraM(CM);
    //printf("ANTES DE COLISIONAR: Matriz 'T' en iteracion %lu
",iterator+1);
    //muestraM(T);
    
    colisiones(CM,T);
    
    printf("%lu	IM->%lu	DM->%lu	CM->%lu
",iterator+1,contadorPT(IM),contadorPT(DM),contadorPT(CM));
    // printf("%lu	%lu	%lu	%lu
",iterator+1,contadorPT(IM),contadorPT(DM),contadorPT(IM)-contadorPT(DM));
    
    //printf("Despues de colisionar: Son un total de (CM+T)-->%lu	(TN)-->%lu  particulas
",contadorPT(CM)+sumaElM(T), sumaElM(TN));
    
    //printf("DESPUES DE COLISIONAR: Matriz 'DM' en iteracion %lu
",iterator+1);
    //muestraM(DM);
    //printf("DESPUES DE COLISIONAR: Matriz 'CM' en iteracion %lu
",iterator+1);
    //muestraM(CM);
    // printf("DESPUES DE COLISIONAR: Matriz 'T' en iteracion %lu
",iterator+1);
    //muestraM(T);
    
   
    limpiaM(IM);
    limpiaM(DM);  //LIMPIO DM

    
 
    // ---------------------------  VERIFICACION 4 ---------------------------------------
  
    

  
    /////////////////////////////////////////////////////////////////////////////////////////
    // *****************************  TRADUZCO PARA DIBUJAR **************************** ////
    /////////////////////////////////////////////////////////////////////////////////////////
    for(j=0;j<N;j++){
      for(i=0;i<M;i++){
	switch(CM[i][j]){
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	case 9:
	case 10:
	case 11:
	case 12:
	case 13:
	case 14:
	case 15:
	  I[i][j]=2; //METRACRILATOS
	  break;
	case 16:
	  I[i][j]=1; //GELATINA
	  break;
	case 17:
	case 18:
	case 19:
	case 20:
	case 21:
	case 22:
	case 23:
	case 24:
	case 25:
	case 26:
	case 27:
	case 28:
	case 29:
	case 30:
	case 31:
	  I[i][j]=3; //MET+GEL
	  break;
	}
      }
    }
    
    //uestraM(T);
    copiarM(CM,IM);
    limpiaM(CM);
    
    
   
    // printf("numero de particulas en ite %lu es (TN)->%lu + %lu(T) = %lu
",iterator+1,contadorPT(TN),contadorPT(T), sumaMtotal(T,TN));

    //   printf("%lu	%lu	%lu
",iterator+1,contadorPT(TN),contadorPT(T));
    //limpiaM(T);
    limpiaM(TN);
    
    
  }//fin de iterator
  
  //printf("y la T es:
");
  //muestraM(T);
  
  //Inicio de liberacion de memoria
   
  for (k=M-1; k>=0; k--) {
    free(I[k]);
    free(IM[k]);
    free(DM[k]);
    free(CM[k]);
    free(T[k]);
  }
  free(I);
  free(IM);
  free(DM);
  free(CM);
  free(T);  
}
/*
  void reshape (int w, int h){
  glViewport (0, 0, (GLsizei) w, (GLsizei) h);
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  if (w <= h)
  gluOrtho2D (0.0, 30.0, 0.0, 30.0*(GLfloat) h/(GLfloat) w);
  else
  gluOrtho2D (0.0, 30.0*(GLfloat) w/(GLfloat) h, 0.0, 30.0);
  glMatrixMode(GL_MODELVIEW);
  }*/

void reshape (int w, int h){
  //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 300.0);
  glMatrixMode (GL_MODELVIEW);
}
 
void keyboard(unsigned char key, int x, int y){
  switch (key) {
  case 27:
    exit(0);
    break;
  }

}

int main(int argc, char** argv){
  FILE *dats;
  
  //  char caso[40]="Simulacion";
  
  if(argc!=2){
    printf("
	---------------------------------------
");
    printf("	USO INCORRECTO!!!!
	USO: exe.o in.dat  
");
    printf("	-----------------------------------------

");
    exit(0);
  }
  if( (dats=fopen(argv[1],"r"))==NULL){
    printf("
No pude abrir %s
",argv[1]);
    exit(1);
  }
  
  
  //Leo las entradas de archivo
  
  fscanf(dats,"%*s	%u",&N);   //leo N->Alto
  printf("N=%u
",N);
  
  fscanf(dats,"%*s	%u",&M);   //leo M->Ancho
  printf("M=%u
",M);
  
  fscanf(dats,"%*s	%lf",&PGEL); // leo porcentaje de GEL DEL TOTAL PANTALLA
  printf("Porcentaje gelelatina =%.3lf
",PGEL);
  PGEL/=100.0;
  fscanf(dats,"%*s	%lf",&PMET); //leo porcentaje de META DEL TOTAL PANTALLA
  
  printf("Porcentaje metacrilato = %.3lf
",PMET);
  PMET/=100.0;
  
  
  fscanf(dats,"%*s	%lf",&PP20); //Leo PP20
  printf("PP20 = %.2lf
",PP20); //imprimo
  PP20/=100.0;                      //divido
  
  fscanf(dats,"%*s	%lf",&PP31); //Leo PP30
  printf("PP31 = %.2lf
",PP31);
  PP31/=100.0;
  
  fscanf(dats,"%*s	%lf",&PP40); //Leo PP40  q de 4 ->0
  printf("PP40 = %.2lf
",PP40);
  PP40/=100.0;

  fscanf(dats,"%*s	%lf",&PPGM21); //Leo PPGM21 Porcentaje de Probabilidad de choque Gelatina-Polimero de 2->1
  printf("PPGM21 = %.2lf
",PPGM21); //imprimo
  PPGM21/=100.0;                      //divido
  
  fscanf(dats,"%*s	%lf",&PPGM31); //Leo PPGM31 Porcentaje de Probabilidad de choque Gelatina-Polimero de 3->1
  printf("PPGM31 = %.2lf
",PPGM31);
  PPGM31/=100.0;
  
  fscanf(dats,"%*s	%lf",&PPGM41);//Leo PPGM21 Porcentaje de Probabilidad de choque Gelatina-Polimero de 4->1
  printf("PPGM41 = %.2lf
",PPGM41);
  PPGM41/=100.0;

  fscanf(dats,"%*s	%lf",&PPGM51);//Leo PPGM21 Porcentaje de Probabilidad de choque Gelatina-Polimero de 5->1
  printf("PPGM41 = %.2lf
",PPGM51);
  PPGM51/=100.0;
  
  fscanf(dats,"%*s	%u",&maxiter); //Leo numero maximo de iteraciones;
  printf("maxiter = %u
",maxiter);

  fscanf(dats,"%*s	%u",&maxpart); //Leo numero maximo de PARTICULAS EN UN SITIO i,j
  printf("maxpart = %u
",maxpart);
  fclose(dats);
  
  glutInit(&argc, argv);
  //glutInitDisplayMode (GLUT_SINGLE|GLUT_RGB); //single usa flush()o finish
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  //glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_SINGLE);
  glutInitWindowSize (M,N);
  glutInitWindowPosition (20, 20);
  glutCreateWindow ("Simulacion");
  init ();
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutKeyboardFunc(keyboard);
  glutMainLoop();
  
  return 0;
}


/*

   //  gluLookAt(0.0, 0.0,1.75.0 , 0.0,0.0,0.0,  0.0,1.0,0.0); 
   // drawString (GLUT_BITMAP_HELVETICA_18, -0.35, 1.05,sele);
   //  glFlush();

*/


PD: Thank in advance… and I have this problem with several programs and I wanna finish this issue right now… :slight_smile:
PD2: This is a CA code. (Cellular Automata)

Any ideas?
Don’t care about seeing the whole code… just the OpenGL functions… I really dont know if it’s for reshape,display or the order they are called in the main function.

Your display function is called whenever your system figures that it needs to redraw the window. This can happen for a number of reasons, two of them are: the window becomes visible and your window is resized.
I’m quite certain that glut calls your resize function at program start before the first call to your display function, in order to give you a chance to setup your projection matrix.
So your glut implementation may (I’m just guessing here) not care about multiple redundant redraw events and just call your display function twice (once for being resized, once for becoming visible).

That is the reason why your display function should not do anything that’s not supposed to happen anytime your window gets drawn, like (I suppose) updating your simulation.
You can simply separate drawing from updating your simulation, the later one triggerd by user input or periodically.

On a completely different topic, I couldn’t help but notice the way you allocate your matrice. I would strongly recommend to use one dimensional arrays instead, the individual elements beeing accessed by matrix[i*&lt;number of columns&gt; + j] instead of matrix[i][j].
That will save you a_lot of runtime costs caused by allocating/freeing memory (and is less error prone).

Ok I’ll try to see what’s wrong about you just said.

And about the topic of matrix, I’ll review that in the 3D after I present this work :slight_smile:

Thank you very much !!!