javaloopsruntime-error

How to stop loop in my hangman program?


I'm working on a typical hangman program where I have a few words in a txt file in the command arguments. I also have another txt file with random words on it in my project files.

error/problem # 1

I'm trying to find out how I can get the game to stop when someone types in 'n' when I prompt the user to see if they want to play again. I'm thinking I need to insert a

 complete = true;

somewhere, but no clue where!

 (Guess) Enter a letter in word ***> c
 (Guess) Enter a letter in word c**> a
 (Guess) Enter a letter in word ca*> r
 The word is car , you missed 0 time(s)
 Do you want to guess another word? Enter y or n > n
 (Guess) Enter a letter in word car> 

error# 2: when I run my code, half the time it works, the other half it shows me this error message

 Exception in thread "main" java.lang.NullPointerException
   at Hangman.asteriskCover(Hangman.java:110)
   at Hangman.main(Hangman.java:63)
  Java Result: 1

Full code is below. Here is a link to an IDE http://ideone.com/hhTQZ9

 import java.io.File;
 import java.io.IOException;
 import java.util.Random;
 import java.util.Scanner;


 /**
  *
  * @author joe
  */
 public class Hangman {

public static void main(String[] args) throws IOException {

    String fileName;
    Scanner reader;
    Scanner typist;
    Random generator = new Random();
    boolean completed;
    StringBuffer asterisk;
    String guess;
    String guesses;
    char again = 'n'; 
    char lett;

    int timesMissed;

    if (args.length == 0) {
        fileName = "worden.txt";
    } else {
        fileName = args[0];
    }
    //using filename to create a new file object 
    java.io.File file = new java.io.File(fileName);

    if (!file.exists()) {
        System.err.println("Error: File " + fileName + " does not exist.");
        System.exit(1);
       }

    reader = new Scanner(file);

     String[] wordArray = new String[15];

    String word;
    int i=0;
     while (reader.hasNext()) {
        word = reader.next();
        wordArray[i] = word;
        i++;
         }

   typist = new Scanner(System.in);

    String worden = wordArray[(int) (Math.random() * wordArray.length)];
      do {            
        completed = false;
        guesses = "";
        timesMissed = 0;

        //create the asterisks 
        asterisk = asteriskCover(worden);

        while (!completed) {
            System.out.print("(Guess) Enter a letter in word " + asterisk + 
                    "> " );
            guess = typist.next();

           //if you're weird and type out the whole thing 

            if (guess.length() > 1) {
                     if (guess.equals(worden)) { 
                    System.out.println("Holy #$@%!, good job!");
                } else {
                    System.out.println("Nope, that's not it.");
                }
                completed = true;
                //if you're not weird and just guess a letter like I 
                // had originally asked you to.
            } else {
                lett = guess.charAt(0);
                guesses += lett;
                //2 lines below rep if letter isn't there and increments 
                //times missed. (hopefully)
                if (worden.indexOf(lett) < 0) {
                    timesMissed++;
                } else {
                    //my awesome method to put the asterisk in
                    rightLett(worden, asterisk, lett);
                }
                if (worden.equals(asterisk.toString())){
               System.out.println("The word is " + worden + " , you missed "
                       + timesMissed + " time(s)");
               System.out.print("Do you want to guess another word?"
                       + " Enter y or n > ");
               again = typist.next().charAt(0);

    }
    }               
    } 
    }    
    while(again == 'Y' || again == 'y');
    reader.close();
    }



public static StringBuffer asteriskCover(String a) {
    StringBuffer asterisk = new StringBuffer(a.length());
    for (int count = 0; count < a.length(); count++) {
        asterisk.append('*');
    }
    return asterisk;
}

public static void rightLett(String worden, StringBuffer asterisk, char lett) {
    for (int dex = 0; dex < worden.length(); dex++) {
        if (worden.charAt(dex) == lett) {
            asterisk.setCharAt(dex, lett);
        }
    }
 }
 }

Solution

  • The problem would seem that your stopping condition: while (again == 'Y' || again == 'y'); is outside the inner loop: while(!completed).

    To fix this, you could do something like so:

    again = typist.next().charAt(0);
    completed = true; //Add this line
    

    The above should break the inner loop (while(!completed)) and execution will proceed to the outer loop (do...while(again == 'Y' || again == 'y');).

    Shift this line: String worden = wordArray[(int) (Math.random() * wordArray.length)]; to here:

    do {
        String worden = wordArray[(int) (Math.random() * wordArray.length)];
        ...
    

    The word is not being updated since you are setting it from outside of the outer loop. That should fix it.