import random as rd

#FONCTIONNALITE 1

def create_grid(taille):
    #la taille doit etre supérieure à 1
    grille = []
    ligne =[]
    for case in range(taille):
        ligne.append(' ') #on crée une ligne contenant le bon nombre de cases
    for nb_ligne in range (taille):
        grille.append(ligne.copy()) #permet de découpler les lignes
    return grille

def add_new_tile(grid):
    #la position indiqué doit etre cohérente avec les dimensions de la grille considérée
    value=choose_value_new_tile()
    (x,y)=get_new_position(grid)
    grid[x][y]=value
    #attention, la fonction modifie la liste passée en argument !
    return(grid)


def choose_value_new_tile():
    #choisi la valeur de la nouvelle case avec la probabilté indiquée dans l'énoncé
    value=rd.choice([2,2,2,2,2,2,2,2,2,4])
    return(value)

def get_all_tiles (grid):
    nb_ligne=len(grid)
    nb_colonne=len(grid[0]) #on suppose que la grille a au moins une ligne
    tiles=[]
    for ligne in range (nb_ligne):
        for colonne in range (nb_colonne):
            tile = grid[ligne][colonne]
            if tile == ' ':
                tiles.append(0)
            else :
                tiles.append(tile)
    return(tiles)

def get_empty_tile_position(grid):
    position_empty=[]
    for ligne in range (len(grid)):
        for colonne in range (len(grid[0])):
            if grid[ligne][colonne]==0 or grid[ligne][colonne]==' ' :
                position_empty.append((ligne,colonne))
    return(position_empty)

def get_new_position (grid):
    #choisi une postion au hasard parmis les position libre
    position_empty=get_empty_tile_position(grid)
    (x,y)=rd.choice(position_empty)
    return((x,y))

def grid_get_value(grid,x,y):
    if grid[x][y] == ' ':
        return (0)
    else :
        return(grid[x][y])

def init_game(taille):
    new_grid=create_grid(taille)
    (x1,y1)=get_new_position(new_grid) #choisi la première tuile qui va être un 2 ou un 4
    new_grid[x1][y1]=choose_value_new_tile()
    (x2,y2)=get_new_position(new_grid) #choisi la deuxièeme tuile
    new_grid[x2][y2]=choose_value_new_tile()
    return(new_grid)


#FONCTIONNALITE 2

def grid_to_string(grid):
    #je chosis de ne pas prendre l'argument "n" car cette information est déjà contenue dans la grid et elle me semble redondante
    #on suppose que la grille est carrée

    affichage=" "+"=== "*len(grid)+"\n"
    #crée la délimation du dessus

    for ligne in range (len(grid)):

        for colonne in range (len(grid[0])):
            #on suppose que la grille a au moins une ligne et qu'elles ont toutes la même taille
            affichage=affichage+"| "+str(grid[ligne][colonne])+" "
            #crée l'affichage de l'interieure des tuiles et de leur séparation

        affichage=affichage+"|\n" #fini la ligne
        affichage=affichage+" "+"=== "*len(grid)+"\n"#

    return (affichage)



def long_value (grid):
    all_tiles=get_all_tiles(grid)
    str_all_tiles=[] #création d'une liste de chaine de caractére prenant la valeur des tuiles
    long_str_tiles=[] #liste contenant les longueurs des tuiles
    for tile in range (len (all_tiles)):
        str_all_tiles.append(str(all_tiles[tile]))
    for string_tile in range (len(str_all_tiles)):
        long_str_tiles.append(len(str_all_tiles[string_tile]))
    return (max(long_str_tiles))

def grid_to_string_with_size(grid):
    longest=long_value(grid)

    nb_espace=longest+2 #donne le nombre d'espace necessaire dansla grille
    espaces = "="*nb_espace
    espaces=espaces+" "

    affichage=" "+espaces*len(grid)+"\n"
    #crée la délimation du dessus

    for ligne in range (len(grid)):

        for colonne in range (len(grid[0])):
            #on suppose que la grille a au moins une ligne et qu'elles ont toutes la même taille
            nb_espace_manquant=longest-len(str(grid[ligne][colonne]))-1
            affichage=affichage+"| "+str(grid[ligne][colonne])+" "*nb_espace_manquant

        affichage=affichage+"|\n" #fini la ligne
        affichage=" "+espaces*len(grid)+"\n"
    return(affichage)