/* next_generation(), implementée en utilisant la fonction "tout en un" câblée de compte, de mise à jour et d'affichage des voisines Sinon, semblable au Listing 17-3. */ /* Calcule la prochaine génération de current_map et la stocke dans next_map. */ void cellmap::next_generation(cellmap& next_map) { unsigned int x, y, neighbor_count; unsigned int width_in_bytesX2 = width_in_bytes << 1; unsigned char *cell_ptr, *current_cell_ptr, mask, current_mask; unsigned char *base_cell_ptr, *row_cell_ptr, base_mask; unsigned char *dest_cell_ptr = next_map.cells; // Traitement de toutes les cellules dans l'objet cellmap courant row_cell_ptr = cells; // pointe sur la cellule en haut à gauche // première cellule dans la carte de cellules for (y=0; y>= 1) == 0) { mask = 0x80; cell_ptr++; } // Mémorise l'emplacement de la cellule courante current_cell_ptr = cell_ptr + width_in_bytes; current_mask = mask; // Compte la voisine du dessus if ((*cell_ptr & mask)) neighbor_count++; // Compte la voisine du dessous if ((*(cell_ptr + width_in_bytesX2) & mask)) neighbor_count++; // Pointe sur la voisine en haut à droite if ((mask >>= 1) == 0) { mask = 0x80; cell_ptr++; } // Compte la voisine en haut à droite if ((*cell_ptr & mask)) neighbor_count++; // Compte la voisine de droite if ((*(cell_ptr + width_in_bytes) & mask)) neighbor_count++; // Compte la voisine en bas à droite if ((*(cell_ptr + width_in_bytesX2) & mask)) neighbor_count++; if (*current_cell_ptr & current_mask) { if ((neighbor_count != 2) && (neighbor_count != 3)) { *(dest_cell_ptr + (current_cell_ptr - cells)) &= ~current_mask; // désactive la cellule draw_pixel(x, y, OFF_COLOR); } } else { if (neighbor_count == 3) { *(dest_cell_ptr + (current_cell_ptr - cells)) |= current_mask; // active la cellule draw_pixel(x, y, ON_COLOR); } } // Passe à la prochaine cellule de la colonne if ((base_mask >>= 1) == 0) { base_mask = 0x80; base_cell_ptr++; // passe au prochain octet de la cellule } } row_cell_ptr += width_in_bytes; // pointe sur le début de la prochaine colonne } }