Ho scritto un gioco di testo dellimpiccato in Java che deve includere le funzionalità che ho incluso nei commenti del mio codice .

In breve, il gioco chiederà allutente di digitare una parola che lui (o una seconda persona) indovinerà. La parola sarà censurata dal programma. Il programma dirà allutente se la lettera indovinata è nella parola o meno e mostrerà lavanzamento della parola censurata dopo ogni ipotesi. Se lutente ha già indovinato la lettera prima, il programma lo dirà allutente e mostrerà le sue ipotesi precedenti senza ripetere alcuna lettera. Il programma mostrerà il numero di tentativi alla fine.

Il codice che ho scritto di seguito funziona e ha tutte le caratteristiche che ho elencato. Ma non sembra ottimale e probabilmente con un galateo molto povero, dato che sono autodidatta fino ad ora. Pertanto, sto cercando qualche consiglio che renderà questo codice migliore e per assicurarmi di non prendere cattive abitudini ( Probabilmente ho già ahah) poiché continuo a imparare Java da solo.

//Simple Hangman game where user types a word, program stores it in all CAPS for easier user readability and censors the word (i.e *****) //User then guesses one letter at a time until the entire word is guessed. Program will inform the user if the guess is in the word, and show the progress of the word after each guess. //If the guessed letter is in the word, program will print out the # of times the letter is in the word. //Program will store and print out # of guesses (attempts) needed to guess the word at the end of the program. //If user tries to duplicate a previous guess, program will inform user of that and show previous guesses by user. Attempt count will not go up for duplicate guesses. //When the program shows previous guesses by the user (using a string), it cannot contain duplicate letters. (i.e: if user guesses "s" twice, "s" will still only show up once in the string) //StackOverFlow readers: This program works as intended, but as a self-taught beginner coder, I need assistance on optimal coding style (less lines the better) and good coding principles/etiquette //I definitely think there are much better ways to code this, but I cannot think of any more (as you probably noticed, this is v3, which has more features and yet similar amount of lines as version 1 haha) //All and any help is appreciated! Thank you :D import java.util.*; public class HangmanGameV3 { public static void main(String [] args){ //Initialize all the variables used here String storedword; char[] charstring; int length; char[] censor; int attempts=0; StringBuilder pastguesses = new StringBuilder(); //String Builder to add and print out previous guesses Scanner typedword = new Scanner(System.in); System.out.println("Enter your word to guess: "); storedword = typedword.nextLine(); storedword = storedword.toUpperCase(); //stores the word and changes it to all caps length = storedword.length(); charstring = storedword.toCharArray(); //creates char array of string //creates and prints an array of chars with the same length as string censor = storedword.toCharArray(); System.out.println("Your secret word is: "); for (int index = 0; index < length; index++){ censor[index] = "*"; } //Main loop to take guesses (is this while loop the ideal loop here? while (String.valueOf(censor).equals(storedword)== false){ //Initialize all variables in loop char charguess; String tempword; String tempstring; boolean correct = false; //required for if loops below/lets the user know if the letter is in the word or not int times = 0; //number of times a letter is in the word boolean repeated = false; //check if user guessed the same letter twice //prints the censored secret word for(int a= 0; a < length; a++){ System.out.print(censor[a]); } System.out.println(); //asks user for guess, then stores guess in Char charguess and String tempstring Scanner guess = new Scanner(System.in); System.out.println("Type your guess: "); tempword = guess.next(); charguess = tempword.charAt(0); //gets char data from scanner pastguesses.append(charguess); //adds guess to previous guess string tempstring = pastguesses.toString(); //checks if user already guessed the letter previously if (tempstring.lastIndexOf(charguess, tempstring.length() -2 ) != -1){ System.out.println("You already guessed this letter! Guess again. Your previous guesses were: "); pastguesses.deleteCharAt(tempstring.length()-1); System.out.println(tempstring.substring(0, tempstring.length()-1)); repeated = true; } //if the guess is not a duplicated guess, checks if the guessed letter is in the word if (repeated == false){ for (int index = 0; index < length; index++){ if(charstring[index] == Character.toUpperCase(charguess)) { censor[index] = Character.toUpperCase(charguess); //replaces * with guessed letter in caps correct = true; times++; } } if(correct == true){ System.out.println("The letter " + charguess + " is in the secret word! There are " + times +" " + charguess + " "s in the word. Revealing the letter(s): "); } else if (correct == false){ System.out.println("Sorry, the letter is not in the word. Your secret word: "); } System.out.println(); } attempts++; } System.out.println("You guessed the entire word "+ storedword.toUpperCase() + " correctly! It took you " + attempts + " attempts!"); //typedword.close(); //StackOverFlow readers: is this necessary? Not sure how to use .close() } 

