Jag skrev ett Hangman-textbaserat spel i Java som måste inkludera de funktioner som jag inkluderade i kommentarerna till min kod .

Kort sagt, spelet kommer att be användaren att skriva ett ord som de (eller en andra person) sedan kommer att gissa. Ordet kommer att censureras av programmet. Programmet berättar för användaren om deras gissade bokstav finns i ordet eller inte, och visar hur det censurerade ordet fortskrider efter varje gissning. Om användaren redan gissat bokstaven tidigare kommer programmet att berätta för användaren om det och visa sina tidigare gissningar utan att upprepa några bokstäver. Programmet visar antalet försök i slutet.

Koden jag skrev nedan fungerar och har alla funktioner jag listade. Men det verkar inte optimalt och förmodligen med mycket dålig etikett, eftersom jag är självlärd hittills. Jag letar därför efter råd som kommer att göra den här koden bättre och se till att jag inte kommer in i några dåliga vanor ( Jag har förmodligen redan haha) eftersom jag fortsätter att lära mig Java själv.

//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() } 

Exempel på min kod för referens om det behövs:

ange bildbeskrivning här

Svar

Några enkla ändringar:

Du skapar två skannrar , en i slingan och en dåligt namngiven i början. Jag byter namn till typedword till input och ersätt användningen av guess med input.

if(repeated == false) 

skulle vara bättre skriven

if(!repeated) 

På samma sätt ändrar jag annat om uttalanden

Jag skulle använda en Set<String> för att lagra tidigare gissningar

Jag har flyttat d deklarationen av times till !repeated loop så att dess deklaration är närmare dess användning och begränsad till dess användning.

Andra deklarationer har kopplats till värdets inställning och vissa tilldelningar kedjade såsom den nya

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

tempstring har tagits bort, den konstrueras bara nu när det behövs

ett antal variabler har döpts om för mer förklarande namn.

Slutlig kod:

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

  • ett annat förslag: Det kan vara intressant att lagra gissningen i en char istället för en sträng, men det ändrar några mindre saker i logiken …

Svar

Tack för att du delar din kod! Det ser ganska bra ut, men (som alltid) finns det några saker att fixa och se upp för:

  1. Skapa flera Scanner instanser: Inte. Du behöver bara en. Att skapa mer än en tar bara mer plats. I stället för att skapa typed word och guess, skapar du bara en som heter input eller något liknande.

  2. Avsluta din Scanners: Gör alltid så när du är klar med att använda dem, annars kommer du att få en ”Resource leak” -varning. Att stänga en Scanner gör det så att Scanner kan inte användas igen. Det är som att stänga av lamporna när du lämnar rummet, det är ingen mening att lämna dem på. Det är bara slöseri om du gör det.

  3. Använd == med booléer. I stället för ==, använd !, så här:

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

    eller

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

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *