mirror of
https://github.com/Fare-spec/cours.git
synced 2025-12-07 10:50:36 +00:00
152 lines
4.1 KiB
Python
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()
|