Nel
precedente articolo, ho descritto la variante di
automa cellulare proposta da
John Horton Conway, battezzata
The Game of Life. Analizzerò ora l’automa in ogni sua parte suggerendo una soluzione implementativa, soffermandomi sugli aspetti principali.
Life si svolge su una
griglia divisa in celle di uguali dimensioni e caratteristiche. La struttura dati portante non può che essere una matrice o meglio un array bidimensionale di dimensione
mXn. Ovviamente la dimensione della matrice indica il numero massimo di celle della griglia, di conseguenza è indicativo del numero massimo di organismi gestibili simultaneamente in un determinato istante.
Analizziamo ora gli stati delle celle: ogni cella della griglia può ospitare un organismo vivo o uno morto; per rappresentare i due stati è più pratico usare un tipo booleano, associando i valori
TRUE e
FALSE rispettivamente agli stati
vivo e
morto. Ricorrendo ad una pratica progettazione modulare, occorre implementare anzitutto una routine per costruire la griglia (matrice), chiamiamola
InitGrid(). Per rendere il gioco interessante, si può fornire in ingresso alla routine di inizializzazione il numero massimo di organismi che si desidera gestire, in modo tale da poter sperimentare il gioco in uno spazio di dimensione variabile a ogni partita.
InitGrid() genera prima la griglia, poi la inizializza a
FALSE restituendo un riferimento ad essa; ipotizzando la necessità di resettare il gioco in un determinato istante, è possibile implementare separatamente la routine di inizializzazione da quella di generazione della griglia, ed anzi ritengo che questa seconda soluzione sia più pratica ed elegante.
E’ ora necessario impostare uno stato iniziale per ogni cella: questa operazione richiede l’implementazione di una routine
StartGrid(). E’ consigliabile costruire un menù che consenta di scegliere se assegnare gli stati manualmente o in modalità casuale; ad ogni cella della griglia dovrà essere assegnato un valore booleano corrispondente ad un determinato stato.
Le routine
InitGrid() e
StartGrid(), si basano su uno stesso blocco di codice principale per la visita della matrice, ovviamente si tratta di un ciclo iterativo annidato. Dato che si conosce a priori la dimensione della matrice, è opportuno ricorrere ad un ciclo
for. Il blocco di codice in C-like dev’essere strutturato come segue:
<span style="font-size:1.0em">…
for(i = 0; i < m; i++) // si sposta lungo le righe della matrice/griglia
for(j = 0; j < n; j++) // si sposta lungo le colonne della matrice/griglia
{…
Inizializza a FALSE | assegna stato casuale | assegna stato manuale;
…
}
…
</span>
Lo stesso blocco di codice si ripete anche nella routine per la stampa a video della griglia
ShowGrid(). Restano da analizzare le due routine più “complesse” dal punto di vista implementativo, ovvero le routine per l’analisi dello stato dei vicini di ogni cella e quella per l’applicazione delle regole di transizione.