import pyxel
import random

# Liste contenant toutes les lettres (chaque lettre représente une carte)
Lettre = ['A','B','C','D','E','A','B','C','D','E','F','F','G','G','H','H']


def Preparation_tableau(liste, taille):
    """
    Prépare le tableau du jeu.
    - Mélange des lettres afin de les placer aléatoirement.
    - Création d'une grille (tableau 2D) selon la taille demandée.
    """
    lettres_utilisees = random.sample(liste, taille * taille)  # Mélange et sélection des cartes en fonction de la taille de la grille
    tableau = []
    index = 0

    for i in range(taille):  # Parcourt chaque ligne
        ligne = []
        for j in range(taille):  # Parcourt chaque colonne
            ligne.append(lettres_utilisees[index])  # Ajoute une lettre dans la grille
            index += 1
        tableau.append(ligne)  # Ajoute la ligne complète dans le tableau final

    return tableau


# Définition de la taille du jeu (4x4)
taille = 4
board = Preparation_tableau(Lettre, taille)  # Génère la grille de jeu

# Tableau parallèle contenant l'état des cartes (True = visible, False = cachée)
reveler = [[False]*4 for _ in board]


def affichage(tab):
    """
    Affiche le tableau du jeu en fonction des cartes révélées.
    - Si une carte est révélée, on affiche la lettre.
    - Sinon, on affiche '?'.
    """
    global reveler
    print()
    print("   0  1  2  3")  # Indique les numéros des colonnes

    for i, ligne in enumerate(reveler):  # Pour chaque ligne du tableau révélateur
        print(i, end='  ')  # Affiche le numéro de la ligne
        for j, case_revelee in enumerate(ligne):  # Pour chaque colonne
            if case_revelee:  # Si la case est révélée (True)
                print(tab[i][j], end='  ')  # Affiche la lettre
            else:
                print('?', end='  ')  # Sinon laisse caché
        print()


def jeu(carte_1, carte_2):
    """
    Compare les deux cartes choisies.
    - Si elles sont identiques → paire trouvée.
    - Sinon → les cartes sont cachées à nouveau.
    """
    if carte_1 == carte_2:
        print("/// 🟢 C'est une paire ! Bravo ! ///")
    else:
        print("/// 🔴 Ce n'est pas une paire... ///")
        reveler[a1][b1] = False  # Cache la première carte
        reveler[a2][b2] = False  # Cache la deuxième carte


def toutes_trouvees():
    """
    Vérifie si le joueur a révélé toutes les cartes.
    Retourne True si aucune case n'est encore cachée.
    """
    for ligne in reveler:
        if False in ligne:  # Si une carte est encore cachée
            return False
    return True


# Première affichage du tableau avant toutes actions
affichage(board)


def client():
    """
    Boucle principale du jeu :
    - Le joueur choisit deux cartes (coordonnées).
    - Le programme révèle les cartes et compare.
    - La boucle continue jusqu'à réussite complète.
    """
    global a1, b1, a2, b2

    while not toutes_trouvees():  # Tant qu'il reste des cartes cachées
        a1 = int(input("Entre la 1ère ligne : "))
        b1 = int(input("Entre la 1ère colonne : "))
        reveler[a1][b1] = True  # Révèle la première carte
        affichage(board)

        a2 = int(input("Entre la 2e ligne : "))
        b2 = int(input("Entre la 2e colonne : "))
        reveler[a2][b2] = True  # Révèle la deuxième carte
        affichage(board)

        jeu(board[a1][b1], board[a2][b2])  # Comparaison et gestion

    print("🎉 Bravo ! Tu as trouvé toutes les paires !")


'''client()'''

# Liste de toutes les lettres utilisées pour les cartes du jeu
Lettre = ['A','B','C','D','E','A','B','C','D','E','F','F','G','G','H','H']
taille = 4  # Taille de la grille (4x4)

# Création du tableau principal avec les lettres mélangées
board = Preparation_tableau(Lettre, taille)
# Tableau parallèle pour savoir si une carte est révélée (True) ou cachée (False)
reveler = [[False]*4 for _ in board]
# Liste pour stocker les coordonnées des cartes sélectionnées par le joueur
selection = []
# Compteur de frames d'attente avant de retourner les cartes
wait_frames = 0

class App:
    def __init__(self):
        pyxel.init(170, 170, title="Memory Game")
        pyxel.mouse(True)
        pyxel.run(self.update, self.draw)

    def update(self):
        """
        Mise à jour logique du jeu à chaque frame.
        - Gère la fermeture avec la touche A.
        - Gère le temps d'attente avant de retourner les cartes.
        - Détecte le clic sur une carte et la révèle.
        """
        global selection, wait_frames

        # Quitter le jeu avec la touche A
        if pyxel.btnr(pyxel.KEY_A):
            pyxel.quit()

        # Gestion de l'attente après la sélection de deux cartes
        if wait_frames > 0:
            wait_frames -= 1
            if wait_frames == 0:
                # Récupère les deux cartes sélectionnées
                (a1, b1), (a2, b2) = selection
                # Si elles ne correspondent pas, on les cache à nouveau
                if board[a1][b1] != board[a2][b2]:
                    reveler[a1][b1] = False
                    reveler[a2][b2] = False
                # On vide la sélection pour la prochaine paire
                selection.clear()
            return

        # Détecte le clic gauche de la souris
        if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
            x = pyxel.mouse_x
            y = pyxel.mouse_y
            # Parcourt toutes les cases de la grille
            for i in range(taille):
                for j in range(taille):
                    rx = 10 + j * 40  # Position x de la case
                    ry = 10 + i * 40  # Position y de la case
                    # Vérifie si le clic est à l'intérieur de la case
                    if rx <= x <= rx + 30 and ry <= y <= ry + 30:
                        if not reveler[i][j]:  # Si la carte est cachée
                            reveler[i][j] = True  # Révèle la carte
                            selection.append((i, j))  # Stocke la sélection
                            if len(selection) == 2:  # Si deux cartes sont sélectionnées
                                wait_frames = 15  # Délai avant de retourner ou valider la paire

    def draw(self):
        """
        Dessine le tableau du jeu à chaque frame.
        - Cartes révélées : fond clair + lettre.
        - Cartes cachées : fond foncé + '?'.
        - Affiche message de victoire si toutes les cartes sont révélées.
        """
        pyxel.cls(13)  # Couleur de fond

        for i in range(taille):
            for j in range(taille):
                rx = 10 + j * 40
                ry = 10 + i * 40
                if reveler[i][j]:  # Carte révélée
                    pyxel.rect(rx, ry, 30, 30, 11)  # Dessine la case claire
                    pyxel.text(rx + 13, ry + 13, board[i][j], 7)  # Affiche la lettre
                else:  # Carte cachée
                    pyxel.rect(rx, ry, 30, 30, 5)  # Dessine la case foncée
                    pyxel.text(rx + 13, ry + 13, "?", 7)

        # Affiche le message de victoire si toutes les cartes sont trouvées
        if all(all(ligne) for ligne in reveler):
            pyxel.text(10, 82, "Bravo ! Tu as trouver toutes les paires !", 10)


# Lance le jeu
App()