Sei sulla pagina 1di 7

Game of Life: implementazione del gioco della vita nel linguaggio C

Andrea De Cosmo
Il gioco della vita un automa cellulare bidimensionale tramite cui possibile osservare il comportamento di celle capaci di interagire tra loro. La particolarit di tale automa che a partire da regole semplici pu originare comportamenti complessi (2512 possibili regole) e la sua denominazione legata di fatto alla complessit della vita, oltre che alla possibilit delle celle di assumere rispettivamente due stati: 0 o 1 ossia morte o vita. Ogni cella caratterizzata dalla presenza di 8 vicini e le regole che descrivono linterazione della cella con essi risultano essere: una cella resta viva se soltanto due o tre delle celle vicine sono vive. una cella nasce se e soltanto se tre delle celle vicine sono vive. nei restanti casi la cella muore. Il programma che simula il Game of Life prende in input le dimensioni del reticolo, variabili per i due assi, il tempo di osservazione dellautoma e la sua congurazione iniziale. Ed proprio la sua congurazione iniziale a denire ogni possibile forma che lautoma pu assumere nella sua evoluzione. Esempi di congurazioni particolari sono: Il blocco

Un particolare tipo di congurazione statica Il lampeggiatore o blinker

Un particolare tipo di congurazione periodica oscillante (T = 2) R-pentomino

Un particolare tipo di congurazione che si stabilizza dopo 1103 generazioni 1

E possibile inoltre utilizzare una congurazione random di cui qui possiamo osservare lo sviluppo per 9 passi temporali:

parametri di riproducibilit: Dx = 6 Dy = 6 seed = 1342 Ci sono poi congurazioni che possono crescere indenitamente come il Cannone di alianti di Gosper.

Il ruolo della congurazione iniziale risulta dunque primario in tale simulazione, subentrano per parametri importanti quali le condizioni al bordo e la simultaneit del cambiamento di stato delle singole celle. Nel programma, denita la dimensione del reticolo, le celle collocate oltre assumono il valore zero, ossia vengono considerate morte. Non vi sono dunque condizioni periodiche al bordo. Mentre per quanto riguarda la simultaneit, essa ottenuta tramite la denizione di due ambienti, uno in cui, per ogni cella in analisi, viene eettuata la somma delle 8 vicine e laltro in cui viene assegnato il nuovo valore ad ogni cella, in considerazione della somma ottenuta nel precedente. I dati in output vengono inseriti nel le DATAGameofLife.dat e contengono le coordinate delle celle e il loro stato, mentre per la realizzazione dellanimazione (di cui le immagini sopra sono un esempio) si utilizza la funzione AnimationGenerator(...) che per la stampa utilizza il le PLOTGameofLife.dat . Altre informazioni relative al codice sono presenti come commenti nel listato riportato di seguito.

LISTATO
#include<stdio.h> #include<stdlib.h>

#define ALIVE 1 #define DEAD 0 /*************PROTOTIPI*************/ int InputData(char *, int, int); void Initialization(int **, int, int, FILE *); int Neighbors(int **, int, int, int, int); int Dead_or_Alive(int **, int, int, int); void printOnFile(FILE *, int **, int, int, int); void array2DCopy(int **, int **, int, int); void AnimationGenerator(int **, int, int, int, FILE *); main(){ int Dx, Dy; int seed, i; int x, y; int t, T; int Sum; int ** Surroundings; int ** NewSurroundings; FILE * fp1, *fp2; if((fp1 = fopen("DATAGameofLife.dat", "w")) == NULL){ printf("Errore nellapertura del file DATAGameofLife.dat\n"); exit(EXIT_FAILURE); } /***File su cui viene realizzata unanimazione delle celle al variare del parametro tempo***/ if((fp2 = fopen("PLOTGameofLife.dat", "w")) == NULL){ printf("Errore nellapertura del file PLOTGameofLife.dat\n"); exit(EXIT_FAILURE); } Dx = InputData("Inserire la dimensione x \nDx = ", 2, 1000); Dy = InputData("Inserire la dimensione y \nDy = ", 2, 1000);

