from random import randint

class Demineur :
    def __init__(self, hauteur, largeur, pourcentage_mines):
        '''
        Pour un pourcentage de 15,6 on donnera au paramètre
        pourcentage_mines la valeur de 0.156.
        '''
        assert 0.1 <= pourcentage_mines <= 0.3, 'Le pourcentage de mines doit être compris entre 10% et 30%.'
        self.hauteur = hauteur
        self.largeur = largeur
        self.pourcentage_mines = pourcentage_mines
        self.grille_demineur = self.grille_demineur_vide()
        self.grille_visibilite = [[False for _ in range(self.largeur)] for _ in range(self.hauteur)]
    
    def grille_demineur_vide(self):
        return [[0 for _ in range(self.largeur)] for _ in range(self.hauteur)]
    
    def placer_mines(self):
        '''
        Cette fonction doit placer de façon aléatoire les mines dans la grille.
        Une mine sera représentée par le nombre -1.
        La méthode permet de mettre à jour l'attribut grille_demineur
        '''
        compteur_mines = 0 # Nombre de mines placées dans la grille.
        # nombre_bombes contient le nombre de mines à placer dans la grille.
        nombre_bombes = self.largeur * self.hauteur * self.pourcentage_mines
        while compteur_mines < nombre_bombes:
            ligne = randint(0, self.hauteur - 1)
            colonne = randint(0, self.largeur - 1)
            if self.grille_demineur[ligne][colonne] == 0:
                self.grille_demineur[ligne][colonne] = -1
                compteur_mines += 1
    
    def voisines(self, coordonnees_case):
        '''
        La méthode voisines renvoie les coordonnées des cases voisines de la case de la grille dont les coordonnées sont données par le tuple coordonnees_case passé en paramètre.
        Cette méthode renvoie une liste de tuple.
        >>> demineur_1 = Demineur(3, 5,0.20)
        >>> demineur_1.voisines((0, 0))
        [(1, 1), (1, 0), (0, 1)]
        >>> demineur_1.voisines((1, 2))
        [(0, 1), (0, 3), (0, 2), (2, 1), (2, 3), (2, 2), (1,
        1), (1, 3)]
        '''
        l = [-1, 0, 1]
        liste_voisines = []
        for i in l:
            for j in l:
                if (i, j) != (0, 0):
                    ligne_voisine = coordonnees_case[0] + i
                    colonne_voisine = coordonnees_case[1] + j
                    if 0 <= ligne_voisine < self.hauteur and 0 <= colonne_voisine < self.largeur:
                        liste_voisines.append((ligne_voisine, colonne_voisine))
        return liste_voisines
    
    def nombre_voisines_avec_mines(self, coordonnees_case):
        '''
        La méthode nombre_voisines_avec_mines renvoie le nombre de cases voisines contenant une mine à la case dont les coordonnées sont passés en paramètre(coordonnees_case) à la fonction.
        '''
        liste_voisines = self.voisines(coordonnees_case)
        nombre_mines = 0
        for case in liste_voisines:
            if self.grille_demineur[case[0]][case[1]] == -1:
                nombre_mines += 1
        return nombre_mines
    
    def generer_demineur(self):
        # Il faut penser à appeler la méthode placer_mines !
        self.placer_mines()
        for i in range(self.hauteur):
            for j in range(self.largeur):
                if self.grille_demineur[i][j] != -1:
                    self.grille_demineur[i][j] = self.nombre_voisines_avec_mines((i, j))

    def visibilite(self, coordonnees_case):
        if self.grille_demineur[coordonnees_case[0]][coordonnees_case[1]] == -1:
            for i in range(self.hauteur):
                for j in range(self.largeur):
                    self.grille_visibilite[i][j] = True
        elif self.grille_demineur[coordonnees_case[0]][coordonnees_case[1]] == 0:
            self.grille_visibilite[coordonnees_case[0]][coordonnees_case[1]] = True
            for case in self.voisines(coordonnees_case):
                if not self.grille_visibilite[case[0]][case[1]]:
                    self.visibilite(case)
        else:
            self.grille_visibilite[coordonnees_case[0]][coordonnees_case[1]] = True
        

demineur_intermediaire = Demineur(16, 16, 0.156)