3
\$\begingroup\$

It's a simple word guessing game. The game picks a random word - you guess a letter until it's correct, the game automatically starts a new one.

Is my code readable? Am I doing anything that could be simplified? Am I doing the right thing by using only one class besides Main?

import java.util.Scanner; 
import java.util.Random;


class Word {
  private String censoredWord = "";
  private String word = "";
  private String[] words = {"cow", "giraffe", "deer", "cat", "dog",   "cheese"}; ////words

  public String randomizeWord() { //randomizes word
      Random rand = new Random();
      int randNum = rand.nextInt(words.length);
      word = words[randNum];
      for (int i = 0; i < word.length(); i++) { //makes a word filled with blank spots the same length as the word chosen
        censoredWord = censoredWord + "_";
      }
      return word;
  }

  public String showProgress(char letter) { //uncensors letters
    char[] wordArray = word.toCharArray(); //sets the word to an array so it can loop though it
    char[] censoredWordArray = censoredWord.toCharArray();
    for (int i = 0; i < wordArray.length; i++) {
      char ichar = wordArray[i];
      if (letter == ichar) { 
        censoredWordArray[i] = ichar; //fills in censored letter
      }
    }
    censoredWord = String.valueOf(censoredWordArray);
    System.out.println(censoredWord);
    return censoredWord;
  }
}

class Main {
  public static void main(String[] args) {
    Word word = new Word();
    String currentWord = word.randomizeWord(); 
    while (true) { //handles the game structure and guessing
      System.out.println("Guess!");
      Scanner guessLetter = new Scanner(System.in); //takes input
      char letterGuessed = guessLetter.nextLine().charAt(0); //puts input into variable
      //checks if user got the word
      guessLetter.close();
      if (word.showProgress(letterGuessed).equals(currentWord)) { 
        System.out.println("Hooray! Resetting...");
        word = new Word();
        currentWord = word.randomizeWord();
      }
    }
  }
}
```
\$\endgroup\$
1
\$\begingroup\$

Performance

You create a new Scanner for every guess. this is unnecessary. the same scanner can be used to read all user input. the scanner should be closed only at the end of the program. and if you adopt that, you can also use Java 7 try-with-resources feature. it is a safe(r) way to open and process external resources.

JDK library features

  1. in order to fill an array with the same character, you can use Arrays.fill() method: Arrays.fill(censoredWordArray, '_'); and you do not need to keep the String representation of the array, just print the string value to the user. However, FYI, Java 11 gives us String::repeat to fill a String with one character: String censoredWord = "_".repeat(word.length());

  2. I assume this is CS course homework, so I do not know if this comment is applicable. However, Java 8 (which has been around for over 5 years) gave us stream processing of collections, which, compared to for loops, is a more expressive (and sometimes performant) way to iterate over collections and arrays. for example, the loop in showProgress can be re-written like this

    IntStream.range(0, wordArray.length)
        .filter(i -> wordArray[i] == letter)
        .findFirst()
        .ifPresent(i -> censoredWordArray[i] = letter);
    

Best practices

Avoid magic numbers and literals: private static final String EMPTY_LETTER = "_";
not only it makes the code more readable, it will eliminate typo bugs in case you need to specify the literal in multiple places in the code.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.