3
\$\begingroup\$

This works for the most part. I am very new to programming so be aware.

import java.util.*;
public class HangManP5 
{
private static Scanner k;
public static void main(String[] args) 
{
int attempts = 10;
int wordLength;
boolean solved;
k = new Scanner(System.in);

System.out.println("Hey, what's your name?");
String name = k.nextLine();
System.out.println(name+ ", hey! This is a hangman game! (Some answers have two words, usually the longer ones\n");
String word = getRandomWord();
int len = word.length(); 
char[] temp = new char[len];
for(int i = 0; i < temp.length; i++)
{
    temp[i] = '*';
}
System.out.print("\n");
System.out.print("Word to date: "+len+" letters.");
while (attempts <= 10 && attempts > 0)
{
    System.out.println("\nAttempts left: " + attempts);
    System.out.print("Enter letter: ");
    String test = k.next();
    if(test.length() != 1) 
    {
        System.out.println("Please enter 1 character");
        continue;
    }
    char testChar = test.charAt(0);
    int foundPos = -2;
    int foundCount = 0;
    while((foundPos = word.indexOf(testChar, foundPos + 1)) != -1)
    {
        temp[foundPos] = testChar;
        foundCount++;
        len--;
    }
    if(foundCount == 0)
    {
        System.out.println("Sorry, didn't find any matches for " + test);
    }
    else
    {
        System.out.println("Found " + foundCount + " matches for " + test);
    }
    for(int i = 0; i < temp.length; i++)
    {
        System.out.print(temp[i]);
    }
    System.out.println();
    if(len == 0)
    {
        break; //Solved!
    }
    attempts--;
}
if(len == 0)
{
    System.out.println("\n---------------------------");
    System.out.println("You did iiiiiiit!");
}
else
{
    System.out.println("\n---------------------------");
    System.out.println("Better luck next time, you didn't get the word!");
    System.out.println("It was \"" + word + "\"");
}
}
public static String getRandomWord() 
{
    switch(new Random().nextInt(5)) 
    {
        case 1:
            return "peace";
        case 2:
            return "nuts";
        case 3:
            return "dankmemes";
        case 4:
            return "fizz";
        case 5:
            return "awesome"; 
        default:
            throw new IllegalStateException("Something went wrong!");
    }
}
}
\$\endgroup\$
2
  • 2
    \$\begingroup\$ "This works for the most part." This makes it seem like something is not working, which is confusing. Please clarify. \$\endgroup\$ Jan 12, 2015 at 4:24
  • 1
    \$\begingroup\$ In this case, it works well enough for the code to be reviewed. \$\endgroup\$ Jan 12, 2015 at 6:52

1 Answer 1

5
\$\begingroup\$

This program is not bad, for a beginner. You split the getRandomWord() routine into its own function, which is good. You should do much more of that, though, as your main() is too long to follow at a glance.

The getRandomWord() function has a serious bug arising from your misuse of Random.nextInt(int n). Possible outputs from that call are 0, 1, 2, 3, 4. Therefore, it will never choose "awesome", and it may throw an IllegalStateException. I don't recommend using a switch statement for that purpose, though, because the vocabulary list should be treated as data, not as code. It would be better to pick a random element from an array of strings.

You also have a logic bug that lets the user "win" by guessing the same correct letter again and again. For example, if the word is "fizz", and the user guesses 'z', then you record the fact that there are two blanks remaining. If the user guesses 'z' again, you report a win. (You really ought to handle duplicate guesses better, but at the least you should prevent such erroneous wins.)

A block of variable declarations at the top of your main() function is unfriendly — nobody likes reading those. Instead, declare your variables as close to the point of use as possible. In fact, within your block of declarations are two unused variables wordLength and solved that you yourself lost track of.

Pick variable names that make sense — not just to you but to any programmer who might come along. Instead of k (short for "keyboard"?), pick input (and initialize it immediately). Instead of temp (which isn't temporary, so it must mean "template"?), try wordDisplay.

Suggested implementation

This is mostly just a result of

  • refactoring your main() code into functions
  • renaming variables for clarity
  • writing some loops a bit more eloquently
import java.util.*;

public class HangMan {
    private static final String[] VOCABULARY = new String[] {
        "peace", "nuts", "dankmemes", "fizz", "awesome"
    };

    private static Scanner input = new Scanner(System.in);

    private static void intro() {
        System.out.println("Hey, what's your name?");
        String name = input.nextLine();
        System.out.println(name+ ", hey! This is a hangman game! (Some answers have two words, usually the longer ones)\n");
    }

    /**
     * Picks a word at random from the vocabulary.
     */
    public static String getRandomWord() {
        return VOCABULARY[new Random().nextInt(VOCABULARY.length)];
    }

    /**
     * Makes an array of placeholder characters the same length as the word.
     */
    private static char[] initWordDisplay(String word) {
        char[] wordDisplay = new char[word.length()];
        Arrays.fill(wordDisplay, '*');
        return wordDisplay;
    }

    /**
     * Prompts the user to enter a single-character guess (repeatedly
     * if necessary in case of errors).
     */
    private static char promptGuess() {
        do {
            System.out.print("Enter letter: ");
            String s = input.next();
            if (s.length() == 1)  {
                return s.charAt(0);
            }
            System.out.println("Please enter 1 character");
        } while (true);
    }

    /**
     * Fills <code>wordDisplay</code> with the guess, returning the
     * number of blanks correctly filled as a result.
     */
    private static int fillGuess(String word, char[] wordDisplay, char guess) {
        int foundCount = 0;
        for (int pos = 0; (pos = word.indexOf(guess, pos)) != -1; pos++) {
            if (wordDisplay[pos] != guess) {   // Prevent repeat guess
                wordDisplay[pos] = guess;
                foundCount++;
            }
        }
        return foundCount;
    }

    public static void main(String[] args) {
        intro();

        String word = getRandomWord();
        char[] wordDisplay = initWordDisplay(word);
        int blanksLeft = wordDisplay.length;

        System.out.print("\nWord to date: " + blanksLeft + " letters.");

        for (int attemptsLeft = 10; blanksLeft > 0 && attemptsLeft > 0; attemptsLeft--) {
            System.out.println("\nAttempts left: " + attemptsLeft);
            char guess = promptGuess();
            int foundCount = fillGuess(word, wordDisplay, guess);
            blanksLeft -= foundCount;

            if (foundCount == 0) {
                System.out.println("Sorry, didn't find any matches for " + guess);
            } else {
                System.out.println("Found " + foundCount + " matches for " + guess);
            }
            System.out.println(new String(wordDisplay));
        }

        if (blanksLeft == 0) {
            System.out.println("\n---------------------------");
            System.out.println("You did iiiiiiit!");
        } else {
            System.out.println("\n---------------------------");
            System.out.println("Better luck next time, you didn't get the word!");
            System.out.println("It was \"" + word + "\"");
        }
    }
}
\$\endgroup\$
0

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.