#! /usr/bin/env python3 # TD8 p.92 # 2.8.5 démineur # imports ################################################################### import random # 1 création de la grille ################################################### def creerGrille(N, M, v=0): grille = [] for _ in range(N): ligne = [] for _ in range(M): ligne.append(v) grille.append(ligne) return grille def size(G): N = len(G) M = len(G[0]) return N, M # 2 placer les mines ######################################################## # version 1 avec vérification que la case tirée d'est pas prise def placerMines(G, X): N, M = size(G) for _ in range(X): while True: i = random.choice(range(N)) j = random.choice(range(M)) if G[i][j] != 1: G[i][j] = 1 break # version 2 en construisant la liste des place vides # et en piochant au hasard def placerMines(G, X): places = [] N, M = size(G) for i in range(N): for j in range(M): if G[i][j] == 0: place = (i, j) places.append(place) for _ in range(X): place = random.choice(places) places.remove(place) (i, j) = place G[i][j] = 1 # version 3 en construisant la liste des place vides # et en piochant à la fin de la pioche mélangée def placerMines(G, X): places = [] N, M = size(G) for i in range(N): for j in range(M): if G[i][j] == 0: place = (i, j) places.append(place) random.shuffle(places) for _ in range(X): place = places.pop() (i, j) = place G[i][j] = 1 # 3 affichage de solution ################################################### def afficheSolution(G): for ligne in G: l = "" for v in ligne: if v == 0: l += '-' else: l += '*' print(l) # 4 teste mine ############################################################## def testMine(G, i, j): if G[i][j] == 1: return True else: return False def testMine(G, i, j): return G[i][j] == 1 # 5 comptage des mines ###################################################### def compteMinesVoisines(G, i, j): c = 0 N, M = size(G) for u in [i-1, i, i+1]: for v in [j-1, j, j+1]: if (0 <= u < N) and (0 <= v < M): if testMine(G, u, v): c += 1 return c # 6 affichage ############################################################### def AfficheJeu(G, D): N, M = size(G) for i in range(N): l = '' for j in range(M): if D[i][j]: # dévoilée if testMine(G, i, j): l += ' * ' else: l += format(compteMinesVoisines(G, i, j), '^3') else: # masquée l += ' ? ' print(l) # 7 demande de coordonnées ################################################## def getCoords(D): N, M = size(D) while True: # demander une ligne i = -1 while not (0 <= i < N): i = int(input("ligne ? ")) # demander une colonne j = -1 while not (0 <= j < M): j = int(input("colonne ? ")) if D[i][j] == False: break else: print('case déjà devoilée') return i, j # 9 decouverte automatique ################################################## # version de base def decouvreCase(G, D, i, j): D[i][j] = True # version qui découvre tout ce qui peut l'être def decouvreCase(G, D, i, j): N, M = size(G) todo = [(i, j)] while todo != []: i, j = todo.pop() if D[i][j]: continue D[i][j] = True if compteMinesVoisines(G, i, j) != 0: continue for u in [i-1, i, i+1]: for v in [j-1, j, j+1]: if (0 <= u < N) and (0 <= v < M): todo.append((u, v)) # pour les curieux, version récursive def decouvreCase(G, D, i, j): N, M = size(G) if D[i][j]: return D[i][j] = True if compteMinesVoisines(G, i, j) != 0: return for u in [i-1, i, i+1]: for v in [j-1, j, j+1]: if (0 <= u < N) and (0 <= v < M): decouvreCase(G, D, u, v) # 8 programme principal ##################################################### def testVictoire(G, D): N, M = size(D) for i in range(N): for j in range(M): if D[i][j] == False and G[i][j] == 0: return False return True N, M = 5, 7 G = creerGrille(N, M) D = creerGrille(N, M, False) X = int(input("combien de mines ? ")) placerMines(G, X) c = 0 while True: print('coup', c) AfficheJeu(G, D) i, j = getCoords(D) decouvreCase(G, D, i, j) c += 1 # défaite if testMine(G, i, j): print('perdu !') AfficheJeu(G, D) print('solution') afficheSolution(G) break # victoire if testVictoire(G, D): print('tu as gagné en', c, 'coups, bravo !') AfficheJeu(G, D) break