In questo semplice esercizio vogliamo riprodurre in Python, in modo un po’ rudimentale, quello che era il gioco del campo minato (poi campo fiorito) per Windows.
Quello che vogliamo ottenere assomiglierà a questo all’avvio:
Mentre alla vittoria otterremo qualcosa di simile:
Il gioco sarà costruito su una griglia 10×10, di 100 caselle in totale, che faremo selezionare all’utente con un numero da 1 a 100.
Anzitutto costruiamo la griglia fatta di oggetti di tipo Casella
, definiti nel modo seguente:
1 2 3 4 5 6 |
class Casella: def __init__(s, mina = False): s.mina = mina s.aperta = False s.conteggio = 0 |
Per costruire il campo useremo la funzione random.randint()
per distribuire le mine in modo casuale, nel modo seguente:
1 |
campo = [[Casella(True if random.randint(0,difficolta)==0 else False) for j in range(n)] for i in range(n)] |
In questo caso la variabile difficolta
viene usata per bilanciare la distribuzione casuale. Se impostiamo difficolta
su 2, avremo in media il 50% di caselle con mine (1/2). Se impostiamo difficolta
su 10 allora avremo circa il 10% di mine (1/10), ecc.
Fatto questo dobbiamo costruire due metodi che si occuperanno rispettivamente di conteggiare le mine e aprire le celle. All’interno di entrambi i metodi useremo due cicli for ricordandoci che rispetto alla posizione attuale quelle intorno partiranno da [-1,-1] fino a [1,1]
Riporto di seguito il codice, commentato, dell’intero giochino realizzato a partire da queste idee:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
import random class Casella: def __init__(s, mina = False): s.mina = mina s.aperta = False s.conteggio = 0 def conteggio(i,j): global n,campo # se nella cella non c'è una mina allora procedi if campo[i][j].mina == False: # controlliamo le celle tutto intorno for di in range(-1,2): for dj in range(-1,2): # se la posizione è compresa nell'intervallo della matrice if (i+di > -1 and j+dj > -1) and (i+di < n and j+dj < n): # se la cella è una mina if campo[i+di][j+dj].mina == True: # incrementiamo il contatore campo[i][j].conteggio += 1 # sfruttiamo il contatore per conteggiare il numero di mine nel gioco # se non abbiamo una mina restituiamo 0 return 0 else: #se abbiamo invece una mina restituiamo 1 return 1 def controlla(i,j): global n,campo # se la cella è aperta non facciamo altro #restituiamo True per dire che il gioco continua if campo[i][j].aperta: return True # impostiamo la cella come aperta campo[i][j].aperta = True # se non abbiamo una mina e il conteggio è a 0, allora procediamo # questo perché, cliccando su una cella, vogliamo aprire tutte le celle vuote #che non hanno alcuna mina accanto if campo[i][j].mina == False and campo[i][j].conteggio == 0: for di in range(-1,2): for dj in range(-1,2): if (i+di > -1 and j+dj > -1) and (i+di < n and j+dj < n): # se non abbiamo una mina e non siamo sulle celle diagonali # l'apertura avviene solo in orizzontale e verticale if not campo[i+di][j+dj].mina: controlla(i+di,j+dj) # altrimenti se abbiamo una mina, restituiamo False elif campo[i][j].mina: return False # in tutti gli altri casi True return True # difficoltà come probabilità di trovare mine, 1 / difficolta difficolta = 10 while True: # stampiamo il menu print("-- MENU --") print("1. gioca") print("2. imposta difficoltà") print("0. esci") s = int(input("> ")) # usciamo dal gioco if s == 0: break # giochiamo if s == 1: #dimensione del campo n = 10 # disegniamo il campo campo = [[Casella(True if random.randint(0,difficolta)==0 else False) for j in range(n)] for i in range(n)] # true = continua il gioco, false = si ferma risultato = True totale_mine = 0 # conteggiamo le mine rispetto alle caselle e le mine totali for i in range(n): for j in range(n): totale_mine += conteggio(i,j) # comincia l'inserimento while True: # numeri in cima print(end=" "*3) for i in range(n): print(i+1,end=" ") print() # conteggio chiuse ancora_chiuse = 0 for nr, r in enumerate(campo): # numeri accanto print(nr,end=" "*2) for c in r: # stampa a video if c.aperta: if c.mina: print("X",end=" ") elif c.conteggio > 0: print(c.conteggio,end=" ") else: print(" ",end=" ") else: if c.mina and not risultato: print("X",end=" ") else: print("-",end=" ") ancora_chiuse += 1 print() if not risultato: print("hai perso") break if ancora_chiuse <= totale_mine: print("hai vinto!") break # leggiamo l'input e trasformiamolo nella posizione i,j pos = int(input("posizione [1-%d]: " % (n**2))) i = int((pos-1)/n) j = pos - i*n - 1 # controlliamo la cella corrente risultato = controlla(i,j) if s == 2: # impostiamo la difficoltà d = int(input("seleziona difficoltà (1 = facile, 2 = medio, 3 = difficile): ")) if d == 1: difficolta = 10 if d == 2: difficolta = 6 if d == 3: difficolta = 4 |