# -*- coding: utf-8 -*-
#!/usr/bin/env python

import pygame
from random import shuffle

"""----------------------variables--------------------------"""
nbcellsx =  5 # nombre de cases horizontalement
nbcellsy =  4 # nombre de cases verticalement
# le produit nbcellsx*nbcellsy doit être paire !

cellsize = 40 # taille d'une carte

set_ = list("*+@=#&~€%$") # liste des symboles

orange = pygame.Color("darkorange") # couleur d'arrière plan
gris   = pygame.Color("grey20")     # couleur des chiffres
noir   = pygame.Color("black")      # couleur du dos des cartes
blanc  = pygame.Color("white")      # couleur de la face des carte

"""-------------------------constantes----------------------"""

"""-------------------------fonctions-----------------------"""
def play_again():
    # indique au joueur qu'il peut rejouer
    mess = police.render('cliquez pour rejouer',1,gris,orange)
    pygame.display.update(scr.blit(mess,mess.get_rect(center=scrrect.center)))
    while True:
        ev = pygame.event.wait()
        if ev.type   == pygame.MOUSEBUTTONDOWN: return True
        elif ev.type == pygame.QUIT: return False

def draw_hidden():
    # dessine et affiche les cartes faces cachées
    scr.fill(orange)
    for y in range(0,scrrect.h,cellsize):
        for x in range(0,scrrect.w,cellsize):
            scr.fill(noir,(x+1,y+1,cellsize-2,cellsize-2))
    pygame.display.flip()

def make_set():
    # construit et mélange la liste de cartes
    nb_cartes = (nbcellsx*nbcellsy)//2
    cartes = set_*int(nb_cartes//len(set_))
    cartes += set_[:nb_cartes%len(set_)]
    cartes *= 2
    shuffle(cartes)
    return cartes

"""-------------------------initialisation------------------"""
scr = pygame.display.set_mode((nbcellsx*cellsize,nbcellsy*cellsize))
scrrect = scr.get_rect()

pygame.font.init()
# détermine la taille de la police en fonction de la taille des cases
police = pygame.font.Font(None,int(cellsize//1.5))

firstcard = None # mémorise l'index de la 1ère carte retournée par tour

"""-------------------------corps---------------------------"""
while True:

    cartes = make_set()
    draw_hidden()

    # lance le chrono
    # toutes les 1000ms, l'événement USEREVENT est posé sur la file des events
    pygame.event.clear()
    pygame.time.set_timer(pygame.USEREVENT,1000)
    secondes = 0

    while any(cartes):
    # les paires trouvées sont misent à None dans cartes
    # donc, temps que cartes ne contient pas que des None
        ev = pygame.event.wait()
        if ev.type == pygame.QUIT: break # quitte le jeu
        elif ev.type == pygame.USEREVENT:
            # update le chrono
            secondes += 1
            pygame.display.set_caption(str(secondes))
        elif ev.type == pygame.MOUSEBUTTONDOWN:
            # la position de la souris est convertie en index dans cartes
            index = ev.pos[1]//cellsize*nbcellsx+ev.pos[0]//cellsize
            if cartes[index] and index!=firstcard: # si la carte n'est pas retournée ...
                # on la retourne en coloriant sa position
                # r mémorise l'emplacement sur l'écran
                r = scr.fill(blanc,(index%nbcellsx*cellsize+1,index//nbcellsx*cellsize+1,cellsize-2,cellsize-2))
                motif = police.render(str(cartes[index]),1,gris)
                # on affiche le symbole au centre
                scr.blit(motif,motif.get_rect(center=(r.center)))
                pygame.display.update(r)
                if firstcard is None: # si vrai alors c'est la première carte que l'on retourne dans ce tour
                    firstcard = index # mémorise la valeur
                    firstr = r # et l'emplacement
                    continue
                # sinon ...
                # si les 2 cartes sont identiques on les "dévoilent" dans cartes en mettant les valeurs à None
                if cartes[index] == cartes[firstcard]:
                    scr.fill(orange,r,special_flags=pygame.BLEND_MIN)
                    scr.fill(orange,firstr,special_flags=pygame.BLEND_MIN)
                    pygame.time.wait(500)
                    pygame.display.update((r,firstr))
                    cartes[index] = cartes[firstcard] = None
                else: # sinon ...
                    pygame.time.wait(500)
                    # on les re-cache en les coloriant
                    pygame.display.update((scr.fill(noir,r),scr.fill(noir,firstr)))
                firstcard = None
    else:
        pygame.time.wait(500)
        if play_again(): continue
    break

pygame.quit()