Requisiti generali Lo svolgimento del progetto deve tenere in considerazione i seguenti requisiti:
- Le classi del modello (non le viste, né i controller) devono essere corredate da classi di test;
- La documentazione deve essere prodotta con javadoc;
- Per quanto riguarda l'interfaccia utente (che deve essere separata dalle classi che realizzano la logica del sistema) è solo necessario che permetta di accedere alle funzionalità del sistema.
Per giocare a battaglia navale occorrono quattro tabelle (due per giocatore), tutte di uguali dimensioni (per esempio 10×10 o un'altra dimensione concordata dai giocatori). I quadretti della tabella sono identificati da coppie di coordinate, corrispondenti a riga e colonna; tradizionalmente si usano lettere per le colonne e numeri per le righe (perciò le celle sono "A-1", "B-6", e così via). Nota: in questo laboratorio, per semplicità, useremo interi sia per le righe che per le colonne (quindi [0,0], [0,1], …). All'inizio, i giocatori devono "posizionare le proprie navi" segnandole su una delle loro due griglie (che terranno nascoste all'avversario per tutta la durata del gioco). Una "nave" occupa un certo numero di quadretti adiacenti in linea retta (orizzontale o verticale) sulla tabella. Due navi non possono toccarsi. I giocatori si accordano preliminarmente su quante navi disporre e di quali dimensioni. Si può notare che molti giocatori utilizzano (anche non sempre in modo consistente) una particolare terminologia per riferirsi alle navi delle varie dimensioni; per esempio un sottomarino è di solito una nave di dimensione 3, insieme all'incrociatore, un cacciatorpediniere è di dimensione 2 e le navi di lunghezza superiore sono corazzate (dimensione 4) e portaerei (dimensione 5). Una volta posizionate le navi, il gioco procede a turni. Il giocatore di turno "spara un colpo" dichiarando un quadretto (per esempio, "B-5"). L'avversario controlla sulla propria griglia se quella cella è occupata da una sua nave. In caso affermativo risponde "colpito!", e marca quel quadretto sulla propria tabella; in caso negativo risponde "acqua" o "mancato". Sulla seconda tabella in dotazione i giocatori prendono nota dei colpi che hanno sparato e del loro esito. Quando un colpo centra l'ultimo quadretto di una nave non ancora affondata, il giocatore che subisce il colpo dovrà dichiarare "colpito e affondato!", e la nave si considera persa. Vince il giocatore che per primo affonda tutte le navi dell'avversario.
Per la parte di laboratorio (Java) è richiesto di implementare una versione di battaglia navale nella quale l’utente umano “sfida” il computer. Potete aggiungere funzionalità a piacimento (senza esagerare), ma le seguenti sono richieste:
- INTERFACCIA: tutti devono implementare una GUI che permetta all’utente umano di visualizzare le sue due mappe (nella sezione dei consigli c’è una descrizione di come potrebbero essere). Per chi decide di implementare la versione semplice, l’interazione con l’utente (es. quale azione fare successivamente) può essere fatta da terminale (con un menu come quello che avete usato per Rubrica), per chi decide di fare la parte OPZ, tutta l’interazione con l’utente deve essere fatta tramite GUI. Ad esempio, potete usare delle JTextField per chiedere le coordinate, o rendere “cliccabili” le caselle della mappa tramite gli eventi del mouse.
Dopo aver iniziato una nuova partita, l’utente deve poter posizionare tutte le sue navi. Per posizionale, deve scegliere la casella “di testa” (es. [3,5]) e l’orientamento (VERTICALE o ORIZZONTALE). La disposizione della nave avviene dalla casella di testa, dall’alto verso il basso o da sinistra verso destra. Il sistema deve verificare che i posizionamenti siano leciti, e comunicare all’utente eventuali errori.
- AVVERSARIO: Il sistema fa da avversario (lo chiameremo CPU). CPU posiziona i suoi pezzi in maniera casuale, dopo che lo ha fatto l’utente.
- PARTITA: Dopo i posizionamenti, inizia la partita, che funziona a turni. Ad ogni turno, l’utente sceglie una casella ed il sistema verifica se ha colpito/affondato o no una nave avversaria (comunicandolo all’utente) e poi la stessa cosa succede per CPU. Nella versione base, CPU sceglie una casella casuale che non ha ancora scelto2. Se decidete di implementare le funzionalità opzionali (OPZ), oltre alla versione base, deve esserci una versione “intelligente” di CPU. Lascio a voi eventuali “strategie evolute”, non necessarie, ma almeno una volta colpita una nave, deve colpire caselle adiacenti finché non la ha affondata. CONSIGLIO: dato che sia l’utente che CPU ad ogni turno devono scegliere una mossa, vi conviene implementare il tutto con un metodo (es. getProssimaMossa), che sarà implementato in maniera diversa per CPU e per l’utente.
- TERMINE PARTITA: Dopo ogni turno, il sistema controlla se tutte le navi di un giocatore sono state affondate. In caso positivo, decreta il vincitore. Per chi decide di fare la parte opzionale (OPZ), c’è un’altra condizione di terminazione della partita. Il giocatore umano inizia la partita con un certo tempo a disposizione (decidete voi se far iniziare il timer con un tempo richiesto all’utente, o dipendente dalla dimensione delle tabelle). Il tempo è decrementato mentre l’utente sta effettuando la scelta su quale casella dell’avversario colpire. Se il timer arriva a 0, l’utente umano ha perso. Classi (obbligatorie) Tutte le classi usate per questo progetto, esclusa eventualmente una classe con il main che vi permette di eseguirlo, devono essere contenute in un package chiamato upo.battleship.cognome (cognome è il cognome di un componente del gruppo, tutto minuscolo). È richiesto che la loro architettura rispecchi il modello MVC, e devono esserci almeno le seguenti classi: • BattleshipModel • BattleshipView • BattleshipController