from davistk import *
import random
from time import sleep
from doctest import testmod

# Constantes
LARGEUR = 800
HAUTEUR = 600
TAILLE_FROG = 20
LARGEUR_VOITURE = 40
VITESSE_VOITURE = 5

# Variables globales

def ordonnee_voie(num_voie):
    """ Ne pas modifier
    Calcule l'ordonnée d'une voie en fonction de son numéro.
    Args:
        num_voie (int): Le numéro de la voie.
    Returns:
        float: L'ordonnée de la voie.

    >>> ordonnee_voie(0)
    20.0
    >>> ordonnee_voie(1)
    100.0
    """
    return num_voie * 2 * HAUTEUR // 3 / 5 + LARGEUR_VOITURE // 2

def init_frog():
    """ Ne pas modifier
    Initialise la grenouille à sa position de départ.
    Returns:
        tuple: Les coordonnées x, y de la grenouille.

    >>> init_frog()
    (400, 580)
    """
    return LARGEUR // 2, HAUTEUR - TAILLE_FROG

def init_voiture(bordure):
    """ Ne pas modifier
    Initialise une voiture avec une position aléatoire ou à la bordure.
    Args:
        bordure (bool): Si True, initialise la voiture à la bordure gauche.
    Returns:
        tuple: Les coordonnées x, y et la longueur de la voiture.

    >>> from random import seed; seed(0)
    >>> init_voiture(True)
    (0, 260.0, 80)
    >>> init_voiture(False)
    (41, 180.0, 120)
    """
    if bordure:
        x = 0
    else:
        x = random.randint(0, LARGEUR - LARGEUR_VOITURE)
    y = ordonnee_voie(random.randint(0, 4))
    longueur_voiture = random.randint(1, 3) * LARGEUR_VOITURE
    return x, y, longueur_voiture

def init_voitures():
    """ Ne pas modifier
    Initialise un ensemble de voitures.
    Returns:
        tuple: Un tuple contenant les voitures initialisées.
    
    >>> from random import seed; seed(0)
    >>> init_voitures()
    ((394, 260.0, 40), (414, 180.0, 80), (265, 340.0, 80), (366, 340.0, 40), (516, 100.0, 80))
    """
    voiture1 = init_voiture(False)
    voiture3 = init_voiture(False)
    voiture2 = init_voiture(False)
    voiture4 = init_voiture(False)
    voiture5 = init_voiture(False)
    return voiture1, voiture2, voiture3, voiture4, voiture5

def dessine_frog(frog):
    """ Ne pas modifier
    Dessine la grenouille à l'écran.
    Args:
        frog (tuple): Les coordonnées x, y de la grenouille.
    """
    frog_x, frog_y = frog
    rectangle(frog_x - TAILLE_FROG // 2, frog_y - TAILLE_FROG // 2,
                frog_x + TAILLE_FROG // 2, frog_y + TAILLE_FROG // 2,
                couleur='green', remplissage='green')

def dessine_voiture(voiture):
    """ Ne pas modifier
    Dessine une voiture à l'écran.
    Args:
        voiture (tuple): Les coordonnées x, y et la longueur de la voiture.
    """
    x, y, longueur_voiture = voiture
    rectangle(x, y, x + longueur_voiture, y + LARGEUR_VOITURE,
                    couleur='red', remplissage='red')
    
def dessine_voitures(voitures):
    """ Ne pas modifier
    Dessine un ensemble de voitures à l'écran.
    Args:
        voitures (tuple): Un tuple contenant les voitures à dessiner.
    """
    voiture1, voiture2, voiture3, voiture4, voiture5 = voitures
    dessine_voiture(voiture1)
    dessine_voiture(voiture2)
    dessine_voiture(voiture3)
    dessine_voiture(voiture4)
    dessine_voiture(voiture5)

def dessine_routes():
    """ Ne pas modifier
    Dessine les routes à l'écran.
    """
    for i in range(5):
        y = ordonnee_voie(i) + LARGEUR_VOITURE + LARGEUR_VOITURE // 2
        ligne(0, y, LARGEUR, y, couleur='black')

def touche_bordure(voiture):
    """
    Vérifie si une voiture touche la bordure de l'écran.
    Args:
        voiture (tuple): Les coordonnées x, y et la longueur de la voiture.
    Returns:
        bool: True si la voiture touche la bordure, sinon False.

    >>> touche_bordure((0, 240, 80))
    False
    >>> touche_bordure((900, 240, 80))
    True
    >>> touche_bordure((400, 240, 80))
    False
    """
    x, y, longueur_voiture = voiture # récupère les coordonnées x, y et la longueur de la voiture
    # A modifier
    return False

def deplace_voiture(voiture):
    """
    Déplace une voiture et réinitialise sa position si elle touche la bordure.
    Utilise la fonction touche_bordure et init_voiture.

    Args:
        voiture (tuple): Les coordonnées x, y et la longueur de la voiture.
    Returns:
        tuple: Les nouvelles coordonnées x, y et la longueur de la voiture.

    >>> deplace_voiture((0, 240, 80))
    (5, 240, 80)
    >>> deplace_voiture((400, 240, 80))
    (405, 240, 80)
    """
    x, y, longueur_voiture = voiture
    x += 0 # A modifier
    # A modifier
    return x, y, longueur_voiture

def deplace_voitures(voitures):
    """ Ne pas modifier
    Déplace un ensemble de voitures.
    Args:
        voitures (tuple): Un tuple contenant les voitures à déplacer.
    Returns:
        tuple: Un tuple contenant les nouvelles positions des voitures.

    """
    voiture1, voiture2, voiture3, voiture4, voiture5 = voitures
    voiture1 = deplace_voiture(voiture1)
    voiture2 = deplace_voiture(voiture2)
    voiture3 = deplace_voiture(voiture3)
    voiture4 = deplace_voiture(voiture4)
    voiture5 = deplace_voiture(voiture5)
    return voiture1, voiture2, voiture3, voiture4, voiture5

def collision(voiture, frog):
    """ Ne pas modifier
    Vérifie s'il y a une collision entre une voiture et la grenouille.
    Args:
        voiture (tuple): Les coordonnées x, y et la longueur de la voiture.
        frog (tuple): Les coordonnées x, y de la grenouille.
    Returns:
        bool: True s'il y a une collision, sinon False.

    >>> collision((0, 240, 80), (400, 240))
    False
    >>> collision((400, 240, 80), (400, 240))
    True
    """
    x, y, longueur_voiture = voiture
    frog_x, frog_y = frog
    if (x < frog_x  - TAILLE_FROG // 2 < x + longueur_voiture or x < frog_x + TAILLE_FROG // 2 < x + longueur_voiture) and \
        (y < frog_y - TAILLE_FROG // 2 < y + LARGEUR_VOITURE or y < frog_y + TAILLE_FROG // 2 < y + LARGEUR_VOITURE):
        return True
    return False

def collisions(voitures, frog):
    """ Ne pas modifier
    Vérifie s'il y a une collision entre la grenouille et un ensemble de voitures.
    Args:
        voitures (tuple): Un tuple contenant les voitures.
        frog (tuple): Les coordonnées x, y de la grenouille.
    Returns:
        bool: True s'il y a une collision, sinon False.
    """
    voiture1, voiture2, voiture3, voiture4, voiture5 = voitures
    if collision(voiture1, frog) or collision(voiture2, frog) or collision(voiture3, frog) or collision(voiture4, frog) or collision(voiture5, frog):
        return True
    return False

def mise_a_jour_frog(direction, frog):
    """
    Met à jour la position de la grenouille en fonction de la direction.
    Si la grenouille est arrivé en haut, elle revient à sa position de départ.
    Args:
        direction (str): La direction de déplacement de la grenouille.
        frog (tuple): Les coordonnées x, y de la grenouille.
    Returns:
        tuple: Les nouvelles coordonnées x, y de la grenouille.
    
    >>> mise_a_jour_frog('Up', (400, 240))
    (400, 220)
    >>> mise_a_jour_frog('Down', (400, 240))
    (400, 260)
    >>> mise_a_jour_frog('Left', (400, 240))
    (380, 240)
    >>> mise_a_jour_frog('Right', (400, 240))
    (420, 240)
    >>> mise_a_jour_frog('Up', (400, 20))
    (400, 580)
    """
    frog_x, frog_y = frog
    # A modifier
    return frog_x, frog_y

def nouveau_depart(frog):
    """
    Vérifie si la grenouille est revenue à sa position de départ.
    Args:
        frog (tuple): Les coordonnées x, y de la grenouille.
    Returns:
        bool: True si la grenouille est à sa position de départ, sinon False.
    
    >>> nouveau_depart((400, 240))
    False
    >>> nouveau_depart((400, 580))
    True
    """
    frog_x, frog_y = frog
    # A modifier
    return False

def affiche_defaite():
    """
    Affiche un message de défaite.
    """
    ... # A modifier

if __name__ == "__main__":
    framerate = 20
    score = 0
    cree_fenetre(LARGEUR, HAUTEUR)
    frog = init_frog() # position de départ de la grenouille
    voitures = init_voitures() # positions de départ des voitures
    jouer = True 
    while jouer:
        efface_tout() # efface tous les objets
        dessine_routes() # dessine les routes
        dessine_frog(frog) # dessine la grenouille
        dessine_voitures(voitures) # dessine les voitures
        mise_a_jour() # met à jour l'affichage
        voitures = deplace_voitures(voitures) # déplace les voitures
        jouer = not collisions(voitures, frog) # vérifie s'il y a une collision
        ev = donne_ev() # récupère un événement
        ty = type_ev(ev) # récupère le type de l'événement
        if ty == 'Quitte': # vérifie si l'événement est de type Quitte
            break # sort de la boucle
        elif ty == 'Touche': # vérifie si l'événement est de type Touche
            frog = mise_a_jour_frog(touche(ev), frog) # met à jour la position de la grenouille
            if nouveau_depart(frog): # vérifie si la grenouille est revenue à sa position de départ
                ...
        attente(1/framerate) # attente avant rafraîchissement

    affiche_defaite()
    mise_a_jour()
    attente(2)
    ferme_fenetre()
