Progetto 2019/20

Questa pagina descrive il progetto per il corso di Informatica della Laurea in Matematica per gli appelli dell'anno accademico 2019/2020.

Problema: verificare una sequenza di mosse negli scacchi

Si consideri una arbitraria scacchiera di dimensioni N x M dove N e M sono naturali positivi. Nella scacchiera è presente un singolo pezzo non pedone degli scacchi (quindi una torre, cavallo, alfiere, donna o re). Tale singolo pezzo è inizialmente collocato in una casella arbitraria p1. Da questa posizione, il pezzo compie una sequenza di K mosse secondo le normali regole degli scacchi, attraversando così le caselle p1,p2,...,pK,p(K+1), tutte distinte (il pezzo non ritorna mai su una casella attraversata in passato). Si ha K>=0, dove il caso degenere K=0 rappresenta la sequenza di zero mosse in cui il pezzo non si muove dalla posizione iniziale p1.

Questa sequenza di mosse può essere rappresentata con una matrice N x M definita come segue. Nella cella di posizione pj è presente il numero j (con 1<=j<=K+1). Nelle altre celle la cui posizione non è stata mai attraversata dal pezzo, si trova il numero zero.

Per esempio, questa matrice rappresenta una sequenza di nove mosse di una torre.

0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
9 0 0 1 0 0 0 0 0 2 0 0 0
0 0 0 0 5 0 0 0 0 0 6 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0 0 7 0 0
0 0 0 0 4 0 0 0 0 3 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0

Ovviamente, non tutte le matrici intere rappresentano sequenze di mosse. Chiamiamo quelle che lo fanno "matrici di mosse" (per un dato pezzo).

Il progetto consiste nello scrivere una funzione Java che, dato un pezzo e una matrice intera arbitraria, verifichi se la matrice è una matrice di mosse per il pezzo in questione.

Alcune precisazioni:

Implementazione in Java

Si chiede di scrivere una funzione Java avente (esattamente) nome e tipo come segue:

public static boolean testChessMoves(String fileName)

Il parametro indica il nome del file da aprire, contenente il nome del pezzo da considerare e la matrice.

Come risultato, deve essere restituito un booleano, che deve essere true se e solo se la matrice è una matrice di mosse del pezzo, come descritto sopra.

Quando la funzione viene chiamata, vi viene garantito che il file di input è un file di testo con esattamente la forma seguente:

  pezzo
  N M
  x1,1 x1,2 ... x1,M
  ...
  xN,1 xN,2 ... xN,M

dove in prima riga, pezzo è il nome del pezzo, una stringa tra le seguenti torre,cavallo,alfiere,donna,re. In seconda riga ci sono le dimensioni della matrice: due interi positivi separati da spazio. Nelle N righe sottostanti ci sono i valori della matrice (int arbitrari xi,j). Le righe sono separate andando a capo, mentre su ogni riga i valori sono separati da uno spazio.

In caso di input malformato non corrispondente a quanto scritto subito sopra (per esempio, pedone come pezzo, "matrice" non rettangolare o non N x M, valore non intero nella matrice) non si richiede nessun comportamento particolare. Il programma può dare un risultato qualunque, o anche generare un errore a tempo di esecuzione.

Si ribadisce che il formato di file di sopra non garantisce nulla sui valori degli interi nella matrice (a parte la loro rappresentabilità in un int). Una matrice di interi delle dimensioni date che non è una matrice di mosse non causa la malformatezza dell'input. Su questi input la funzione deve obbligatoriamente restituire false.

Consigli

Ricordatevi che, quando confrontate due String in Java come per esempio i nomi dei pezzi, dovete usare s1.equals(s2) e non s1 == s2.

Svolgimento

Si chiede di scrivere una singola classe Java Progetto, che contenga la funzione testChessMoves descritta sopra. In particolare, è obbligatorio usare come base per il progetto un progetto Eclipse contenente il il seguente scheletro di di classe Java.

La classe scheletro va posizionata in un progetto Eclipse come segue. Create un progetto Eclipse chiamato cognome_matricola (usate i vostri dati, per esempio tramaglino_000001 o de_paperoni_000002), e create la classe Progetto al suo interno nella cartella src. Dovete ottenere un file come segue:

È obbligatorio rispettare la posizione del file della classe come descritto sopra. Dentro quel file potete quindi inserire il codice dello scheletro fornito.

È tassativamente proibito modificare lo scheletro nelle parti segnate al suo interno come da non modificare. In particolare, non si può modificare il tipo o il nome delle procedure / funzioni all'interno. In nessun caso il file consegnato dovrà contenere una dichiarazione package.

È invece consentito (e consigliabile) definire delle procedure/funzioni addizionali all'interno della classe Progetto. È consentito aggiungere import per usare librerie di Java.

