Archivo

Archivo para la Categoría "Programación"

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.

Seguir

Get every new post delivered to your Inbox.