Esempio di output del mio codice come riferimento, se necessario:

inserisci qui la descrizione dellimmagine

Risposta

Alcune semplici modifiche:

Crei due scanner , uno allinterno del ciclo e uno mal chiamato allinizio. Rinomino il typedword a input e sostituire gli usi di guess con input.

if(repeated == false) 

sarebbe meglio scrivere

if(!repeated) 

Allo stesso modo modifico altro se istruzioni

Vorrei utilizzare un Set<String> per memorizzare le ipotesi passate

Mi sono trasferito d la dichiarazione di times allinterno di !repeated loop in modo che la sua dichiarazione sia più vicina al suo utilizzo e limitata nellambito del suo utilizzo.

Altre dichiarazioni sono state unite allimpostazione del valore e alcune assegnazioni concatenate come il nuovo

String wordToGuess = input.nextLine().toUpperCase(); 

tempstring è stato rimosso, viene costruito solo ora quando necessario

un certo numero di variabili è stato rinominato per nomi più esplicativi.

Codice finale:

import java.util.HashSet; import java.util.Scanner; import java.util.Set; public class HangmanGameV3 { public static void main(String[] args) { int attempts = 0; Set<String> previousGuesses = new HashSet<>(); Scanner input = new Scanner(System.in); System.out.println("Enter your word to guess: "); String wordToGuess = input.nextLine().toUpperCase(); int length = wordToGuess.length(); char[] wordToGuessChars = wordToGuess.toCharArray(); //creates char array of string //creates and prints an array of chars with the same length as string char[] censor = wordToGuess.toCharArray(); System.out.println("Your secret word is: "); for (int index = 0; index < length; index++) { censor[index] = "*"; } //Main loop to take guesses (is this while loop the ideal loop here? while (!String.valueOf(censor).equals(wordToGuess)) { //Initialize all variables in loop boolean correct = false; //required for if loops below/lets the user know if the letter is in the word or not boolean repeated = false; //check if user guessed the same letter twice //prints the censored secret word for (int a = 0; a < length; a++) { System.out.print(censor[a]); } System.out.println(); //asks user for guess, then stores guess in Char charguess and String tempstring System.out.println("Type your guess: "); String currentGuess = input.next().toUpperCase().substring(0, 1); char currentGuessChar = currentGuess.charAt(0); //gets char data from scanner //checks if user already guessed the letter previously if (previousGuesses.contains(currentGuess)) { System.out.println("You already guessed this letter! Guess again. Your previous guesses were: "); System.out.println(previousGuesses.stream().reduce("", String::concat)); repeated = true; } previousGuesses.add(currentGuess); //if the guess is not a duplicated guess, checks if the guessed letter is in the word if (!repeated) { int times = 0; //number of times a letter is in the word for (int index = 0; index < length; index++) { if (wordToGuessChars[index] == currentGuessChar) { censor[index] = currentGuessChar; //replaces * with guessed letter in caps correct = true; times++; } } if (correct) { System.out.println("The letter " + currentGuessChar + " is in the secret word! There are " + times + " " + currentGuessChar + " "s in the word. Revealing the letter(s): "); } else { System.out.println("Sorry, the letter is not in the word. Your secret word: "); } System.out.println(); } attempts++; } System.out.println("You guessed the entire word " + wordToGuess.toUpperCase() + " correctly! It took you " + attempts + " attempts!"); } } 

Commenti

  • un altro suggerimento: potrebbe essere interessante memorizzare lipotesi in un char invece di una stringa, ma questo cambia alcune cose minori nella logica …

Risposta

Grazie per aver condiviso il tuo codice! Sembra abbastanza buono, ma (come sempre) ci sono alcune cose da sistemare e tenere docchio:

  1. Creazione di più istanze Scanner: Non “t. Ne hai solo bisogno. La creazione di più di una richiede solo più spazio. Invece di creare typed word e guess, crea uno chiamato input o qualcosa del genere.

  2. Chiusura di Scanners: fai sempre quindi quando hai finito di utilizzarli, altrimenti riceverai un avviso “Perdita di risorse”. La chiusura di un Scanner fa in modo che Scanner non può essere riutilizzato. È come spegnere le luci quando esci dalla stanza, non ha senso lasciarle accese. È solo uno spreco se lo fai.

  3. Utilizzo di == con valori booleani. Invece di ==, utilizza !, in questo modo:

    if(condition) { //if "condition" is true. 

    o

    if(!condition) { //if "condition" is false 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *