diff --git a/.idea/libraries/google_code_gson.xml b/.idea/libraries/google_code_gson.xml new file mode 100644 index 0000000..22e952f --- /dev/null +++ b/.idea/libraries/google_code_gson.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/PatenteELibbrettoPregoh.iml b/PatenteELibbrettoPregoh.iml index e98415d..0e47b0b 100644 --- a/PatenteELibbrettoPregoh.iml +++ b/PatenteELibbrettoPregoh.iml @@ -8,5 +8,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lib/gson-2.10.1.jar b/lib/gson-2.10.1.jar new file mode 100644 index 0000000..a88c5bd Binary files /dev/null and b/lib/gson-2.10.1.jar differ diff --git a/src/it/unibs/fp/patenteelibbrettopregoh/Comune.java b/src/it/unibs/fp/patenteelibbrettopregoh/Comune.java index da52e0b..6804030 100644 --- a/src/it/unibs/fp/patenteelibbrettopregoh/Comune.java +++ b/src/it/unibs/fp/patenteelibbrettopregoh/Comune.java @@ -1,22 +1,46 @@ package it.unibs.fp.patenteelibbrettopregoh; +/** + * Classe che rappresenta un comune con nome e codice. + */ public class Comune { private final String nome; private final String codice; + /** + * Costruttore della classe Comune. + * + * @param nome il nome del comune + * @param codice il codice del comune + */ public Comune(String nome, String codice) { this.nome = nome; this.codice = codice; } + /** + * Restituisce il nome del comune. + * + * @return il nome del comune + */ public String getNome() { return nome; } + /** + * Restituisce il codice del comune. + * + * @return il codice del comune + */ public String getCodice() { return codice; } + /** + * Restituisce una rappresentazione testuale del comune. + * + * @return una stringa che rappresenta il comune + */ @Override public String toString() { return "Comune{" + diff --git a/src/it/unibs/fp/patenteelibbrettopregoh/Comuni.java b/src/it/unibs/fp/patenteelibbrettopregoh/Comuni.java index 3866bec..0fcff3e 100644 --- a/src/it/unibs/fp/patenteelibbrettopregoh/Comuni.java +++ b/src/it/unibs/fp/patenteelibbrettopregoh/Comuni.java @@ -2,25 +2,53 @@ package it.unibs.fp.patenteelibbrettopregoh; import java.util.ArrayList; +/** + * Classe che rappresenta una lista di comuni. + */ public class Comuni { private final ArrayList comuni; + /** + * Costruttore della classe Comuni. + * Inizializza la lista di comuni. + */ public Comuni() { this.comuni = new ArrayList<>(); } + /** + * Aggiunge un comune alla lista. + * + * @param comune il comune da aggiungere + */ public void addComune(Comune comune) { this.comuni.add(comune); } + /** + * Rimuove un comune dalla lista. + * + * @param comune il comune da rimuovere + */ public void removeComune(Comune comune) { this.comuni.remove(comune); } + /** + * Restituisce la lista di comuni. + * + * @return la lista di comuni + */ public ArrayList getComuni() { return comuni; } + /** + * Restituisce il codice del comune dato il nome. + * + * @param nomeComune il nome del comune + * @return il codice del comune, oppure null se non trovato + */ public String getCodiceComune(String nomeComune) { for (Comune comune : comuni) { if (comune.getNome().equalsIgnoreCase(nomeComune)) { diff --git a/src/it/unibs/fp/patenteelibbrettopregoh/GameData.java b/src/it/unibs/fp/patenteelibbrettopregoh/GameData.java index 0924513..d0cea98 100644 --- a/src/it/unibs/fp/patenteelibbrettopregoh/GameData.java +++ b/src/it/unibs/fp/patenteelibbrettopregoh/GameData.java @@ -3,6 +3,13 @@ package it.unibs.fp.patenteelibbrettopregoh; import java.time.LocalDate; import java.util.ArrayList; +/** + * GameData.java + * questa classe rappresenta i dati di gioco, come il formato, il nome del personaggio, + * il diario, le persone, il saldo, il numero di mazzette accettate dalla polizia, + * il numero di rivoluzionari accettati, lo stato del gioco e la data. + * + */ public class GameData { private final Formato formato; private final String nomePersonaggio; @@ -14,9 +21,14 @@ public class GameData { private int numeroRivoluzionariAccettati; private StatoGioco statoGioco; private int giorno; - private int indiceUltimaPersonaPassata; private LocalDate data; + /** + * costruttore della classe GameData. + * Inizializza i dati di gioco con il formato specificato. + * + * @param formato il formato del gioco + */ public GameData(Formato formato) { this.formato = formato; this.diario = new ArrayList<>(); @@ -28,52 +40,95 @@ public class GameData { this.statoGioco = StatoGioco.IN_CORSO; this.nomePersonaggio = "Ajeje Brazorf"; this.giorno = 1; - this.indiceUltimaPersonaPassata = -1; - this.data = LocalDate.of(2024, 5, giorno); + this.data = LocalDate.of(2024, 4, 26); } + /** + * getter per il diario. + * + */ public ArrayList getDiario() { return diario; } + /** + * getter per i comuni. + * + * @return i comuni + */ public Comuni getComuni() { return comuni; } + /** + * getter per le persone. + * + * @return le persone + */ public ArrayList getPersone() { return persone; } + /** + * getter per il saldo. + * + * @return il saldo + */ public double getSaldo() { return saldo; } + /** + * getter di una persona casuale da controllare. + * + * @return la persona casuale da controllare + */ public Persona getPersonaDaControlare() { - indiceUltimaPersonaPassata++; - return persone.get(indiceUltimaPersonaPassata); - + return persone.get((int) (Math.random() * (persone.size() + 1))); } + /** + * getter per il numero di mazzette accettate dalla polizia. + * + * @return il numero di mazzette accettate dalla polizia + */ public int getNumeroMazzetteAccettatePolizia() { return numeroMazzetteAccettatePolizia; } + /** + * getter per il numero di rivoluzionari accettati. + * + * @return il numero di rivoluzionari accettati + */ public int getNumeroRivoluzionariAccettati() { return numeroRivoluzionariAccettati; } + /** + * aggiunge una pagina al diario. + */ public void addPaginaDiario(PaginaDiario pagina) { diario.add(pagina); } + /** + * incrementa il saldo di un valore specificato. + */ public void addSaldo(double valore) { saldo += valore; } + /** + * paga una multa di un valore specificato. + */ public void pagaMulta(double valore) { paga(valore); } + /** + * aumenta il numero di mazzette accettate dalla polizia. + */ public void incrementaMazzetteAccettatePolizia() { numeroMazzetteAccettatePolizia++; if (numeroMazzetteAccettatePolizia >= 2) { @@ -81,6 +136,9 @@ public class GameData { } } + /** + * aumenta il numero di rivoluzionari accettati. + */ public void incrementaRivoluzionariAccettati() { numeroRivoluzionariAccettati++; if (numeroRivoluzionariAccettati >= 5) { @@ -88,25 +146,45 @@ public class GameData { } } + /** + * getter per il nome del personaggio. + * + * @return il nome del personaggio + */ public String getNomePersonaggio() { return nomePersonaggio; } + /** + * getter per lo stato del gioco. + * + * @return lo stato del gioco + */ public StatoGioco getStatoGioco() { return statoGioco; } + /** + * getter per il giorno corrente del gioco. + * + * @return il giorno corrente del gioco + */ public int getGiorno() { return giorno; } + /** + * aumenta il giorno corrente e aggiorna il saldo. + * + * @param personeControllate la lista delle persone controllate + */ public void incrementaGiorno(ArrayList personeControllate) { if (!personeControllate.isEmpty()) { addSaldo(50 * personeControllate.size()); } paga(200); - PaginaDiario pagina = new PaginaDiario(giorno + "/" + data.getMonthValue() + "/" + data.getYear(), saldo); + PaginaDiario pagina = new PaginaDiario(String.format("%d-%02d-%02d", data.getYear(), data.getMonthValue(), data.getDayOfMonth()), saldo); for (PersonaControllata persona : personeControllate) { pagina.addPersonaControllata(persona); } @@ -114,7 +192,7 @@ public class GameData { giorno++; - data = LocalDate.of(2024, 5, giorno); + data = LocalDate.of(data.getYear(), data.getMonthValue(), data.getDayOfMonth() + 1); if (giorno > 12 && statoGioco == StatoGioco.IN_CORSO && saldo > 2300) { statoGioco = StatoGioco.DODICESIMO_GIORNO; @@ -123,6 +201,9 @@ public class GameData { } } + /** + * fa pagare un valore specificato al saldo. + */ private void paga(double valore) { saldo -= valore; if (saldo < 0) { @@ -130,10 +211,19 @@ public class GameData { } } + /** + * getter per la data del gioco. + * + * @return la data del gioco + */ public LocalDate getData() { return data; } + /** + * salva il diario in un file. + * + */ public void saveDiario() { Parser.saveDiario("FileEsercizio/diario", diario, formato); } diff --git a/src/it/unibs/fp/patenteelibbrettopregoh/PaginaDiario.java b/src/it/unibs/fp/patenteelibbrettopregoh/PaginaDiario.java index 3546cd4..a12f756 100644 --- a/src/it/unibs/fp/patenteelibbrettopregoh/PaginaDiario.java +++ b/src/it/unibs/fp/patenteelibbrettopregoh/PaginaDiario.java @@ -1,38 +1,82 @@ package it.unibs.fp.patenteelibbrettopregoh; +import com.google.gson.annotations.SerializedName; + +// import java.time.LocalDate; import java.util.ArrayList; +/** + * La classe PaginaDiario rappresenta una pagina del diario di un personaggio. + * Ogni pagina contiene la data, il bilancio e una lista di persone controllate. + */ public class PaginaDiario { - private final String data; + private final String data; // per nevitare problemi con Gson e la serializzazione di LocalDate private final double bilancio; + @SerializedName("persone") private final ArrayList personeControllate; + /** + * Costruttore della classe PaginaDiario. + * + * @param data la data della pagina + * @param bilancio il bilancio della pagina + */ public PaginaDiario(String data, double bilancio) { this.data = data; this.bilancio = bilancio; this.personeControllate = new ArrayList<>(); } + /** + * Restituisce il giorno. + * + * @return il giorno della data + */ public int getGiorno() { - return Integer.parseInt(data.split("/")[0]); + return Integer.parseInt(data.split("-")[2]); } + /** + * Restituisce la data. + * + * @return la data + */ public String getData() { return data; } + /** + * Restituisce il bilancio. + * + * @return il bilancio + */ public double getBilancio() { return bilancio; } + /** + * Restituisce la lista di persone controllate. + * + * @return la lista di persone controllate + */ public ArrayList getPersoneControllate() { return personeControllate; } + /** + * aggiunge una persona controllata alla pagina del diario. + * + * @param persona la persona da aggiungere + */ public void addPersonaControllata(PersonaControllata persona) { this.personeControllate.add(persona); } + /** + * rimuove una persona controllata dalla pagina del diario. + * + * @param persona la persona da rimuovere + */ public void removePersonaControllata(PersonaControllata persona) { this.personeControllate.remove(persona); } diff --git a/src/it/unibs/fp/patenteelibbrettopregoh/Parser.java b/src/it/unibs/fp/patenteelibbrettopregoh/Parser.java index fcfd414..8cf09f8 100644 --- a/src/it/unibs/fp/patenteelibbrettopregoh/Parser.java +++ b/src/it/unibs/fp/patenteelibbrettopregoh/Parser.java @@ -2,213 +2,339 @@ package it.unibs.fp.patenteelibbrettopregoh; import javax.xml.stream.*; import java.io.*; +import java.lang.reflect.Type; import java.util.ArrayList; +import com.google.gson.Gson; +import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; + +import java.io.FileWriter; + +/** + * Parser.java + * Questa classe è responsabile della lettura e scrittura dei dati di gioco in formato JSON e XML. + * Utilizza la libreria Gson per la serializzazione e deserializzazione dei dati. + */ public class Parser { + /** + * Metodo per il parsing delle persone da un file JSON o XML. + * + * @param formato il formato del file (JSON o XML) + * @param fileName il nome del file senza estensione + * @return una lista di oggetti Persona + */ public static ArrayList parsePersone(Formato formato, String fileName) { ArrayList persone = new ArrayList<>(); if (formato == Formato.XML) { - fileName = fileName + ".xml"; - XMLInputFactory xmlif; - XMLStreamReader xmlr; - String currentElement = null; - String nome = null; - String cognome = null; - String sesso = null; - String dataNascita = null; - String comuneNascita = null; - String codiceFiscale = null; - String scadenzaDocumento = null; - - try (FileInputStream reader = new FileInputStream(fileName)) { - xmlif = XMLInputFactory.newInstance(); - xmlr = xmlif.createXMLStreamReader(fileName, reader); - - while (xmlr.hasNext()) { - int event = xmlr.getEventType(); - switch (event) { - case XMLStreamConstants.START_ELEMENT: - currentElement = xmlr.getLocalName(); // <- sposta qui, nel posto giusto - break; - case XMLStreamConstants.CHARACTERS: - String text = xmlr.getText().trim(); - if (!text.isEmpty() && currentElement != null) { - switch (currentElement) { - case "nome" -> nome = text; - case "cognome" -> cognome = text; - case "sesso" -> sesso = text; - case "data_nascita" -> dataNascita = text; - case "comune_nascita" -> comuneNascita = text; - case "codice_fiscale" -> codiceFiscale = text; - case "scadenza_documento" -> scadenzaDocumento = text; - } - } - break; - case XMLStreamConstants.END_ELEMENT: - String endTag = xmlr.getLocalName(); - if (endTag.equals("persona")) { - Persona persona = new Persona(nome, cognome, sesso, dataNascita, comuneNascita, codiceFiscale, scadenzaDocumento); - persone.add(persona); - } - currentElement = null; // reset solo alla fine di un elemento - break; - } - xmlr.next(); // importante: avanza solo una volta per ciclo - } - xmlr.close(); - } catch (FactoryConfigurationError | XMLStreamException | IOException e) { - System.out.println("Error reading the file: " + e.getMessage()); - } + parsePersoneXML(fileName, persone); } else { - fileName = fileName + ".json"; + persone = parsePersoneJSON(fileName, persone); + } return persone; } + /** + * Metodo per il parsing delle persone da un file JSON. + * + * @param fileName il nome del file senza estensione + * @param persone la lista di persone da riempire + * @return la lista di persone + */ + private static ArrayList parsePersoneJSON(String fileName, ArrayList persone) { + fileName = fileName + ".json"; + try (FileReader reader = new FileReader(fileName)) { + Gson gson = new Gson(); + Type listType = new TypeToken>(){}.getType(); + persone = gson.fromJson(reader, listType); + } catch (JsonIOException | JsonSyntaxException | IOException e) { + System.out.println("Error reading the JSON file: " + e.getMessage()); + } + return persone; + } + + /** + * Metodo per il parsing delle persone da un file XML. + * + * @param fileName il nome del file senza estensione + * @param persone la lista di persone da riempire + */ + private static void parsePersoneXML(String fileName, ArrayList persone) { + fileName = fileName + ".xml"; + XMLInputFactory xmlif; + XMLStreamReader xmlr; + String currentElement = null; + String nome = null; + String cognome = null; + String sesso = null; + String dataNascita = null; + String comuneNascita = null; + String codiceFiscale = null; + String scadenzaDocumento = null; + + try (FileInputStream reader = new FileInputStream(fileName)) { + xmlif = XMLInputFactory.newInstance(); + xmlr = xmlif.createXMLStreamReader(fileName, reader); + + while (xmlr.hasNext()) { + int event = xmlr.getEventType(); + switch (event) { + case XMLStreamConstants.START_ELEMENT: + currentElement = xmlr.getLocalName(); // <- sposta qui, nel posto giusto + break; + case XMLStreamConstants.CHARACTERS: + String text = xmlr.getText().trim(); + if (!text.isEmpty() && currentElement != null) { + switch (currentElement) { + case "nome" -> nome = text; + case "cognome" -> cognome = text; + case "sesso" -> sesso = text; + case "data_nascita" -> dataNascita = text; + case "comune_nascita" -> comuneNascita = text; + case "codice_fiscale" -> codiceFiscale = text; + case "scadenza_documento" -> scadenzaDocumento = text; + } + } + break; + case XMLStreamConstants.END_ELEMENT: + String endTag = xmlr.getLocalName(); + if (endTag.equals("persona")) { + Persona persona = new Persona(nome, cognome, sesso, dataNascita, comuneNascita, codiceFiscale, scadenzaDocumento); + persone.add(persona); + } + currentElement = null; // reset solo alla fine di un elemento + break; + } + xmlr.next(); // importante: avanza solo una volta per ciclo + } + xmlr.close(); + } catch (FactoryConfigurationError | XMLStreamException | IOException e) { + System.out.println("Error reading the file: " + e.getMessage()); + } + } + + /** + * Metodo per il parsing dei comuni da un file JSON o XML. + * + * @param formato il formato del file (JSON o XML) + * @param fileName il nome del file senza estensione + * @return un oggetto Comuni contenente la lista di comuni + */ public static Comuni parseComuni(Formato formato, String fileName) { Comuni comuni = new Comuni(); if (formato == Formato.XML) { - fileName = fileName + ".xml"; - XMLInputFactory xmlif; - XMLStreamReader xmlr; - String currentElement = null; - String nome = null; - String codice = null; - - try (FileInputStream reader = new FileInputStream(fileName)) { - xmlif = XMLInputFactory.newInstance(); - xmlr = xmlif.createXMLStreamReader(fileName, reader); - - while (xmlr.hasNext()) { - int event = xmlr.getEventType(); - - switch (event) { - - case XMLStreamConstants.START_ELEMENT: - currentElement = xmlr.getLocalName(); // <- sposta qui, nel posto giusto - break; - - - case XMLStreamConstants.CHARACTERS: - String text = xmlr.getText().trim(); - if (!text.isEmpty() && currentElement != null) { - if (currentElement.equals("nome")) { - nome = text; - } else if (currentElement.equals("codice")) { - codice = text; - } - } - break; - - case XMLStreamConstants.END_ELEMENT: - String endTag = xmlr.getLocalName(); - if (endTag.equals("comune")) { - Comune comune = new Comune(nome, codice); - comuni.addComune(comune); - - nome = null; - codice = null; - } - currentElement = null; // reset solo alla fine di un elemento - break; - } - - xmlr.next(); // importante: avanza solo una volta per ciclo - } - - xmlr.close(); - } catch (FactoryConfigurationError | XMLStreamException | IOException e) { - System.out.println("Error reading the file: " + e.getMessage()); - } + parseComuniXML(fileName, comuni); } else { - fileName = fileName + ".json"; + comuni = parseComuniJSON(fileName, comuni); + } + + return comuni; + } + + /** + * Metodo per il parsing dei comuni da un file JSON. + * + * @param fileName il nome del file senza estensione + * @param comuni l'oggetto Comuni da riempire + * @return l'oggetto Comuni + */ + private static Comuni parseComuniJSON(String fileName, Comuni comuni) { + fileName = fileName + ".json"; + try (FileReader reader = new FileReader(fileName)) { + Gson gson = new Gson(); + Type listType = new TypeToken>() {}.getType(); + ArrayList listaComuni = gson.fromJson(reader, listType); + + comuni = new Comuni(); + for (Comune comune : listaComuni) { + comuni.addComune(comune); + } + + } catch (JsonIOException | JsonSyntaxException | IOException e) { + System.out.println("Error reading the JSON file: " + e.getMessage()); } return comuni; } - public static void saveDiario (String fileName, ArrayList pagineDiario, Formato formato) { - if (formato == Formato.XML) { - fileName = fileName + ".xml"; - try (FileOutputStream outputStream = new FileOutputStream(fileName)) { - XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance(); - XMLStreamWriter xmlWriter = xmlOutputFactory.createXMLStreamWriter(outputStream, "UTF-8"); + /** + * Metodo per il parsing dei comuni da un file XML. + * + * @param fileName il nome del file senza estensione + * @param comuni l'oggetto Comuni da riempire + */ + private static void parseComuniXML(String fileName, Comuni comuni) { + fileName = fileName + ".xml"; + XMLInputFactory xmlif; + XMLStreamReader xmlr; + String currentElement = null; + String nome = null; + String codice = null; - xmlWriter.writeStartDocument("UTF-8", "1.0"); - xmlWriter.writeStartElement("diario"); + try (FileInputStream reader = new FileInputStream(fileName)) { + xmlif = XMLInputFactory.newInstance(); + xmlr = xmlif.createXMLStreamReader(fileName, reader); - for (PaginaDiario pagina : pagineDiario) { - xmlWriter.writeStartElement("giornata"); - xmlWriter.writeAttribute("numero", String.valueOf(pagina.getGiorno())); + while (xmlr.hasNext()) { + int event = xmlr.getEventType(); - xmlWriter.writeStartElement("data"); - xmlWriter.writeCharacters(pagina.getData()); - xmlWriter.writeEndElement(); + switch (event) { - xmlWriter.writeStartElement("bilancio"); - xmlWriter.writeCharacters(String.valueOf(pagina.getBilancio())); - xmlWriter.writeEndElement(); + case XMLStreamConstants.START_ELEMENT: + currentElement = xmlr.getLocalName(); + break; - xmlWriter.writeStartElement("persone"); - xmlWriter.writeAttribute("numero", String.valueOf(pagina.getPersoneControllate().size())); - for (int i = 0; i < pagina.getPersoneControllate().size(); i++) { - PersonaControllata persona = pagina.getPersoneControllate().get(i); + case XMLStreamConstants.CHARACTERS: + String text = xmlr.getText().trim(); + if (!text.isEmpty() && currentElement != null) { + if (currentElement.equals("nome")) { + nome = text; + } else if (currentElement.equals("codice")) { + codice = text; + } + } + break; - xmlWriter.writeStartElement("persona"); - xmlWriter.writeAttribute("id", String.valueOf(i + 1)); + case XMLStreamConstants.END_ELEMENT: + String endTag = xmlr.getLocalName(); + if (endTag.equals("comune")) { + Comune comune = new Comune(nome, codice); + comuni.addComune(comune); - xmlWriter.writeStartElement("nome"); - xmlWriter.writeCharacters(persona.getNome()); - xmlWriter.writeEndElement(); - - xmlWriter.writeStartElement("cognome"); - xmlWriter.writeCharacters(persona.getCognome()); - xmlWriter.writeEndElement(); - - xmlWriter.writeStartElement("sesso"); - xmlWriter.writeCharacters(persona.getSesso()); - xmlWriter.writeEndElement(); - - xmlWriter.writeStartElement("data_nascita"); - xmlWriter.writeCharacters(persona.getDataNascita()); - xmlWriter.writeEndElement(); - - xmlWriter.writeStartElement("comune_nascita"); - xmlWriter.writeCharacters(persona.getComuneNascita()); - xmlWriter.writeEndElement(); - - xmlWriter.writeStartElement("codice_fiscale"); - xmlWriter.writeCharacters(persona.getCodiceFiscale()); - xmlWriter.writeEndElement(); - - xmlWriter.writeStartElement("data_scadenza_id"); - xmlWriter.writeCharacters(persona.getScadenzaDocumento()); - xmlWriter.writeEndElement(); - - xmlWriter.writeStartElement("stato_transito"); - xmlWriter.writeCharacters(persona.getStatoTransito()); - xmlWriter.writeEndElement(); - - xmlWriter.writeEndElement(); // persona - } - - xmlWriter.writeEndElement(); // persone - xmlWriter.writeEndElement(); // giornata + nome = null; + codice = null; + } + currentElement = null; + break; } - xmlWriter.writeEndElement(); // diario - xmlWriter.writeEndDocument(); - xmlWriter.flush(); - } catch (XMLStreamException | IOException e) { - System.out.println("Error writing the file: " + e.getMessage()); + xmlr.next(); } - } else if (formato == Formato.JSON) { - fileName = fileName + ".json"; + xmlr.close(); + } catch (FactoryConfigurationError | XMLStreamException | IOException e) { + System.out.println("Error reading the file: " + e.getMessage()); + } + } + + /** + * Metodo per il salvataggio del diario in formato JSON o XML. + * + * @param fileName il nome del file senza estensione + * @param pagineDiario la lista di pagine del diario + * @param formato il formato del file (JSON o XML) + */ + public static void saveDiario (String fileName, ArrayList pagineDiario, Formato formato) { + if (formato == Formato.XML) { + salvaDiarioXML(fileName, pagineDiario); + + } else if (formato == Formato.JSON) { + salvaDiarioJSON(fileName, pagineDiario); + } + } + + /** + * Metodo per il salvataggio del diario in formato JSON. + * + * @param fileName il nome del file senza estensione + * @param pagineDiario la lista di pagine del diario + */ + private static void salvaDiarioJSON(String fileName, ArrayList pagineDiario) { + fileName = fileName + ".json"; + Gson gson = new Gson(); + try (FileWriter writer = new FileWriter(fileName)) { + gson.toJson(pagineDiario, writer); + } catch (JsonIOException | IOException e) { + System.out.println("Error in initializing the writer:"); + System.out.println(e.getMessage()); + } + } + + /** + * Metodo per il salvataggio del diario in formato XML. + * + * @param fileName il nome del file senza estensione + * @param pagineDiario la lista di pagine del diario + */ + private static void salvaDiarioXML(String fileName, ArrayList pagineDiario) { + fileName = fileName + ".xml"; + try (FileOutputStream outputStream = new FileOutputStream(fileName)) { + XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance(); + XMLStreamWriter xmlWriter = xmlOutputFactory.createXMLStreamWriter(outputStream, "UTF-8"); + + xmlWriter.writeStartDocument("UTF-8", "1.0"); + xmlWriter.writeStartElement("diario"); + + for (PaginaDiario pagina : pagineDiario) { + xmlWriter.writeStartElement("giornata"); + xmlWriter.writeAttribute("numero", String.valueOf(pagina.getGiorno())); + + xmlWriter.writeStartElement("data"); + xmlWriter.writeCharacters(pagina.getData()); + xmlWriter.writeEndElement(); + + xmlWriter.writeStartElement("bilancio"); + xmlWriter.writeCharacters(String.valueOf(pagina.getBilancio())); + xmlWriter.writeEndElement(); + + xmlWriter.writeStartElement("persone"); + xmlWriter.writeAttribute("numero", String.valueOf(pagina.getPersoneControllate().size())); + + for (int i = 0; i < pagina.getPersoneControllate().size(); i++) { + PersonaControllata persona = pagina.getPersoneControllate().get(i); + + xmlWriter.writeStartElement("persona"); + xmlWriter.writeAttribute("id", String.valueOf(i + 1)); + + xmlWriter.writeStartElement("nome"); + xmlWriter.writeCharacters(persona.getNome()); + xmlWriter.writeEndElement(); + + xmlWriter.writeStartElement("cognome"); + xmlWriter.writeCharacters(persona.getCognome()); + xmlWriter.writeEndElement(); + + xmlWriter.writeStartElement("sesso"); + xmlWriter.writeCharacters(persona.getSesso()); + xmlWriter.writeEndElement(); + + xmlWriter.writeStartElement("data_nascita"); + xmlWriter.writeCharacters(persona.getDataNascita()); + xmlWriter.writeEndElement(); + + xmlWriter.writeStartElement("comune_nascita"); + xmlWriter.writeCharacters(persona.getComuneNascita()); + xmlWriter.writeEndElement(); + + xmlWriter.writeStartElement("codice_fiscale"); + xmlWriter.writeCharacters(persona.getCodiceFiscale()); + xmlWriter.writeEndElement(); + + xmlWriter.writeStartElement("data_scadenza_id"); + xmlWriter.writeCharacters(persona.getScadenzaDocumento()); + xmlWriter.writeEndElement(); + + xmlWriter.writeStartElement("stato_transito"); + xmlWriter.writeCharacters(persona.getStatoTransito()); + xmlWriter.writeEndElement(); + + xmlWriter.writeEndElement(); // persona + } + + xmlWriter.writeEndElement(); // persone + xmlWriter.writeEndElement(); // giornata + } + + xmlWriter.writeEndElement(); // diario + xmlWriter.writeEndDocument(); + xmlWriter.flush(); + } catch (XMLStreamException | IOException e) { + System.out.println("Error writing the file: " + e.getMessage()); } - return; } } diff --git a/src/it/unibs/fp/patenteelibbrettopregoh/PatenteELibbrettoPregohMain.java b/src/it/unibs/fp/patenteelibbrettopregoh/PatenteELibbrettoPregohMain.java index 80ab698..89597a7 100644 --- a/src/it/unibs/fp/patenteelibbrettopregoh/PatenteELibbrettoPregohMain.java +++ b/src/it/unibs/fp/patenteelibbrettopregoh/PatenteELibbrettoPregohMain.java @@ -3,18 +3,32 @@ package it.unibs.fp.patenteelibbrettopregoh; import it.kibo.fp.lib.InputData; import java.util.ArrayList; + +/** + * PatenteELibbrettoPregohMain.java + * Questa classe rappresenta il punto di ingresso del gioco "Patente e Libretto Pregoh". + * Inizializza il gioco, gestisce il ciclo di gioco e termina il gioco. + */ public class PatenteELibbrettoPregohMain { + /** + * Metodo principale che avvia il gioco. + * + */ public static void main(String[] args) { System.out.println("PatenteELibbrettoPregoh!"); Formato formato = getFormato(); GameData gameData = new GameData(formato); - gameLoop(gameData); endGame(gameData); } + /** + * Metodo che gestisce il ciclo di gioco. + * + * @param gameData i dati di gioco + */ private static void gameLoop(GameData gameData) { while (gameData.getStatoGioco() == StatoGioco.IN_CORSO) { int personeChePassano = ((int)(Math.random() * 5) + 3); @@ -31,6 +45,12 @@ public class PatenteELibbrettoPregohMain { } } + /** + * Metodo che gestisce una persona controllata. + * + * @param gameData i dati di gioco + * @param personeControllate la lista delle persone controllate + */ private static void gestisciPersona(GameData gameData, ArrayList personeControllate) { Persona personaDaControllare = gameData.getPersonaDaControlare(); boolean esito = controllaPersona(personaDaControllare, gameData.getComuni(), gameData); @@ -50,6 +70,13 @@ public class PatenteELibbrettoPregohMain { } } + /** + * Metodo che gestisce i dati errati rifiutati. + * + * @param personaDaControllare la persona da controllare + * @param gameData i dati di gioco + * @param personeControllate la lista delle persone controllate + */ private static void datiSbagliatiRifiutati(Persona personaDaControllare, GameData gameData, ArrayList personeControllate) { System.out.println("La persona aveva i dati errati"); PersonaControllata personaControllata; @@ -61,12 +88,25 @@ public class PatenteELibbrettoPregohMain { } } + /** + * Metodo che gestisce la persona rifiutata. + * + * @param personaDaControllare la persona da controllare + * @param personeControllate la lista delle persone controllate + */ private static void personaRifiutata(Persona personaDaControllare, ArrayList personeControllate) { PersonaControllata personaControllata; personaControllata = new PersonaControllata(personaDaControllare, false, TipoPersonaControllata.PERSONA_NORMALE); personeControllate.add(personaControllata); } + /** + * Metodo che gestisce la mazzetta. + * + * @param personaDaControllare la persona da controllare + * @param gameData i dati di gioco + * @param personeControllate la lista delle persone controllate + */ private static void gestisciMazzetta(Persona personaDaControllare, GameData gameData, ArrayList personeControllate) { PersonaControllata personaControllata; int mazzetta = ((int)((Math.random() * 251))) + 250; @@ -84,12 +124,25 @@ public class PatenteELibbrettoPregohMain { } } + /** + * Metodo che gestisce la mazzetta rifiutata. + * + * @param personaDaControllare la persona da controllare + * @param personeControllate la lista delle persone controllate + */ private static void mazzettaRifiutata(Persona personaDaControllare, ArrayList personeControllate) { PersonaControllata personaControllata; personaControllata = new PersonaControllata(personaDaControllare, false, TipoPersonaControllata.PERSONA_NORMALE); personeControllate.add(personaControllata); } + /** + * Metodo che gestisce la mazzetta di un poliziotto. + * + * @param personaDaControllare la persona da controllare + * @param gameData i dati di gioco + * @param personeControllate la lista delle persone controllate + */ private static void mazzettaPoliziotto(Persona personaDaControllare, GameData gameData, ArrayList personeControllate) { PersonaControllata personaControllata; System.out.println("Hai accettato la mazzetta ... era un poliziotto"); @@ -99,6 +152,13 @@ public class PatenteELibbrettoPregohMain { personeControllate.add(personaControllata); } + /** + * Metodo che gestisce la mazzetta di un rivoluzionario. + * + * @param personaDaControllare la persona da controllare + * @param gameData i dati di gioco + * @param personeControllate la lista delle persone controllate + */ private static void mazzettaRivoluzionario(Persona personaDaControllare, GameData gameData, ArrayList personeControllate) { PersonaControllata personaControllata; System.out.println("Hai accettato la mazzetta, ti è andata bene ... era un rivoluzionario"); @@ -107,6 +167,13 @@ public class PatenteELibbrettoPregohMain { personeControllate.add(personaControllata); } + /** + * Metodo che gestisce i dati corretti rifiutati. + * + * @param personaDaControllare la persona da controllare + * @param personeControllate la lista delle persone controllate + * @param gameData i dati di gioco + */ private static void datiCorrettiRifiutati(Persona personaDaControllare, ArrayList personeControllate, GameData gameData) { System.out.println("La persona aveva i dati corretti ... come sei salato"); PersonaControllata personaControllata = new PersonaControllata(personaDaControllare, false, TipoPersonaControllata.PERSONA_NORMALE); @@ -119,6 +186,13 @@ public class PatenteELibbrettoPregohMain { } } + /** + * Metodo che gestisce i dati errati accettati. + * + * @param personaDaControllare la persona da controllare + * @param personeControllate la lista delle persone controllate + * @param gameData i dati di gioco + */ private static void datiSbagliatiAccettati(Persona personaDaControllare, ArrayList personeControllate, GameData gameData) { System.out.println("La persona aveva i dati errati"); PersonaControllata personaControllata = new PersonaControllata(personaDaControllare, true, TipoPersonaControllata.PERSONA_NORMALE); @@ -131,12 +205,23 @@ public class PatenteELibbrettoPregohMain { } } + /** + * Metodo che gestisce i dati corretti accettati. + * + * @param personaDaControllare la persona da controllare + * @param personeControllate la lista delle persone controllate + */ private static void datiCorrettiAccettati(Persona personaDaControllare, ArrayList personeControllate) { System.out.println("La persona aveva i dati corretti"); PersonaControllata personaControllata = new PersonaControllata(personaDaControllare, true, TipoPersonaControllata.PERSONA_NORMALE); personeControllate.add(personaControllata); } + /** + * Metodo che termina il gioco e mostra il risultato finale. + * + * @param gameData i dati di gioco + */ private static void endGame(GameData gameData) { gameData.saveDiario(); @@ -150,10 +235,23 @@ public class PatenteELibbrettoPregohMain { } } + /** + * Metodo che controlla se una persona ha i dati corretti. + * + * @param persona la persona da controllare + * @param comuni la lista dei comuni + * @param gameData i dati di gioco + * @return true se la persona ha i dati corretti, false altrimenti + */ private static boolean controllaPersona(Persona persona, Comuni comuni, GameData gameData) { return persona.isCodiceFiscaleValido(comuni) && persona.isDocumentoValido(gameData.getData()); } + /** + * Metodo che chiede all'utente di scegliere il formato di salvataggio. + * + * @return il formato scelto + */ private static Formato getFormato() { Formato formato = null; diff --git a/src/it/unibs/fp/patenteelibbrettopregoh/Persona.java b/src/it/unibs/fp/patenteelibbrettopregoh/Persona.java index f2014ed..18adf3e 100644 --- a/src/it/unibs/fp/patenteelibbrettopregoh/Persona.java +++ b/src/it/unibs/fp/patenteelibbrettopregoh/Persona.java @@ -1,20 +1,41 @@ package it.unibs.fp.patenteelibbrettopregoh; -import java.text.DateFormat; -import java.text.SimpleDateFormat; +import com.google.gson.annotations.SerializedName; + import java.time.LocalDate; import java.util.ArrayList; -import java.util.Date; +/** + * Classe che rappresenta una persona con i suoi dati anagrafici e il codice fiscale. + * La classe fornisce metodi per calcolare il codice fiscale e verificarne la validità. + */ public class Persona { private final String nome; private final String cognome; private final String sesso; + @SerializedName("data_nascita") // Per la serializzazione/deserializzazione JSON private final String dataNascita; + + @SerializedName("comune_nascita") // Per la serializzazione/deserializzazione JSON private final String comuneNascita; + + @SerializedName("codice_fiscale") // Per la serializzazione/deserializzazione JSON private final String codiceFiscale; + + @SerializedName("scadenza_documento") // Per la serializzazione/deserializzazione JSON private final String scadenzaDocumento; + /** + * Costruttore della classe Persona. + * + * @param nome Nome della persona. + * @param cognome Cognome della persona. + * @param sesso Sesso + * @param dataNascita Data di nascita in formato "YYYY-MM-DD". + * @param comuneNascita Comune di nascita. + * @param codiceFiscale Codice fiscale. + * @param scadenzaDocumento Data di scadenza del documento in formato "YYYY-MM-DD". + */ public Persona(String nome, String cognome, String sesso, String dataNascita, String comuneNascita, String codiceFiscale, String scadenzaDocumento) { this.nome = nome; this.cognome = cognome; @@ -25,38 +46,85 @@ public class Persona { this.scadenzaDocumento = scadenzaDocumento; } + /** + * Restituisce il nome della persona. + * + * @return Nome della persona. + */ public String getNome() { return nome; } + /** + * Restituisce il cognome della persona. + * + * @return Cognome della persona. + */ public String getCognome() { return cognome; } + /** + * Restituisce il sesso della persona. + * + * @return Sesso della persona. + */ public String getSesso() { return sesso; } + /** + * Restituisce la data di nascita della persona. + * + * @return Data di nascita della persona in formato "YYYY-MM-DD". + */ public String getDataNascita() { return dataNascita; } + /** + * Restituisce il comune di nascita della persona. + * + * @return Comune di nascita della persona. + */ public String getComuneNascita() { return comuneNascita; } + /** + * Restituisce il codice fiscale della persona. + * + * @return Codice fiscale della persona. + */ public String getCodiceFiscale() { return codiceFiscale; } + /** + * Restituisce la data di scadenza del documento della persona. + * + * @return Data di scadenza del documento in formato "YYYY-MM-DD". + */ public String getScadenzaDocumento() { return scadenzaDocumento; } + /** + * Verifica se il codice fiscale fornito è valido confrontandolo con quello calcolato. + * + * @param comuni Oggetto Comuni per ottenere il codice del comune di nascita. + * @return true se il codice fiscale è valido, false altrimenti. + */ public boolean isCodiceFiscaleValido(Comuni comuni) { return codiceFiscale.equals(calcolaCodiceFiscale(comuni)); } + /** + * Calcola il codice fiscale della persona in base ai suoi dati anagrafici. + * + * @param comuni Oggetto Comuni per ottenere il codice del comune di nascita. + * @return Il codice fiscale calcolato. + */ public String calcolaCodiceFiscale(Comuni comuni) { ArrayList consonantiCognome = getCaratteri(cognome, true); ArrayList consonantiNome = getCaratteri(nome, true); @@ -154,6 +222,13 @@ public class Persona { return codiceFiscaleCalcolato.toString(); } + /** + * Restituisce il valore numerico associato a un carattere in base alla sua posizione. + * + * @param c Carattere da convertire. + * @param b Indica se il carattere è in una posizione pari o dispari. + * @return Valore numerico associato al carattere. + */ private int getValueOf(char c, boolean b) { if (!b) { return switch (c) { @@ -194,6 +269,12 @@ public class Persona { } } + /** + * Restituisce la lettera corrispondente al mese fornito. + * + * @param mese Mese in formato numerico (1-12). + * @return Lettera corrispondente al mese. + */ private String getLetteraMese(int mese) { return switch (mese) { case 1 -> "A"; @@ -212,20 +293,45 @@ public class Persona { }; } + /** + * Verifica se il documento della persona è valido in base alla data fornita. + * + * @param date Data da confrontare con la scadenza del documento. + * @return true se il documento è valido, false altrimenti. + */ public boolean isDocumentoValido(LocalDate date) { LocalDate scadenza = LocalDate.parse(scadenzaDocumento); return date.isBefore(scadenza) || date.isEqual(scadenza); } + /** + * Verifica se il carattere fornito è una vocale. + * + * @param c Carattere da verificare. + * @return true se il carattere è una vocale, false altrimenti. + */ private static boolean isVocale(char c) { c = Character.toLowerCase(c); return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'; } + /** + * Verifica se il carattere fornito è una consonante. + * + * @param c Carattere da verificare. + * @return true se il carattere è una consonante, false altrimenti. + */ public static boolean isConsonante(char c) { return Character.isLetter(c) && !isVocale(c); } + /** + * Restituisce un ArrayList di caratteri consonanti o vocali presenti nella stringa fornita. + * + * @param s Stringa da analizzare. + * @param tipo true per consonanti, false per vocali. + * @return ArrayList di caratteri consonanti o vocali. + */ private ArrayList getCaratteri(String s, boolean tipo){ ArrayList ret = new ArrayList<>(); if (tipo){ // consonanti @@ -244,6 +350,11 @@ public class Persona { return ret; } + /** + * Restituisce una rappresentazione testuale della persona. + * + * @return Stringa contenente i dati anagrafici e il codice fiscale della persona. + */ @Override public String toString() { return nome + " " + cognome + " (" + sesso + ") nato il " + dataNascita + " a " + comuneNascita + " con C.F. " + codiceFiscale + ", validità documento " + scadenzaDocumento; diff --git a/src/it/unibs/fp/patenteelibbrettopregoh/PersonaControllata.java b/src/it/unibs/fp/patenteelibbrettopregoh/PersonaControllata.java index 3c2ac85..d52907b 100644 --- a/src/it/unibs/fp/patenteelibbrettopregoh/PersonaControllata.java +++ b/src/it/unibs/fp/patenteelibbrettopregoh/PersonaControllata.java @@ -1,27 +1,61 @@ package it.unibs.fp.patenteelibbrettopregoh; -public class PersonaControllata extends Persona { - private final boolean esitoControllo; - private final TipoPersonaControllata tipoPersonaControllata; +import com.google.gson.annotations.SerializedName; +/** + * La classe PersonaControllata estende la classe Persona e rappresenta una persona che è stata controllata. + * Contiene informazioni sul risultato del controllo e sul tipo di persona controllata. + */ +public class PersonaControllata extends Persona { + @SerializedName("approvato") + private final boolean esitoControllo; + private transient final TipoPersonaControllata tipoPersonaControllata; + + /** + * Costruttore della classe PersonaControllata. + * + * @param persona L'oggetto Persona da cui estrarre le informazioni. + * @param esitoControllo Il risultato del controllo (true se approvato, false se rifiutato). + * @param tipoPersonaControllata Il tipo di persona controllata. + */ public PersonaControllata(Persona persona, boolean esitoControllo, TipoPersonaControllata tipoPersonaControllata) { super(persona.getNome(), persona.getCognome(), persona.getSesso(), persona.getDataNascita(), persona.getComuneNascita(), persona.getCodiceFiscale(), persona.getScadenzaDocumento()); this.esitoControllo = esitoControllo; this.tipoPersonaControllata = tipoPersonaControllata; } + /** + * Restituisce il risultato del controllo. + * + * @return true se il controllo è positivo, false altrimenti. + */ public boolean isEsitoControllo() { return esitoControllo; } + /** + * Restituisce il tipo di persona controllata. + * + * @return Il tipo di persona controllata. + */ public TipoPersonaControllata getTipoPersonaControllata() { return tipoPersonaControllata; } + /** + * Restituisce lo stato del transito in base all'esito del controllo. + * + * @return "APPROVATO" se il controllo è positivo, "RIFIUTATO" altrimenti. + */ public String getStatoTransito() { return esitoControllo ? "APPROVATO" : "RIFIUTATO"; } + /** + * Restituisce una rappresentazione testuale della PersonaControllata. + * + * @return Una stringa contenente le informazioni della persona controllata. + */ @Override public String toString() { return "Nome: " + getNome() + "\n" + diff --git a/uml.png b/uml.png new file mode 100644 index 0000000..04bdfdc Binary files /dev/null and b/uml.png differ diff --git a/uml.puml b/uml.puml new file mode 100644 index 0000000..4e1eb2f --- /dev/null +++ b/uml.puml @@ -0,0 +1,149 @@ +@startuml + class Comune { + - nome: String + - codice: String + + getNome(): String + + getCodice(): String + } + + class Comuni { + - comuni: ArrayList + + addComune(Comune): void + + removeComune(Comune): void + + getComuni(): ArrayList + + getCodiceComune(String): String + } + + enum Formato { + JSON + XML + } + + enum StatoGioco { + IN_CORSO + GIUSTIZIATO + RIVOLUZIONE + DODICESIMO_GIORNO + NON_ABBASTANZA_SOLDI + ARRESTATO + } + +class PatenteELibbrettoPregohMain { + +main(String[]): void + -gameLoop(GameData): void + -gestisciPersona(GameData, ArrayList): void + -datiSbagliatiRifiutati(Persona, GameData, ArrayList): void + -personaRifiutata(Persona, ArrayList): void + -gestisciMazzetta(Persona, GameData, ArrayList): void + -mazzettaRifiutata(Persona, ArrayList): void + -mazzettaPoliziotto(Persona, GameData, ArrayList): void + -mazzettaRivoluzionario(Persona, GameData, ArrayList): void + -datiCorrettiRifiutati(Persona, ArrayList, GameData): void + -datiSbagliatiAccettati(Persona, ArrayList, GameData): void + -datiCorrettiAccettati(Persona, ArrayList): void + -endGame(GameData): void + -controllaPersona(Persona, Comuni, GameData): boolean + -getFormato(): Formato +} + +class Persona { + -nome: String + -cognome: String + -sesso: String + -dataNascita: String + -comuneNascita: String + -codiceFiscale: String + -scadenzaDocumento: String + +getNome(): String + +getCognome(): String + +getSesso(): String + +getDataNascita(): String + +getComuneNascita(): String + +getCodiceFiscale(): String + +getScadenzaDocumento(): String + +isCodiceFiscaleValido(Comuni): boolean + +calcolaCodiceFiscale(Comuni): String +} + + class GameData { + - formato: Formato + - nomePersonaggio: String + - diario: ArrayList + - comuni: Comuni + - persone: ArrayList + - saldo: double + - numeroMazzetteAccettatePolizia: int + - numeroRivoluzionariAccettati: int + - statoGioco: StatoGioco + - giorno: int + - data: LocalDate + + getDiario(): ArrayList + + getComuni(): Comuni + + getPersone(): ArrayList + + getSaldo(): double + + getPersonaDaControlare(): Persona + + getNumeroMazzetteAccettatePolizia(): int + + getNumeroRivoluzionariAccettati(): int + + addPaginaDiario(PaginaDiario): void + + addSaldo(double): void + + pagaMulta(double): void + + incrementaMazzetteAccettatePolizia(): void + + incrementaRivoluzionariAccettati(): void + + getNomePersonaggio(): String + + getStatoGioco(): StatoGioco + + getGiorno(): int + + incrementaGiorno(ArrayList): void + + getData(): LocalDate + + saveDiario(): void + } + + class PaginaDiario { + - data: String + - bilancio: double + - personeControllate: ArrayList + + getGiorno(): int + + getData(): String + + getBilancio(): double + + getPersoneControllate(): ArrayList + + addPersonaControllata(PersonaControllata): void + + removePersonaControllata(PersonaControllata): void + } + + class Parser { + + parsePersone(Formato, String): ArrayList + + parseComuni(Formato, String): Comuni + + saveDiario(String, ArrayList, Formato): void + } + +class PersonaControllata { + - esitoControllo: boolean <<@SerializedName("approvato")>> + - tipoPersonaControllata: TipoPersonaControllata <> + -- + + PersonaControllata(persona: Persona, esitoControllo: boolean, tipoPersonaControllata: TipoPersonaControllata) + + isEsitoControllo(): boolean + + getTipoPersonaControllata(): TipoPersonaControllata + + getStatoTransito(): String + + toString(): String +} + +PersonaControllata --|> Persona + + PatenteELibbrettoPregohMain --> GameData + PatenteELibbrettoPregohMain --> PersonaControllata + PatenteELibbrettoPregohMain --> Persona + PatenteELibbrettoPregohMain --> Formato + PatenteELibbrettoPregohMain --> StatoGioco + PatenteELibbrettoPregohMain --> Comuni + PatenteELibbrettoPregohMain --> Parser + Persona --> Comuni + Comune <-- Comuni + GameData --> Comuni + GameData --> "0..*" Persona + GameData --> "0..*" PaginaDiario + GameData --> Formato + GameData --> StatoGioco + + GameData --> "0..*" PersonaControllata + +} +@enduml