import java.util.Scanner; /** Il gioco dell'impiccato. */ public class ImpiccatoCompleto { /** * Questo è un array di stringhe. Ogni stringa contiene un disegno dell'impiccato parzialmente * completato. Deve essere utilizzato dal metodo showStatus. Java costringe a inserire queste * stringhe nel codice in maniera complessa e illegebile. Con Java 17 si può fare molto meglio e in * maniera più leggibile, ma in questo modo siamo compatibili con Java 11 che è la versione di Java * che usiamo nel nostro corso. */ static final String[] HANGMAN = { "____\n" + "|/ |\n" + "|\n" + "|\n" + "|\n" + "|\n" + "|\n" + "|_____\n" , "____\n" + "|/ |\n" + "| (_)\n" + "|\n" + "|\n" + "|\n" + "|\n" + "|_____\n" , "____\n" + "|/ |\n" + "| (_)\n" + "| |\n" + "| |\n" + "|\n" + "|\n" + "|_____\n" , "____\n" + "|/ |\n" + "| (_)\n" + "| \\|\n" + "| |\n" + "|\n" + "|\n" + "|_____\n" , "____\n" + "|/ |\n" + "| (_)\n" + "| \\|/\n" + "| |\n" + "|\n" + "|\n" + "|_____\n" , "____\n" + "|/ |\n" + "| (_)\n" + "| \\|/\n" + "| |\n" + "| /\n" + "|\n" + "|_____\n" , "____\n" + "|/ |\n" + "| (_)\n" + "| \\|/\n" + "| |\n" + "| / \\\n" + "|\n" + "|_____\n" , "____\n" + "|/ |\n" + "| (_)\n" + "| /|\\\n" + "| |\n" + "| | |\n" + "|\n" + "|_____\n" }; /** * Visualizza un messaggio diverso all'utente sulla base di quanti errori ha commesso. È * possibile utilizzare l'array HANGMAN come se fosse definito all'interno del metodo, e * visualizzare la stringa corrispondnete al valore della variabile "errors". */ public static void showStatus(int errors) { System.out.println(HANGMAN[errors]); } /** * Restituisce un array di parole. In un gioco vero dovrebbe leggere l'elenco di parole da un * file su disco. In questa versione è sufficiente restituire un array di parole prefissato. */ public static String[] readWords() { return new String[] {"amico", "teletrasporto", "amichevolmente"}; } /** * Restituisce una parola da utilizzare per il gioco. Utilizza il metodo readWords() per * ottenere l'elenco di tutte le parole ammissibili, e ne sceglie una casualmente. */ public static String chooseWord() { String[] words = readWords(); int randomPos = (int) (Math.random() * words.length); return words[randomPos]; } /** * Determina se il carattere c è presente nella parola word, e restituisce true o false a * seconda del risultato. È possibile realizzare questo metodo usando il metodo indexOf della * classe String. * https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#indexOf(int) */ public static boolean findChar(String word, char c) { for (int i = 0; i < word.length(); i++) { if (word.charAt(i) == c) return true; } return false; } /** * Se la stringa word è formata solo da caratteri che appaiono nella stringa chars, allora * restituisce true. Se anche una solo carattere di word non è presente in chars, restituisce * false. */ public static boolean foundWord(String word, String chars) { for (int i = 0; i < word.length(); i++) { if (!findChar(chars, word.charAt(i))) return false; } return true; } /** * Restiuisce una stringa ottenuta rimpiazzando tutti i caratteri in word che non si trovano in * chars con un asterisco. Ad esempio hideWord("amico","ac") resituisce "a**c*\n" + */ public static String hideWord(String word, String chars) { String result = ""; for (int i = 0; i < word.length(); i++) { if (findChar(chars, word.charAt(i))) result += word.charAt(i); else result += '*'; } return result; } /** * Legge un carattere da tastiera. Se il carattere è presente in forbiddenChars, chiede di * reinserirlo fino a che non se ne immette uno nuovo. La variabile kbd contiene un oggetto di * tipo Scanner da usare per la lettura da tastiera. */ public static char readInput(Scanner kbd, String forbiddenChars) { System.out.print("Indovina lettera: "); char c; do { c = kbd.nextLine().charAt(0); if (findChar(forbiddenChars, c)) { System.out.print("Hai già provato con questa lettera, scegline un'altra: "); } } while (findChar(forbiddenChars, c)); return c; } /** * Programma principale. */ public static void main(String[] args) { // Visualizza un banner di instestazione System.out.println("L'IMPICCATO CLEII"); // Inizializzo la variabile kbd di tipo Scanner Scanner kbd = new Scanner(System.in); // Scelgo la parola da far indovinare String word = chooseWord(); // La variabile attempts è una stringa che conterrà tutti i caratteri immessi dal giocatore. String attempts = ""; // La variabile errors conta il numero di errori commessi int errors = 0; // La variabile found è true quando il giocatore ha trovato tutte le lettere della parola // misteriosa. boolean found = false; // Se il numero di errori commessi è inferiore a 7 e la parola non è stata ancora trovata, // ripete il ciclo. while (errors < 7 && !found) { // Visualizza lo stato dell'impiccato showStatus(errors); // Visualizza la parola misteriosa con le lettere individuate in chiaro System.out.print("Parola da indovidare: "); System.out.println(hideWord(word, attempts)); // Legge un carattere da tastiera, evitando i duplicati char c = readInput(kbd, attempts); // Aggiungere il carattere alla stringa attemps attempts += c; if (findChar(word, c)) { // Se il carattere c si trova nella stringa word, aggiorna la variabile found, nel // caso il giocatore abbia individuato tutte le lettere. found = foundWord(word, attempts); } else { // Altrimenti incrementa il nunero di errori. System.out.println("*** LA LETTERA NON È PRESENTE NELLA PAROLA ***"); errors += 1; } } if (found) { // Se siamo usciti dal ciclo perché la parola è stata trovata, visualizza un messaggio // di congratulazioni. System.out.println("Congratulazioni, hai vinto"); } else { // Altrimenti visualizza lo stato dell'impiccato e un messaggio di errore. showStatus(errors); System.out.println("Mi dispiace, hai perso"); } kbd.close(); } }