[ Foro de C ]

Ayuda con "El juego de la vida" en C. Como crear un contador en una "matriz esferica" ?

22-Dec-2013 00:28
Invitado (j59)
1 Respuestas

Hola, imagino que conoceréis las reglas del juego de la vida... http://es.wikipedia.org/wiki/Juego_de_la_vida me han mandado hacer este juego con programación en C y estoy atascado en la función de Contar Vecinos Vivos. Esta función sirve para contar los vecinos vivos que tiene cada celda, y en función del número de vecinos vivos, las células nacen o mueren (si tiene 3 vecinos exactamente, una célula surge de la nada, por ejemplo)

Todas las demás funciones ya las he hecho, pero en esta me falta un detalle, y es que el "mundo" es esférico, es decir, la última casilla de cada fila se conecta con la primera, y la última casilla de una columna se conecta con con la primera también...(es decir, que cada celda tiene en total ocho celdas vecinas)... no sé si me explico bien. La cosa es que no se hacer una función que cuente los vecinos de cada celda teniendo en cuenta este último detalle. He hecho el siguiente código para contar los vecinos en los límites de la matriz, pero no funciona del todo bien :/


int Contar_Vecinos_Vivos(int i, int j){ 

int vecinos = 0; 

if(j-1 < 0) { 

  if (vida1[i-1][N_COLUMNAS-1]=='@'){ 
    vecinos++; 
 } 
  if (vida1[i][N_COLUMNAS-1]=='@'){ 
    vecinos++; 
 } 
 if (vida1[i+1][N_COLUMNAS-1]=='@'){ 
    vecinos++; 
 } 
 } 

 if(j+1 >= N_COLUMNAS) { 
       if (vida1[i-1][0]=='@'){ 
    vecinos++; 
 } 
  if (vida1[i][0]=='@'){ 
    vecinos++; 
 } 
 if (vida1[i+1][0]=='@'){ 
    vecinos++; 
 } 
 } 

 if (i-1<=0){ 
     if (vida1[N_FILAS][j-1]=='@'){ 
    vecinos++; 
 } 
  if (vida1[N_FILAS][j]=='@'){ 
    vecinos++; 
 } 
 if (vida1[N_FILAS][j-11]=='@'){ 
    vecinos++; 
 } 
 } 

if (i+1>=N_FILAS){ 
    if (vida1[0][j-1]=='@'){ 
    vecinos++; 
 } 
 if (vida1[0][j]=='@'){ 
    vecinos++; 
 } 
 if (vida1[0][j+1]=='@'){ 
    vecinos++; 
 } 
} 


A ver si podéis echarme una mano por favor. Por internet he encontrado este código que cuenta correctamente los vecinos de cada celda, pero sin tener en cuenta que el mundo es esférico :/


int Contar_Vecinos_Vivos(int i, int j){ 

int vecinos = 0; 

if(i-1 >= 0 && j-1 >= 0) { 

  if(vida1[i-1][j-1] == '@') 
   vecinos++; 
 } 

 if(i-1 >= 0) { 

  if(vida1[i-1][j] == '@') 
   vecinos++; 
 } 

 if(i-1 >= 0 && j+1 <= N_COLUMNAS-1) { 

  if(vida1[i-1][j+1] == '@') 
   vecinos++; 
 } 

 if(j-1 >= 0) { 

  if(vida1[i][j-1] == '@') 
   vecinos++; 
 } 

 if(j+1 <= N_COLUMNAS-1) { 

  if(vida1[i][j+1] == '@') 
   vecinos++; 
 } 


 if(i+1 <= N_FILAS-1 && j-1 >= 0) { 

  if(vida1[i+1][j-1] == '@') 
   vecinos++; 
 } 

 if(i+1 <= N_FILAS-1) { 

  if(vida1[i+1][j] == '@') 
   vecinos++; 
 } 

 if(i+1 <= N_FILAS-1 && j+1 <= N_COLUMNAS-1){ 

  if(vida1[i+1][j+1] == '@') 
   vecinos++; 
} */ 
return vecinos; 
} 


Muchas gracias de antemano!


23-Dec-2013 17:28
Nacho Cabanes (+83)

Eso de comprobar los 8 vecinos, uno por uno, es una solución que me parece un poco engorrosa.

A mí me gusta más un doble "for", que recorra desde la posición anterior a la siguiente, así:


for (fila=-1; fila<=1; fila++)
    for (columna=-1; columna<=1; columna++)
        if(tablero[x+columna][y+fila] == '@') 
            vecinos++;


En ese fuente faltan dos detalles:

- Por una parte, no deberías contar la casilla actual (fila 0, columna 0), pero lo he conservado así para que se viera mejor la lógica del "doble for".

- Por otra parte, si tu matriz es "esférica", basta con decir "si he obtenido una posición negativa, miro la del final". Por ejemplo, si tienes 10 columnas, y estás en la 0, a su izquierda estaría la -1, que deberías transformar en la 9 (basta con sumarle la cantidad de columnas).

Con esos dos detalles, podría quedar algo como:


for (fila=-1; fila<=1; fila++)
    for (columna=-1; columna<=1; columna++)
        if ((fila !=0 ) && (columna != 0))  // Si no en posicion central
        {
            if (x+columna < 0)
                columna += anchoTablero;  // Dar la vuelta en matriz esferica
            if (y+fila < 0)
                fila += altoTablero;  // Dar la vuelta en matriz esferica
                
            if(tablero[x+columna][y+fila] == '@')  // Finalmente, miro el vecino
                vecinos++;
        }







(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)