È consentito modificare il metodo main della classe nello scheletro. Si noti, tuttavia, che tale metodo potrà essere cancellato e sovrascritto, o comunque non eseguito, da chi corregge. Di conseguenza, se si decidono di usare variabili globali, queste devono essere inizializzate dentro le funzioni relative ai due esercizi, e non dentro il main, in quanto quest'ultimo non verrà eseguito.

Durante la correzione, le funzioni relative agli esercizi verranno chiamate ripetutamente eseguendo (anche) test automatizzati.

Helper

Per potere testare più facilmente il vostro progetto, vi viene fornita la seguente libreria Java.

Aggiornamento: abbiamo corretto un bug nell'helper 1.0, che invertiva il numero delle righe con quelle delle colonne. L'helper 1.1 qui sotto include la correzione.

Dopo avere scaricato il file di sopra in una qualunque cartella, potete inserire la libreria helper nel vostro progetto Eclipse, selezionando il vostro progetto, facendo clic destro, e selezionando dal menù la voce Build Path -> Add External Archives.... Comparirà un finestra dove potete selezionare il file jar fornito sopra.

Dopo avere aggiunto la libreria helper al vostro progetto, all'interno del file Java Progetto.java potete usare le funzioni della libreria, che mostriamo sotto. Nello scheletro di progetto che vi forniamo, trovate già degli esempi su come usarle nel main(), dopo avere usato import progetto2019.Helper; all'inizio del file.

static void Helper.generateMoveFile(String fileName)

static void Helper.generateNonMoveFile(String fileName)

La procedura Helper.generateMoveFile prende come parametro un nome di file. La procedura crea un file con quel nome (se già esistente, viene sovrascritto, quindi state attenti a non cancellare un file con dati importanti). Il file così creato è un file random del formato atteso dalla vostra funzione testChessMoves(), contenente una matrice di mosse, e sul quale la vostra funzione deve restituire true.

Analogamente, Helper.generateNonMoveFile compie un'analoga operazione, creando (sovrascrivendo) un file random nello stesso formato, ma contenente una matrice di interi che non è una matrice di mosse. Su questo file la funzione testChessMoves(), deve quindi restituire false.

Usare l'helper non è obbligatorio (anche se fortemente raccomandato). Se non lo volete usare, per potere compilare lo scheletro dovete rimuovere dal file sia la riga import progetto2019.Helper; che tutti i riferimenti alle funzioni Helper.

Nota bene: se usate l'helper un certo numero di volte, e se sui file così generati la vostra funzione fornisce il risultato atteso, questo non vuol dire che la funzione sia corretta in tutti i casi possibili. È possibile che, in fase di valutazione del progetto, vengano controllati altri casi, e che su questi si scopra che il vostro codice non funziona correttamente. In altre parole: con i test possiamo solo dimostrare che un programma è scorretto, ma mai che è corretto.

Requisiti e criteri di valutazione

Il progetto verrà valutato secondo i seguenti criteri, che formano un insieme di requisiti sul codice consegnato. Ogni requisito primario è condizione necessaria per il superamento della prova: anche se uno di questi non viene rispettato, la prova non è superata. I requisiti secondari devono essere generalmente rispettati. Nel caso ci siano solo minori violazioni di tali requisiti, la prova è comunque superata. Violazioni gravi possono comunque causare il non superamento della prova.

Requisiti tecnici (primario). La soluzione consegnata deve seguire lo scheletro di progetto fornito sopra, modificato nel modo descritto sopra.

Devono inoltre essere rispettati questi requisiti:

  1. Non modificate il nome della classe Progetto, i nomi o i tipi delle procedure/funzioni segnate come da non modificare. Non ci deve essere nessuna dichiarazione di package della classe.
  2. Posizionate la classe Progetto come descritto sopra nel vostro progetto eclipse.
  3. Il file di input deve essere quello passato come parametro, e non uno con un nome prefissato. Per esempio, new File(fileName) usa il parametro, mentre new File("fileName") usa un nome prefissato.
  4. Le procedure/funzioni richieste non devono interagire con l'utente in nessun modo (ad es., chiedere di inserire dati all'utente). I nostri test devono potere chiamare ripetutamente quelle funzioni in modo automatico, senza il nostro intervento manuale. Il main invece può interagire con l'utente, se desiderato (ma comunque come detto sopra il codice del main può essere ignorato da noi durante i test.)
  5. Non usate lettere accentate nei vostri file Java, neppure all'interno delle stringhe o dei commenti. (In passato hanno creato problemi di compilazione, visto che i sorgenti arrivavano in encoding diversi.)

Il non rispettare questi requisiti tecnici può causare il fallimento dei nostri test automatizzati, ed in tal caso la prova non sarà superata.

