#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Nov  6 09:23:02 2025

@author: pjoulaud
"""

import random
import time

class Cellule:
    def __init__(self):
        self.actuel = False
        self.futur = False
        self.voisins = None
        
    def est_vivant(self):
        return self.actuel
    def set_voisins(self, cell_voisines):
        self.voisins = cell_voisines
    def get_voisins(self):
        return self.voisins
    def naitre(self):
        self.futur = True
    def mourir(self):
        self.futur = False
    def basculer(self):
        self.actuel = self.futur
    def __repr__(self):
        if self.actuel:
            return 'x'
        return '-'
    def __str__(self):
        return self.__repr__()
    def calcule_etat_futur(self):
        nb_voisines_vivantes = 0
        for cel in self.get_voisins():
            if cel.est_vivant():
                nb_voisines_vivantes = nb_voisines_vivantes + 1
        if nb_voisines_vivantes!=2 and nb_voisines_vivantes!=3:
            if self.est_vivant():
                self.mourir()
        elif nb_voisines_vivantes==3:
            if not self.est_vivant():
                self.naitre()
                # print("naissance")
                
class Grille :
    def __init__(self, haut=5, larg=10):
        self.largeur = larg
        self.hauteur = haut
        self.matrix = []
        for h in range(self.hauteur):
            self.matrix.append([])
            for l in range(self.largeur):
                self.matrix[h].append(Cellule())
    def dans_grille(self, i, j):
        if i<0 or i>=self.hauteur :
            return False
        if j<0 or j>=self.largeur:
            return False
        return True
    def setXY(self, x, y, obj):
        self.matrix[y][x]=obj
    def getXY(self, x, y):
        return self.matrix[y][x]
    def get_largeur(self):
        return self.largeur
    def get_hauteur(self):
        return self.hauteur
    def est_voisin(self, x, y, i, j):
        if abs(x-i)==1 and abs(y-j)<=1:
            return True
        elif abs(y-j)==1 and abs(x-i)<=1:
            return True
        elif  x==i and y==0 and j==self.hauteur-1:
            return True
        elif  x==i and y==self.hauteur-1 and j==0:
            return True
        elif  y==j and x==0 and i==self.largeur-1:
            return True
        elif  y==j and x==self.largeur-1 and i==0:
            return True
        return False
    def get_voisins(self, x,y):
        liste_voisins = []
        for h in range(self.hauteur):
            for l in range(self.largeur):
                if self.est_voisin(x, y, l, h):
                    liste_voisins.append(self.getXY(l, h))
        return liste_voisins
    def affecte_voisins(self):
        for h in range(self.hauteur):
            for l in range(self.largeur):
                self.getXY(l, h).set_voisins(self.get_voisins(l, h))
    def __repr__(self):
        aff = ""
        for h in range(self.hauteur):
            for l in range(self.largeur):
                aff += self.getXY(l, h).__repr__()
                aff +=' '
            aff += "\n"
        return aff
    def remplir_alea(self, pourcentage=50):
        for h in range(self.hauteur):
            for l in range(self.largeur):
                c = Cellule()
                if random.randint(0,100)>=pourcentage:
                    c.naitre()
                self.matrix[h][l] = c
    def jeu(self):
        for h in range(self.hauteur):
            for l in range(self.largeur):
                self.getXY(l, h).calcule_etat_futur()
    def actualise(self):
        for h in range(self.hauteur):
            for l in range(self.largeur):
                self.getXY(l, h).basculer()

def effacer_ecran():
    print("\u001B[H\u001B[J")
        
g = Grille(20,50)        
g.remplir_alea(50)
g.affecte_voisins()
g.actualise()
print(g)
for i in range(100):
    g.jeu()
    g.actualise()
    effacer_ecran()
    print(g)
    time.sleep(0.1)

        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        