From 6a4934969ba72f5da5fec175d835e6bf39e99e88 Mon Sep 17 00:00:00 2001 From: Spectre Date: Fri, 21 Nov 2025 13:54:08 +0100 Subject: [PATCH] Finished the homework --- university/tp8/drawer.py | 46 ------------ university/tp8/main.py | 155 +++++++++++++++++++++++++++++---------- 2 files changed, 117 insertions(+), 84 deletions(-) delete mode 100644 university/tp8/drawer.py diff --git a/university/tp8/drawer.py b/university/tp8/drawer.py deleted file mode 100644 index ca9538b..0000000 --- a/university/tp8/drawer.py +++ /dev/null @@ -1,46 +0,0 @@ -import time as tm -import turtle as tl - -import board as bd - -screen = tl.Screen() -screen.setup(width=800, height=600) -screen.tracer(0, 0) - - -def draw_board(board: bd.Grid): - tl.clear() # instead of resetscreen() - tl.hideturtle() - tl.penup() - - if not board: - screen.update() - return - - cell_size = 60 - - rows = len(board) - cols = max(len(line) for line in board) - - origin_x = -cols * cell_size / 2 - origin_y = rows * cell_size / 2 - - for i, line in enumerate(board): - for j, cell in enumerate(line): - x = origin_x + j * cell_size - y = origin_y - i * cell_size - - tl.goto(x, y) - tl.pendown() - for _ in range(4): - tl.forward(cell_size) - tl.right(90) - tl.penup() - - tl.goto(x + cell_size / 2, y - 0.8 * cell_size) - tl.write( - cell, align="center", font=("Courier", int(cell_size / 2), "normal") - ) - - screen.update() - tm.sleep(100) diff --git a/university/tp8/main.py b/university/tp8/main.py index e7625e3..f26dd49 100644 --- a/university/tp8/main.py +++ b/university/tp8/main.py @@ -1,72 +1,151 @@ import board as bd -import drawer as dw +# 4.8.1.1 : création de la grille def creerGrille(N, M, v=0): + """Crée une grille N x M initialisée à la valeur v.""" return bd.gen_grid(N, M, v) -def placerMine(grid, X): +# 4.8.1.2 : placement des mines +def placerMines(grid, X): + """Place X mines (valeur 1) dans la grille à des positions aléatoires.""" bd.place_mine(grid, X) -def TestMine(grid, i, j): +# 4.8.2.1 : test d'une mine +def testMine(grid, i, j): + """Renvoie True s'il y a une mine à la case (i, j).""" return bd.test_mine(grid, (i, j)) +# 4.8.2.2 : compte des mines voisines def compteMinesVoisines(positionsMines, i, j): - return bd.get_neighbours((i, j), positionsMines) + """Renvoie le nombre de mines voisines de la case (i, j).""" + return bd.count_near_mines(positionsMines, (i, j)) +# 4.8.3.1 : affichage de la solution def afficheSolution(positionsMines): + """Affiche la grille solution : '-' pour vide, '*' pour mine.""" bd.display_mines(positionsMines) +# 4.8.3.2 : affichage du jeu def afficheJeu(positionsMines, casesDevoilees): + """ + Affiche la grille telle que vue par le joueur : + '?' pour inconnue, '*' pour mine découverte, + nombre de mines voisines autrement. + """ bd.display_known(positionsMines, casesDevoilees) -def getCoords(known_grid, N, M): - return bd.get_coords(known_grid) +# 4.8.4.1 : lecture filtrée du nombre de mines +def getNbMines(N, M): + """ + Lit et renvoie un nombre de mines X tel que 1 <= X <= N*M - 1. + Évite le cas où le placement serait impossible. + """ + max_mines = N * M - 1 + nb = 0 + while not (1 <= nb <= max_mines): + try: + nb = int(input(f"Nombre de mines (entre 1 et {max_mines}) ? ")) + except ValueError: + nb = 0 + return nb -def main2(): - grid = creerGrille(8, 8) - placerMine(grid, 10) - dw.draw_board(grid) +# 4.8.4.2 : lecture filtrée des coordonnées +def getCoords(casesDevoilees, N, M): + """ + Demande à l'utilisateur des coordonnées (ligne, colonne) : + - dans les bornes, + - sur une case non encore dévoilée. + Ne redemande que la coordonnée incorrecte. + Renvoie (i, j) correctes. + """ + max_i = N - 1 + max_j = M - 1 + + i = -1 + j = -1 + + while True: + # Lecture de la ligne + while not (0 <= i <= max_i): + try: + if i == -1: + i = int(input("Ligne? ")) + else: + i = int(input(f"Ligne < {N} svp ? ")) + except ValueError: + i = -1 + + while not (0 <= j <= max_j): + try: + if j == -1: + j = int(input("Colonne? ")) + else: + j = int(input(f"Colonne < {M} svp ? ")) + except ValueError: + j = -1 + + if not casesDevoilees[i][j]: + return i, j + + print("Case deja devoilee, recommence") + i = -1 + j = -1 -def main() -> None: +def main(): + """ + Programme principal : + - initialise une grille, + - demande le nombre de mines, + - lance la boucle de jeu, + - s'arrête quand le joueur perd ou gagne. + """ N, M = 8, 8 grid = creerGrille(N, M) - mines_number = 0 - while not (0 < mines_number <= N * M - 1): - mines_number = int( - input(f"Please input a number of mines between 0-{N * M - 1}: ") - ) - # In theory we should put the line below after the first pick on the board or else the user could loose on their first attempt - placerMine(grid, mines_number) - known_grid = [[False for _ in range(N)] for _ in range(M)] - going = True - while going: - afficheJeu(grid, known_grid) - y, x = getCoords(known_grid, N, M) - known_grid[y][x] = True - # If the user lost: - if TestMine(grid, y, x): - print("You lost") - afficheJeu(grid, known_grid) - print("Here is the solution: ") + nb_mines = getNbMines(N, M) + placerMines(grid, nb_mines) + + # Grille des cases dévoilées : N lignes, M colonnes + casesDevoilees = [[False for _ in range(M)] for _ in range(N)] + + nb_coups = 0 + en_cours = True + + while en_cours: + nb_coups += 1 + print(f"Coup numero {nb_coups}") + afficheJeu(grid, casesDevoilees) + print("A toi de jouer !") + + i, j = getCoords(casesDevoilees, N, M) + casesDevoilees[i][j] = True + + # Mine touchée -> perdu + if testMine(grid, i, j): + print("Perdu, touche une mine !") + afficheJeu(grid, casesDevoilees) + print("La solution etait :") afficheSolution(grid) - going = False - # If he won - elif bd.is_end(known_grid, grid): - print("Congrats ! You've just won") - going = False + en_cours = False else: - linked = bd.linked_cells(grid, known_grid, (y, x)) - for coord in linked: - known_grid[coord[1]][coord[0]] = True + # Expansion façon démineur (bonus, pas demandé mais utile) + linked = bd.linked_cells(grid, casesDevoilees, (i, j)) + for cy, cx in linked: + casesDevoilees[cy][cx] = True + # Fin de partie + if bd.is_end(casesDevoilees, grid): + afficheJeu(grid, casesDevoilees) + print(f"Tu as gagne en {nb_coups} coups, bravo !") + en_cours = False -main2() +if __name__ == "__main__": + main()