Jeg skrev et Hangman-tekstbasert spill i Java som må inkludere funksjonene jeg inkluderte i kommentarene til koden min .
Kort sagt, spillet vil be brukeren om å skrive et ord som de (eller en 2. person) vil gjette. Ordet vil bli sensurert av programmet. Programmet vil fortelle brukeren om deres gjettede bokstav er i ordet eller ikke, og viser fremdriften til det sensurerte ordet etter hvert gjetning. Hvis brukeren allerede gjettet brevet før, vil programmet fortelle brukeren om det og vise sine tidligere gjetninger uten å gjenta noen bokstaver. Programmet viser antall forsøk på slutten.
Koden jeg skrev nedenfor fungerer og har alle funksjonene jeg har oppført. Men det virker ikke optimalt og sannsynligvis med veldig dårlig etikette, ettersom jeg er selvlært så langt. Derfor leter jeg etter noen råd som vil gjøre denne koden bedre og for å sikre at jeg ikke kommer inn på noen dårlige vaner ( Jeg har sannsynligvis allerede haha) da jeg fortsetter å lære Java alene.
//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() }
Eksempel på utdata av koden min for referanse hvis nødvendig:
Svar
Noen enkle endringer:
Du oppretter to skannere , en inne i sløyfen og en dårlig navngitt i starten. Jeg omdøper typedword
til input
og erstatt bruk av guess
med input
.
if(repeated == false)
ville vært bedre skrevet
if(!repeated)
Tilsvarende endrer jeg andre hvis uttalelser
Jeg vil bruke en Set<String>
for å lagre tidligere gjetninger
Jeg har flyttet d erklæringen om times
til !repeated loop
slik at erklæringen er nærmere bruken, og begrenset i omfang til bruken.
Andre erklæringer er knyttet til innstillingen av verdien, og noen oppgaver lenket som den nye
String wordToGuess = input.nextLine().toUpperCase();
tempstring
er fjernet, den er bare konstruert nå når det er nødvendig
et antall variabler har blitt omdøpt for mer forklarende navn.
Endelig kode:
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!"); } }
Kommentarer
Svar
Takk for at du delte koden din! Det ser ganske bra ut, men (som alltid) er det noen ting å fikse og se etter:
-
Opprette flere
Scanner
forekomster: Ikke «t. Du trenger bare en. Å lage mer enn en tar bare mer plass. I stedet for å opprettetyped word
ogguess
, er det bare å opprette en som heterinput
eller noe sånt. -
Lukker
Scanners
: Gjør det alltid så når du er ferdig med å bruke dem, ellers vil du få en «Ressurslekkasje» -varsel. Å lukke enScanner
gjør det slik atScanner
kan ikke brukes igjen. Det er som å slå av lysene når du forlater rommet, det er ingen vits i å la dem være på. Det er bare bortkastet hvis du gjør det. -
Bruk av
==
med booleans. I stedet for==
, bruk!
, slik:if(condition) { //if "condition" is true.
eller
if(!condition) { //if "condition" is false
char
i stedet for en streng, men det endrer noen mindre ting i logikken …