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(); }