/****Ambiente che garantisce la possibilita di aggiornare simultaneamente le celle****/ Surroundings = (int **) calloc(Dx, sizeof(int *)); for(i = 0; i < Dx; i++){ Surroundings[i] = (int *) calloc(Dy, sizeof(int)); } /****Ambiente finale definito dopo laggiornamento****/ NewSurroundings = (int **) calloc(Dx, sizeof(int *)); for(i = 0; i < Dx; i++){ NewSurroundings[i] = (int *) calloc(Dy, sizeof(int)); 3

} T = InputData("Inserire il tempo di osservazione (valore intero) dellevoluzione dellautoma\nt = ", 1, 10000); seed = InputData("Inserire il seme per una eventuale generazione di numeri psedocasuali\nseed = ", 0, 1000000); srand48(seed); t = 0; fprintf(fp1, "#First Configuration t = %d\n", t); fprintf(fp1, "#x y S\n"); /* S rappresenta lo stato di vita di una cella cio viva (1) o morta (0)*/ Initialization(Surroundings, Dx, Dy, fp1); AnimationGenerator(Surroundings, Dx, Dy, t, fp2); for(t = 1; t<T; t++){ fprintf(fp1, "#New Configuration t = %d\n", t); fprintf(fp1, "#x y S\n"); for(x = 0; x < Dx; x++){ for(y = 0; y < Dy; y++){ /***La funzione Neighbors restituisce la somma degli 8 vicini della cella (x, y)***/ Sum = Neighbors(Surroundings, x, y, Dx, Dy); /***Le celle del nuovo ambiente vengono assegnate secondo le regole definite in Dead_or_Alive***/ NewSurroundings[x][y] = Dead_or_Alive(Surroundings, Sum, x, y); printOnFile(fp1, NewSurroundings, x, y, t); } } /***Copia il nuovo ambiente nel vecchio***/ array2DCopy(NewSurroundings, Surroundings, Dx, Dy); AnimationGenerator(NewSurroundings, Dx, Dy, t, fp2); } /*****Operazioni conclusive******/ fclose(fp1); fclose(fp2); for(i=0; i< Dx; i++){ free(Surroundings[i]); free(NewSurroundings[i]); } free(Surroundings); free(NewSurroundings); }

/***************************FUNZIONI*****************************/

/****************************************************************/ int InputData(char * message, int min, int max){ int cond; double temp; printf("%s", message); do{ scanf("%lf", &temp); cond = ((temp >= max) && (temp <= min)) ? 1 : 0; if(cond) printf("Il valore deve essere compreso tra %d e %d. \n%s", min, max, message); } while(cond); return(temp); } /****************************************************************/ void Initialization(int ** Surroundings, int Dx, int Dy, FILE * fp1){ double rand; int x, y; int choice; printf("\nSe si desidera generare lautoma casualmente inserire 1 altrimenti inserire 0\n"); choice = InputData("choice = ", 0, 1); for(x = 0; x < Dx; x++){ for(y = 0; y < Dy; y++){ if(choice == 1){ rand = (double)lrand48()/RAND_MAX; Surroundings[x][y] = (rand <= 0.5) ? ALIVE : DEAD; } else{ printf("(%d, %d) = ", x, y); scanf("%d", &Surroundings[x][y]); } printOnFile(fp1, Surroundings, x, y, 0); } } } /****************************************************************/ int Neighbors(int ** Surroundings, int centerX, int centerY, int Dx, int Dy){ int SumNeighbor; int x, y; int move1, move2; 5

SumNeighbor = 0; for(move1 = -1; move1 <= 1; move1++){ x = centerX + move1; for(move2 = -1; move2 <= 1; move2++){ y = centerY + move2; if((x>-1) && (y>-1) && (x<Dx) && (y<Dy) &&((x != centerX) || (y != centerY))){ SumNeighbor += Surroundings[x][y]; } else SumNeighbor += 0; } } return(SumNeighbor); } /****************************************************************/ int Dead_or_Alive(int ** Surroundings, int Sum, int x, int y){ if(Surroundings[x][y] == ALIVE){ if(Sum == 2 || Sum == 3) return ALIVE; else return DEAD; } else if(Surroundings[x][y] == DEAD){ if(Sum == 3) return ALIVE; else return DEAD; } } /****************************************************************/ void printOnFile(FILE * fp1, int ** Surroundings, int x, int y, int t){ if(Surroundings[x][y] == ALIVE){ fprintf(fp1, "%d %d %d\n", x, y, ALIVE); } else if(Surroundings[x][y] == DEAD){ fprintf(fp1, "%d %d %d\n", x, y, DEAD); } } /****************************************************************/ void array2DCopy(int ** Input, int ** Output, int Dx, int Dy){ int x, y; for(x = 0; x < Dx; x++){ for(y = 0; y < Dy; y++){ Output[x][y] = Input[x][y]; } } } /****************************************************************/ 6

void AnimationGenerator(int ** NewSurroundings, int Dx, int Dy, int t, FILE * fp){ int x, y; if(t == 0){ printf("\nVerra realizzata unanimazione riprodotta interamente sul file \nPLOTGameofLife.dat\n"); } fprintf(fp, "\nConfigurazione al tempo t = %d \n", t); for(x = 0; x < Dx; x++){ for(y = 0; y < Dy; y++){ fprintf(fp, "|"); (NewSurroundings[x][y] == ALIVE) ? (fprintf(fp, "X")) : (fprintf(fp, " ")); if(y == (Dy - 1)) fprintf(fp, "|"); } fprintf(fp, "\n"); } fprintf(fp, "\n"); } /****************************************************************/