import random as rd THEMES = {"0": {"name": "Default", 0: "", 2: "2", 4: "4", 8: "8", 16: "16", 32:"32", 64: "64", 128: "128", 256: "256", 512: "512", 1024: "1024", 2048: "2048",4096: "4096", 8192: "8192"}, "1": {"name": "Chemistry", 0: "", 2: "H", 4: "He", 8:"Li", 16: "Be", 32: "B", 64: "C", 128: "N", 256: "O", 512: "F", 1024: "Ne", 2048:"Na", 4096: "Mg", 8192: "Al"}, "2": {"name": "Alphabet", 0: "", 2: "A", 4: "B", 8:"C", 16: "D", 32: "E", 64: "F", 128: "G", 256: "H", 512: "I", 1024: "J", 2048: "K",4096: "L", 8192: "M"}} #FONCTIONNALITE 1 def create_grid(n): game_grid = [] for i in range(n): #crée le bon nombre de ligne game_grid.append([0]*n) #crée le bon nombre de colonnes return (game_grid) def get_value_new_tile(): #choisi la valeur de la nouvelle case avec la probabilté indiquée dans l'énoncé return rd.choice([2,2,2,2,2,2,2,2,2,4]) def get_all_tiles(grid): tiles = [] for line in grid: #parcours toutes les lignes for tile in line: #parcours toutes les colonnes if tile == ' ': tiles.append(0) #traite le cas particulier de la double notation 0 ou " " pour les emplacments vides else: tiles.append(tile) return tiles def get_empty_tiles_positions(grid): empty_tiles = [] nb_ligne = len(grid) nb_colonne = len(grid[0]) #on suppose que la grille a au moins une ligne #on suppose que toutes les lignes ont le même nombre de colonnes for i in range(nb_ligne): for j in range(nb_colonne): if grid[i][j] == ' ' or grid[i][j] == 0: #traite le cas particulier de la double notation 0 ou " " pour les emplacments vides empty_tiles.append((i,j)) return empty_tiles def get_new_position(grid): #choisi une postion au hasard parmis les position libre empty_tiles = get_empty_tiles_positions(grid) return (rd.choice(empty_tiles)) def grid_get_value(grid,x,y): if grid[x][y] == ' ': #traite le cas particulier de la double notation 0 ou " " return 0 return grid[x][y] def grid_add_new_tile(grid): x,y = get_new_position(grid) grid[x][y] = get_value_new_tile() #attention, la fonction modifie la liste passée en argument ! return grid def init_game(n = 4): grid = create_grid(n) for new_tile in range(2): grid = grid_add_new_tile(grid) return grid #FONCTIONNALITE 2 def grid_to_string_with_size_and_theme(grid, theme,n): longest_str = long_value_with_theme(grid,theme) affichage = "" for ligne in range(n): #création de la délimation du dessus affichage += (" " + "="*(longest_str+2))*n + "\n" #calcul du nombre nécéssaire d'espaces for colonne in range(n): affichage += "| {}".format(theme[grid[ligne][colonne]]) + " "*(1 + longest_str - len(theme[grid[ligne][colonne]])) affichage += "|\n" #fini la ligne #création de la dernière délimation du bas affichage += (" " + "="*(longest_str+2))*n return affichage def long_value_with_theme(grid,theme): return max(len(theme[v]) for v in get_all_tiles(grid)) # FONCTIONNALITE 4 def del_zeros(row): #fonction permettant de supprimer les zeros d'une ligne, et donne la taille de la liste initiale qui sont inutiles lors du processus de fusion des cases n = len(row) new_row = [] for i in range(n): if row[i] != 0: new_row.append(row[i]) return new_row, n def move_left_bis(row,i=0): #fonction aide pour la fonction recursive finale n = len(row) if i >= n-1: return row if row[i] == row[i+1]: row[i] = row[i]*2 for j in range(i+1,n-1): row[j] = row[j+1] row[n-1] = 0 return move_left_bis(row,i+1) def move_row_left(row): row,n = del_zeros(row) new_row = move_left_bis(row) return new_row + [0]*(n - len(new_row)) def move_row_right(row): #bouger à droite revient à bouger à gauche la liste lue dans le sens inverse return move_row_left(row[::-1])[::-1] def move_grid(grid,d): taille=len(grid) #cas droite et gauche plus simple car utilisation directe des fonctions codées ci dessus if d=="left": new_grid=[] for ligne in range (taille): row=grid[ligne] new_grid.append(move_row_left(row)) elif d=="right": new_grid=[] for ligne in range (taille): row=grid[ligne] new_grid.append(move_row_right(row)) #si on doit bouger en haut ou en bas celà revient à bouger la transposer à gauche ou à droite else: grid_t=transpose_grid(grid) #on s'interresse donc à la transposée new_grid_t=[] if d=="up": for ligne in range (taille): row=grid_t[ligne] new_grid_t.append(move_row_left(row)) else : #on ne peut bouger que en haut,bas,droite,gauche, pas besoin de elif donc par deduction for ligne in range (taille): row=grid_t[ligne] new_grid_t.append(move_row_right(row)) #on obtient la transposée de la grille finale new_grid=transpose_grid(new_grid_t) #permet de retoruver la grille "dans le bon sens" return(new_grid) def transpose_grid (liste): #fonction permettant de transposer une liste de liste que l'on identifie à sa matrice #cette fonction ne marche que sur des matrice carrée n=len(liste) transpo_liste=[] for colonne in range (n) : ligne_transpo=[] #création des lignes de la transposée for ligne in range (n) : ligne_transpo.append(liste[ligne][colonne]) transpo_liste.append(ligne_transpo) #renvoie une liste return(transpo_liste) # FONCTIONNALITE 5 def is_grid_full(grid): return get_empty_tiles_positions(grid) == [] def move_possible(grid): #renvoie une liste de 4 booléens indiquant si le déplacement à gauche,droite,haut,bas est possible. possibles = [] for d in ["left","right","up","down"]: possibles.append(move_grid(grid,d) != grid) #si le deplacement n'est pas possible, la grille reste inchangée apres avoir effectué ce déplacement return possibles def is_game_over(grid): #on a perdu si la grille est pleine et que aucun mouvement n'est possible return is_grid_full(grid) and True not in move_possible(grid) def get_grid_tile_max(grid): return max(get_all_tiles(grid)) def did_you_win (grid): return (get_grid_tile_max(grid)>=2048) #Fonctinnalité 6 def list_move_possible (grid): #renvoie la liste des deplacements possibles list_bool=move_possible(grid) list_final=[] if list_bool[0]: list_final.append("left") if list_bool[1]: list_final.append("right") if list_bool[2]: list_final.append("up") if list_bool[3]: list_final.append("down") return(list_final) def random_play(): #on suppose que le jeu par defaut comprend une grille de 4x4 #phase d'initialisation du jeu grid_game=init_game(4) print(grid_to_string_with_size_and_theme(grid_game,THEMES["0"],4)) #phase de jeu while not is_game_over(grid_game): #pour chaque tour d=rd.choice(list_move_possible(grid_game)) #on choisi un mouvement grid_game=move_grid(grid_game,d) #on le fait grid_game=grid_add_new_tile(grid_game) #une tuile se crée print(grid_to_string_with_size_and_theme(grid_game,THEMES["0"],4)) #on affuche le résulat print("\n***********************************\n") #permet aux différentes grilles d'être plus lisible #vérification si le jeu est gagnant ou perdant if did_you_win(grid_game): print("CONGRATS ! YOU WON !!!") else : print ("YOU FAIL, TRY AGAIN") return()