Files
cours/university/tp8/main.py
2025-11-21 13:54:08 +01:00

152 lines
4.1 KiB
Python

import board as bd
# 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)
# 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)
# 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):
"""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)
# 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
# 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():
"""
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)
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)
en_cours = False
else:
# 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
if __name__ == "__main__":
main()