Campo Minato

Transcript

Campo Minato
Campo Minato
in java
Il gioco
● campo rettangolare o quadrato suddiviso in
tanti quadratini
● Il giocatore deve “sminare” il campo,
cliccando sui quadratini, col tasto destro o
col tasto sinistro
●
il gioco
● cliccando su un quadratino:
a. se il quadratino su cui si clicca contiene una bomba
il gioco è finito
b. se il quadratino non contiene una bomba viene
mostrato il numero di bombe presente nei quadrati
vicini
■ se tutti i quadrati vicini non contengono bombe,
vengono scoperte tutte le caselle fino a quando
non si trovano caselle nelle cui immediate
vicinanze ci sia una bomba.
● è possibile segnare una possibile bomba col
il gioco - esempio
cliccando nella prima cella in
alto a sx, in questo caso si
“scoprono” le 3 celle sottostanti
e in modo recursivo tutte le
celle segnate di blu…
Implementazione
Si può partire da una matrice di interi..
ogni quadratino conterrà -1 se c’è la bomba,
oppure un numero compreso tra 0 e 8 (al
massimo può avere 8 bombe avendo 8
quadratini vicini).
int[][] quadrati = new int[NUM_COLONNE][NUM_RIGHE];
Attenzione che, se il campo è rettangolare, è diverso scrivere
int[][] quadrati = new int[NUM_RIGHE][NUM_COLONNE]
Implementazione
All’inizio ogni elemento della matrice è
composta di 0. (metodo inizializzaCampo() )
Successivamente si possono estrarre a sorte
un certo numero di bombe, per esempio un
10% delle celle (metodo posizionaBombe())
Individuo 2 coordinate casuali, se la cella non
contiene una bomba, setto il contenuto a -1 e
incremento il numero delle bombe inserite.
Implementazione
Una volta posizionate le bombe, bisogna che
ogni cella contenga il numero di bombe che si
trovano nelle otto celle adiacenti.
Può essere comodo avere un metodo
int getNumBombeVicine(int x, int y)
che riceve 2 parametri (le 2 coordinate della
tabella) e restituisce il numero tra 0 e 8.
Implementazione
Può essere utile adoperare due vettori che
contengono i valori per “guardare” attorno al
quadratino. I quadratini situati ai bordi avranno
meno vicini..
qudratino
(x-1,y-1)
qudratino
(x +0,y-1)
qudratino
(x+1,y-1)
qudratino
(x-1,y+0)
quadratino
(x,y)
qudratino
(x+1,y+0)
qudratino
(x-1,y+1)
qudratino
(x+0,y+1)
qudratino
(x+1,y+1)
Implemantazione
utilizzare un metodo stampaQuadratiConsole()
che produca un output sul terminale, per
comodità di visualizzazione utilizzare una X o
un asterisco al posto del valore -1
Implementazioni gui
Per l’interfaccia grafica possiamo creare una
classe che estenda JFrame che conterrà tutto il
campo da gioco. (FrameCampoMinato)
Possiamo utilizzare una classe che estende
JLabel per creare i singoli quadratini grafici.
(Cella)
Implementazione gui
FrameCampoMinato
sarà attivata dalla classe CampoMinato; nel
costruttore riceverà
numColonne, numRighe e la matrice di interi
la matrice di interi sarà “renderizzata” dalla
classe Cella che estende JLabel e implementa
l’interfaccia java.awt.event.MouseListerner
interfaccia gui
FrameCampoMinato
avrà un metodo pubblico (o almeno protetto)
Cella getCella(colonna, riga) che ritorna un
puntatore alla cella che si trova nella riga e
colonna specificata.
avrà anche un metodo void
giocoFinitoEsplosioneTotale() che farà
esplodere tutte le bombe
interfaccia gui
Altri metodi per FrameCampoMinato
boolean isGiocoTerminato()
guarda se tutte le celle tranne le bombe sono
scoperte.. e tutte le bombe segnate.
interfaccia gui
Cella
La classe cella estende JLabel.
Per ogni cella è utile sapere riga e colonna
(interi), se è girata o se è segnata (boolean).
Sarà utile mantenere un puntatore all’oggetto
che la contiene (l’oggetto che l’ha creata.. di
classe FrameCampoMinato)
E’ conveniente passare riga, colonna e frame
direttamente nel costruttore
interfaccia gui
Cella
Questa classe avrà al suo interno la logica del
gioco, in quanto implementerà l’interfaccia
MouseListener, responsabile dei classici
comportamenti del mouse (mouseOver,
mouseDown, ecc..)
class Cella extends JLabel implements MouseListeners {
public Cella(int c, int r, int v,
…
this.addMouseListener(this)
}
}
int obj ){
interfaccia gui
al click del mouse,
se premo tasto destro dovrò
segnalare/non segnalare una possibile bomba
(tramite il boolean segnata)
se premo tasto sinistro dovrò
scoprire il quadratino (boolean girata) e...
interfaccia gui - classe Cella
se il valore della cella è BOMBA
- ho finito il gioco (eventuale metodo
esplodiBomba della classe Cella) e chiamata al
metodo giocoFinitoEsplosioneTotale() dell’
oggetto contenitore..
se il valore della cella è compreso tra 0 e 8
- chiamo il metodo della classe Cella
void scopriCella()
interfaccia gui - classe Cella
il metodo scopriCella()
- segna la cella come girata
- guarda il valore della cella: se è compreso tra
1 e 8 semplicemente lo scrive
- se è 0 viene chiamato il metodo della classe
Cella scopriCellaRecursivo(riga, colonna)
interfaccia gui - classe Cella
scopriCellaRecursivo(riga, colonna)
- calcola le coordinate dei vicini..
notare che per sapere se sono valide abbiamo
bisogno di sapere (tramite metodi getter dell’
oggetto contenitore) il numero massimo di righe
e di colonne
inoltre mi interessano soltanto le celle che non
sono ancora state girate e non sono segnate!
interfaccia gui - classe Cella
scopriCellaRecursivo(riga, colonna)
la singola Cella non può accedere direttamente
alle altre celle, per questo dobbiamo utilizzare il
metodo getCella(colonna,riga) definito sull’
oggetto contenitore (FrameCampoMinato).
Se abbiamo un generico Object contenitore
possiamo utilizzare l’operatore di cast
(
(FrameCampoMinato) c).getCella(c,r)
interfaccia gui - classe Cella
Una volta individuate le celle, per ogni cella
che non contiene una bomba viene invocato il
metodo scopriCella() che, se trova altre celle
con 0, chiamerà nuovamente
scopriCellaRecursivo con nuove coordinate.
if (valoreVicino != CampoMinato.BOMBA) {
c.getCella(posX, posY).scopriCella();
}