Correttezza (primario). Non ci devono essere errori a tempo di compilazione: il programma deve compilare. Non ci devono essere errori a tempo di esecuzione: il programma non deve generare eccezioni (per esempio, DivisionByZero oppure ArrayIndexOutOfBounds) quando eseguito su un input ben formato. Il programma deve dare l'output desiderato su qualunque input compatibile con la specifica.
Nota bene: Nel caso il programma sia scorretto, non è compito di chi corregge fare il debugging, ovvero identificare la causa dell'errore e suggerire una modifica per rimuoverla. Anche quando tale causa fosse nota a chi corregge, non verrà comunicata allo studente, in quanto sarebbe come suggerire una parte non banale della soluzione della prova. Infatti, capita frequentemente che correggere l'errore dopo averlo individuato diventi banale ("devo usare x, e non x+1"), e che la prova di conseguenza consista prevalentemente nella ricerca dell'errore.
Corollario: se provando il programma su un insieme di input campione si riscontrano già errori di correttezza, chi corregge non è tenuto ad esaminare il codice del programma.

Leggibilità (secondario). Il codice deve essere scritto in modo tale da permettere ad un altro programmatore di comprenderne la logica. Non è sufficiente che il codice "funzioni", o che sia chiaro a chi lo ha scritto. Per aiutare la lettura del codice da parte di altri, si consiglia di usare dei nomi di variabile e di funzione appropriati, strutturare il codice adeguatamente (dove ha senso, meglio dividere una funzione lunga in più funzioni ausiliarie), e di inserire dei commenti.

Non commentate come state calcolando qualcosa, commentate piuttosto cosa state calcolando. Per esempio, il seguente commento è altamente inutile:

	// incremento i
	i++;

Al contrario, il seguente aiuta a comprendere il codice:

	// passo a coordinate polari
	rho = Math.sqrt(x*x + y*y);
	theta = Math.atan2(y, x);

Consegna del progetto

Per potere partecipare allo scritto di un appello di esame, il progetto deve essere consegnato entro le date indicate nell'elenco degli appelli d'esame. La consegna si svolge mandando una email avente esattamente le seguenti caratteristiche.

Note Finali

Se avete dubbi sul testo del progetto, ovvero su che cosa vi sta venendo chiesto, chiedete pure delucidazioni per email o a ricevimento. Se invece avete dubbi sulla soluzione dell'esercizio, ovviamente non possiamo suggerirvi nulla.

Il progetto non viene svolto in un ambiente "controllato" come per esempio avviene per un esame scritto, ma vi viene lasciata libertà di svolgerlo dove e quando preferite (compatibilmente con le scadenze). Per esempio, potete usare i laboratori quando liberi, o farlo su un vostro computer personale.

Il progetto è individuale, non di gruppo. Tuttavia, vi è consentito discutere del progetto con altre persone per scambiarsi opinioni a riguardo. Non è consentita, ovviamente, la copia di pezzi di codice inerenti al progetto da uno studente all'altro. Allo stesso modo, farsi fare il progetto da un'altra persona è considerato equivalente a copiare. In caso di dubbi sull'autenticità del progetto, ci riserviamo la possibilità di convocarvi per un colloquio sul codice che avete consegnato, anche dopo l'esame scritto.

Vi è consentito di "copiare" invece pezzi di codice che vi abbiamo fornito noi, o di "tradurre in Java" dei pezzi di codice che potreste trovare su qualche libro o tutorial online, e che non siano soluzioni degli esercizi proposti o di una loro parte significativa. Nei casi consentiti dovete obbligatoriamente citare la fonte in un commento nel codice.

Il discutere del progetto su forum di discussione su Internet o simili non è vietato a prescindere, ma è soggetto alle stesse regole della comunicazione tra altri studenti. Inoltre, se iniziate una discussione su un forum riguardo al progetto, dovete obbligatoriamente dichiarare 1) che l'esercizio in questione è un progetto di esame, e 2) che non desiderate che qualcuno vi scriva una soluzione al posto vostro. Se anche chiarendo ciò qualcuno vi risponde includendo del codice, voi non potete includerlo nel progetto.

Risposte a domande degli studenti

Se la matrice contiene solo zeri, non è una matrice di mosse e il risultato del test deve essere false. Infatti, dati i vincoli sopra (numero mosse K>=0 e sequenza di mosse p1,p2,...,pK,p(K+1)), qualunque sequenza di mosse contiene almeno la posizione iniziale p1, e quindi un (unico) 1 deve essere sempre presente in una matrice di mosse.

Una matrice con solo zeri tranne per una singola cella con un 1 è una matrice di mosse per qualunque pezzo.

Se preferite, potete usare anche caratteristiche di Java non viste a lezione (costrutti diversi come gli oggetti, librerie non viste a lezione purché incluse tra quelle standard di Java), anche se il progetto si può svolgere benissimo senza. Dovete però comprendere il codice che state usando: se venite chiamati ad un colloquio (vedi sopra) vi può essere chiesto di spiegarlo.

Informatica - Teaching - Home


Valid CSS Valid XHTML 1.1 Roberto Zunino, 2019