int compte_voisins_vivants (int i, int j, grille g){ int v = 0, l=g.nbl, c = g.nbc; v+= est_vivante(modulo(i-1,l),modulo(j-1,c),g); v+= est_vivante(modulo(i-1,l),modulo(j,c),g); v+= est_vivante(modulo(i-1,l),modulo(j+1,c),g); v+= est_vivante(modulo(i,l),modulo(j-1,c),g); v+= est_vivante(modulo(i,l),modulo(j+1,c),g); v+= est_vivante(modulo(i+1,l),modulo(j-1,c),g); v+= est_vivante(modulo(i+1,l),modulo(j,c),g); v+= est_vivante(modulo(i+1,l),modulo(j+1,c),g); return v; }
int compte_voisins_non_cyclique (int i, int j, grille g){ int v = 0, l=g.nbl, c = g.nbc; if (i>0) { // voisins à gauche if ( j > 0 ) v+= est_vivante(i-1,j-1,g); v+= est_vivante(i-1,j,g); if ( j < c-1) v+= est_vivante(i-1,j+1,g); } // voisins haut et bas if ( j > 0 ) v+= est_vivante(i,j-1,g); if ( j < c-1) v+= est_vivante(i,j+1,g); if (i < l-1 ) { // voisins à droite if ( j > 0 ) v+= est_vivante(i+1,j-1,g); v+= est_vivante(i+1,j,g); if ( j < c-1) v+= est_vivante(i+1,j+1,g); } return v; }
void evolue (grille *g, grille *gc){ copie_grille (*g,*gc); // copie temporaire de la grille int i,j,l=g->nbl, c = g->nbc,v; for (i=0; i<l; i++) { for (j=0; j<c; ++j) { v = compte_voisins_vivants (i, j, *gc); if (est_vivante(i,j,*g)) { // evolution d'une cellule vivante if ( v!=2 && v!= 3 ) set_morte(i,j,*g); } else { // evolution d'une cellule morte if ( v==3 ) set_vivante(i,j,*g); } } } return; }
void evolue (grille *g, grille *gc){ copie_grille (*g,*gc); // copie temporaire de la grille int i,j,l=g->nbl, c = g->nbc,v; for (i=0; i<l; i++) { for (j=0; j<c; ++j) { if (est_viable(i,j,*g)){ // TODO : encapsuler le code d'évolution dans ce test v = compte_voisins_vivants (i, j, *gc); if (est_vivante(i,j,*g)) { // evolution d'une cellule vivante if ( v!=2 && v!= 3 ) set_morte(i,j,*g); else set_continue_vie(i,j,*g); // a ajouter } else { // evolution d'une cellule morte if ( v==3 ) set_vivante(i,j,*g); } } } } return; }
void debut_jeu(grille *g, grille *gc){ char c = getchar(); while (c != 'q') // touche 'q' pour quitter { printf("\e[J"); switch (c) { case '\n' : { // touche "entree" pour évoluer evolue(g,gc); efface_grille(*g); affiche_grille(*g); break; } case 'c' : // touche pour changer de mode cyclique/non-cyclique { cyclique=abs(cyclique-1); compte_voisins_vivants=(cyclique==0) ? compte_cyclique : compte_non_cyclique; printf("\n\e[1A"); break; } case 'v' : // touche pour activer/désactiver le veillissement { viellissement=abs(viellissement-1); if (!viellissement) { //effacer les âges d'avant int i,j; for (i=0; i<g->nbl; i++) for (j=0;j<g->nbc; j++) if (est_vivante(i,j,*g)) set_vivante(i,j,*g); else set_morte(i,j,*g); } printf("\n\e[1A"); break; } case 'o' : // touche pour tester si la colonie est oscillante { int periode=0, failsafe=0; grille gtest,gmorte; //g doit rester inchangée alloue_grille (g->nbl, g->nbc, >est); alloue_grille (g->nbl, g->nbc, &gmorte); copie_grille(*g,gtest); do { periode++; failsafe++; evolue(>est,gc); } while (!( compare_grilles(gtest,*g) || compare_grilles(gtest,gmorte) ) && failsafe < MAX_TEST ); //soit on retombe sur la même configuration (-> oscillant) //soit toutes les cellules seront mortes à un moment (-> pas oscillant) if (compare_grilles(gtest,gmorte) || failsafe==MAX_TEST) printf("Pas oscillant."); else printf("Oscillant. Période: %d ",periode); libere_grille(>est); libere_grille(&gmorte); break; } default : { // touche non traitée printf("\n\e[1A"); break; } } c = getchar(); } return; }