El juego de la vida – Lenguaje de programación C
El juego de la vida es un autómata celular diseñado por el matemático británico John Horton Conway en el año 1970.
Este simula en cierta manera el mundo en el que vivimos, nos encontramos con una cuadricula de tamaño predeterminado (por nosotros) en el que cada casilla puede tener dos estados, vivo o muerto, este estado viene determinado por las casillas circundantes mediante unas sencillas reglas.
- Una casilla muerta con exactamente 3 casillas vecinas vivas “nace” (el siguiente turno estará viva).
- Una casilla viva con 2 ó 3 casillas vecinas vivas sigue viva, si solo tiene 1 vecino muere por soledad, si tiene mas de 3 vecinos muere por superpoblación.

En clase de programación se propuso como ejercicio realizar el juego de la vida en C, a continuación os dejo el código de mi programa.
En el juego se pueden formar múltiples formas, algunas variables, otras intermitentes y otras fijas e inamovibles, en este programa solo se ha realizado un “bloque” principal pues es mi primera experiencia programando en tablas bidimensionales, el juego original estaría formado por docenas de bloques que irían evolucionando independientemente, se fusionarían o desaparecerían, como por ejemplo, podréis observar en el gif de arriba, para mas información, tenéis la Wikipedia.
#include<stdio.h> #include<conio.h> #define X 20 //el numero de filas declarado en una constante #define Y 20 //el numero de columnas declarado en una constante int main() { //declaración de variables int ix, iy, ixd, ixe, iys, iyi, vius; //las variables ixd(ix derecha), iys(iy superior).etc.. //sirven para comprobar las casillas alrededor de la casilla que se examina char mundo[X][Y], estado[X][Y], opc; //una tabla se mostrará, en la otra se aplicarán los cambios //inicializar tabla mundo for(ix=0; ix<X; ix++) { for(iy=0; iy<Y; iy++) { mundo[ix][iy]=' '; } } //mostrar un menú y escoger el estado inicial de nuestro juego de la vida printf("Selecciona el estado inicial:\na)bloque\nb)barco\nc)parpadeador\nd)sapo\ne)planeador\nf) nave ligera\n"); do //mientras la opción no sea valida, seguirá leyendo hasta dar con una letra valida { scanf("%c", &opc); }while(opc<'a' || opc>'f'); //situar estado inicial switch(opc) { case 'a':mundo[0][0]='X';mundo[0][1]='X';mundo[1][0]='X';mundo[1][1]='X';break; case 'b':mundo[0][0]='X';mundo[0][1]='X';mundo[1][0]='X';mundo[1][2]='X';mundo[2][1]='X';break; case 'c':mundo[0][0]='X';mundo[0][1]='X';mundo[0][2]='X';break; case 'd':mundo[0][1]='X';mundo[0][2]='X';mundo[0][3]='X';mundo[1][0]='X';mundo[1][1]='X';mundo[1][2]='X';break; case 'e':mundo[0][0]='X';mundo[0][1]='X';mundo[0][2]='X';mundo[1][0]='X';mundo[2][1]='X';break; case 'f':mundo[0][1]='X';mundo[0][4]='X';mundo[1][0]='X';mundo[2][0]='X';mundo[2][4]='X';mundo[3][0]='X';mundo[3][1]='X';mundo[3][2]='X';mundo[3][3]='X';break; default: printf("error, ha de ser entre 'a' i 'f'"); } //bucle infinito, dado que el juego de la vida no tiene final while(1==1) { //for para mostrar la tabla mundo for(ix=0; ix<X; ix++) { for(iy=0; iy<Y; iy++) { printf("%c",mundo[ix][iy]); } printf("\n"); } system("pause"); //pausa el juego, hasta que pulsemos una tecla, no mostrará el siguiente estado de la tabla //recorrido total para comprobar si ha llegado al limite de la tabla for(ix=0; ix<X; ix++) { for(iy=0; iy<Y; iy++) { vivos=0; if(ix>=X-1) ixd=0; else ixd=ix+1; if(iy>=Y-1) iyi=0; else iyi=iy+1; if(ix<=0) ixe=X-1; else ixe=ix-1; if(iy<=0) iys=Y-1; else iys=iy-1; //comprobación para saber si los vecinos están vivos o muertos if(mundo[ixd][iy]=='X') vivos++; if(mundo[ixe][iy]=='X') vivos++; if(mundo[ix][iys]=='X') vivos++; if(mundo[ix][iyi]=='X') vivos++; if(mundo[ixd][iys]=='X') vivos++; if(mundo[ixe][iys]=='X') vivos++; if(mundo[ixd][iyi]=='X') vivos++; if(mundo[ixe][iyi]=='X') vivos++; //condicional para determinar si la casilla vive o muere if(mundo[ix][iy]=='X') { // esta vivo if(vivos<=1 || vivos>3) { estado[ix][iy]=' '; }else{ estado[ix][iy]='X'; } }else { // esta muerto if(vivos==3) { estado[ix][iy]='X'; }else{ estado[ix][iy]=' '; } } }// final del for iy } // final del for ix //guardamos la tabla estado en la tabla mundo, para que la próxima vez que entre en el bucle se muestre actualizada for(ix=0; ix<X; ix++) { for(iy=0; iy<Y; iy++) { mundo[ix][iy]=estado[ix][iy]; } } //final del for para guardar la tabla estado en la tabla mundo } //final del bucle }
#include<stdio.h>
#include<conio.h>
#define X 20
#define Y 20
int main()
{
//variables
int ix, iy, ixd, ixe, iys, iyi, vius, aux;
char mundo[X][Y], estado[X][Y], opc;
//netejar mundo
for(ix=0; ix<X; ix++)
{
for(iy=0; iy<Y; iy++)
{
mundo[ix][iy]=’ ‘;
}
}
//mostrar menu i escollir estado inicial
printf(“Selecciona l’estado inicial:\na)bloc\nb)barca\nc)semafor\nd)gripau\ne)planador\nf)astronau\n”);
do
{
scanf(“%c”, &opc);
}while(opc<’a’ || opc>’f');
//situar estado inicial
switch(opc)
{
case ‘a’:mundo[0][0]=’X';mundo[0][1]=’X';mundo[1][0]=’X';mundo[1][1]=’X';break;
case ‘b’:mundo[0][0]=’X';mundo[0][1]=’X';mundo[1][0]=’X';mundo[1][2]=’X';mundo[2][1]=’X';break;
case ‘c’:mundo[0][0]=’X';mundo[0][1]=’X';mundo[0][2]=’X';break;
case ‘d’:mundo[0][1]=’X';mundo[0][2]=’X';mundo[0][3]=’X';mundo[1][0]=’X';mundo[1][1]=’X';mundo[1][2]=’X';break;
case ‘e’:mundo[0][0]=’X';mundo[0][1]=’X';mundo[0][2]=’X';mundo[1][0]=’X';mundo[2][1]=’X';break;
case ‘f’:mundo[0][1]=’X';mundo[0][4]=’X';mundo[1][0]=’X';mundo[2][0]=’X';mundo[2][4]=’X';mundo[3][0]=’X';mundo[3][1]=’X';mundo[3][2]=’X';mundo[3][3]=’X';break;
default: printf(“error, ha de ser entre ‘a’ i ‘f’”);
}
//proces
//bucle infinit
while(1==1)
{ //for per mostra la taula mundo
for(ix=0; ix<X; ix++)
{
for(iy=0; iy<Y; iy++)
{
printf(“%c”,mundo[ix][iy]);
}
printf(“\n”);
}
system(“pause”);
//recorregut total per comprobar si ha arrivat al limit del tauler
for(ix=0; ix<X; ix++)
{
for(iy=0; iy<Y; iy++)
{
vius=0;
if(ix>=X-1)
ixd=0;
else
ixd=ix+1;
if(iy>=Y-1)
iyi=0;
else
iyi=iy+1;
if(ix<=0)
ixe=X-1;
else
ixe=ix-1;
if(iy<=0)
iys=Y-1;
else
iys=iy-1;
//comprobació de si els veins estan vius o morts
if(mundo[ixd][iy]==’X') vius++;
if(mundo[ixe][iy]==’X') vius++;
if(mundo[ix][iys]==’X') vius++;
if(mundo[ix][iyi]==’X') vius++;
if(mundo[ixd][iys]==’X') vius++;
if(mundo[ixe][iys]==’X') vius++;
if(mundo[ixd][iyi]==’X') vius++;
if(mundo[ixe][iyi]==’X') vius++;
//condicional per determinar si la casella viu o mor
if(mundo[ix][iy]==’X')
{
// esta viu
if(vius<=1 || vius>3)
{
estado[ix][iy]=’ ‘;
}else{
estado[ix][iy]=’X';
}
}else
{
// esta mort
if(vius==3)
{
estado[ix][iy]=’X';
}else{
estado[ix][iy]=’ ‘;
}
}
}// for iy
} // for ix
//guardem la taula estado amb l’estado actual a la taula mundo, per a que la seguent vegada que entri al bucle pugi mostrarla actualitzada
for(ix=0; ix<X; ix++)
{
for(iy=0; iy<Y; iy++)
{
mundo[ix][iy]=estado[ix][iy];
}
}
}
return 0;
}
Por motivos de fomatado de texto, es imposible mostrar correctamente todo el código sin que se excedan los margenes, dado que considero que realizar saltos de linea podría dificultar la lectura del código, adjunto documento de texto para que podáis descargaros el código cómodamente y así compilarlo vosotros mismos.
Agradecería el gesto de comunicar aquellos posibles errores detectados en el código, para así facilitar-les la vida a los lectores.