Jai écrit un jeu textuel du pendu en Java qui doit inclure les fonctionnalités que jai incluses dans les commentaires de mon code .
En bref, le jeu demandera à lutilisateur de taper un mot quil (ou une deuxième personne) devinera ensuite. Le mot sera censuré par le programme. Le programme dira à lutilisateur si sa lettre devinée est dans le mot ou non, et montrera la progression du mot censuré après chaque estimation. Si lutilisateur a déjà deviné la lettre avant, le programme en informera lutilisateur et montrera ses suppositions précédentes sans répéter aucune lettre. Le programme affichera le nombre de tentatives à la fin.
Le code que jai écrit ci-dessous fonctionne et possède toutes les fonctionnalités que jai énumérées. Mais cela ne semble pas optimal et probablement avec une étiquette très médiocre, car je suis autodidacte jusquà présent. Par conséquent, je suis à la recherche de conseils qui amélioreront ce code et massurer de ne pas prendre de mauvaises habitudes ( Jai probablement déjà haha) car je continue à apprendre Java par moi-même.
//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() }
Exemple de sortie de mon code pour référence si nécessaire:
Réponse
Quelques changements simples:
Vous créez deux scanners , un dans la boucle et un mal nommé au début. Je renomme le typedword
à input
et remplacer les utilisations de guess
par input
.
if(repeated == false)
serait mieux écrit
if(!repeated)
De même, je modifie autre si instructions
Jutiliserais un Set<String>
pour stocker les suppositions passées
Jai déménagé d la déclaration de times
à lintérieur de !repeated loop
afin que sa déclaration soit plus proche de son utilisation et limitée dans sa portée à son utilisation.
Dautres déclarations ont été jointes au paramétrage de la valeur, et certaines affectations enchaînées comme la nouvelle
String wordToGuess = input.nextLine().toUpperCase();
tempstring
a été supprimé, il nest construit que lorsque cela est nécessaire
un certain nombre de variables ont été renommées pour des noms plus explicatifs.
Code final:
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!"); } }
Commentaires
Réponse
Merci davoir partagé votre code! Cela semble plutôt bien, mais (comme toujours) il y a des choses à corriger et à rechercher:
-
Création de plusieurs instances
Scanner
: Don « t. Vous nen avez besoin que dun seul. En créer plusieurs prend simplement plus despace. Plutôt que de créertyped word
etguess
, créez simplement un appeléinput
ou quelque chose comme ça. -
Clôture de votre
Scanners
: Toujours faire Ainsi, lorsque vous aurez fini de les utiliser, vous obtiendrez un avertissement « Fuite de ressources ». La fermeture dunScanner
fait en sorte que leScanner
ne peut plus être utilisé. Cest comme éteindre les lumières lorsque vous quittez la pièce, il ne sert à rien de les laisser allumées. Cest juste un gaspillage si vous le faites. -
Utilisation de
==
avec des booléens. Au lieu de==
, utilisez!
, comme ceci:if(condition) { //if "condition" is true.
ou
if(!condition) { //if "condition" is false
char
au lieu dune chaîne, mais cela change quelques petites choses dans la logique …