1

I'm trying to get Java to recognize the output of a while loop as a variable and to use that output in further operations.

I wanted to try and upgrade it by letting one player set the word and the other one guess it. The problem came from making the number of dashes equal to the number of letters in the word that the player entered, so I separated the code out, which worked.

But when I put it all back in main, it would not recognize how many dashes are there after the loop finishes; it only recognizes the initial one which is only 1 dash, and so it poses a problem.

EDIT: Thank you so much guys, its my first time on stack overflow, tnx again. Works like a charm :D

package iB;
import java.util.Scanner;
 import java.lang.String;
 public class WordGuess {
/**
 * @param args
 */
public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    String secretWord ;
    String guess, dash = "-", upWord;
    int numGuesses = 0;
    int numWord;
    final String SENTINEL = "!";
    System.out.println("Player 2, please look away.    Player 1, please enter  the secter word: \n");
    secretWord = input.next().toUpperCase().trim();
    numWord = secretWord.length();
    //System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");   
    for(int dashNum = 1; dashNum < numWord; dashNum++) {
        dash += "-" ;
    }
    System.out.println("WordGuess game!\n");
    do {
        System.out.println("Enter a letter (" + SENTINEL + "to guess entire word): ");
        guess = input.next().toUpperCase().trim();
        numGuesses ++;
      if (secretWord.contains(guess) && guess.length() == 1)    {
            upWord = dash.substring(0, secretWord.indexOf(guess));
            upWord += guess;
            upWord += dash.substring(secretWord.indexOf(guess) + 1, dash.length());
            dash = upWord.toUpperCase();
            System.out.println(dash);
            if (dash.equals(secretWord))    {
                System.out.println("You won!\n" + "The secret word is " + secretWord);
                System.out.println("You made " + numGuesses + " guesses."); }
      } else    if (guess.length() >= 2)    {
            System.out.println("Please only enter one letter at a time! \n");   }               
            if (guess.contains(SENTINEL)) {
            System.out.println("What is your guess? ");
            guess = input.next().toUpperCase().trim();
            if (guess.equals(secretWord))   {
                System.out.println("You won!\n" + "The secret word is " + secretWord);
                System.out.println("You made " + numGuesses + " guesses.");
                break;
            } else {
                System.out.println("You Lose!");
                System.out.println("The secret word was " + secretWord);
                System.out.println("You made " + numGuesses + " guesses.");
                    break;
                }
            }
        }   while(!guess.contains(SENTINEL));
        input.close();  
}

}

Supercan
  • 305
  • 1
  • 6
  • 14
  • 3
    OK there's promise here, that said - it's good to narrow done code *a little* - i.e post the code that will matter.. leave out filler code – Caffeinated Oct 12 '13 at 03:23
  • Also make sure to isolate what the problem is, instead of posting a huge amount of code. If you post a more concise amount of code, then you will receive a more accurate and timely answer. – Blue Ice Oct 12 '13 at 03:30

3 Answers3

3

The problem

The following piece of code appears to be trying to show where in a word the correctly chosen letter can be found

    if (SecretWord.indexOf(guess) >= 0) {
        UpWord = dash.substring(0, SecretWord.indexOf(guess));
        UpWord += guess;
        UpWord += dash.substring(SecretWord.indexOf(guess) + 1, dash.length());
        System.out.println(UpWord);
    } else {

So if the word was this and you guessed i then the output should be

--i-

dash.substring does not repeat dash, it takes a sub part of dash, as dash is 1 letter long, anything other than substring(0,1) will lead to an exception.

Basic solution

I believe you want to repeat dash until you get to the guessed letter, and then after it till the end of the word. Something along the lines of:

        if (SecretWord.indexOf(guess) >= 0) {
            int guessedIndex=SecretWord.indexOf(guess);

            String outString="";

            for(int i=0;i<guessedIndex;i++){
                outString+=dash; //repeat dash until we get to the correctly guessed letter
            }

            outString+=guess; //put the letter in

            for(int i=guessedIndex;i<SecretWord.length();i++){
                outString+=dash; //repeat dash until we get to end of the word
            }

            System.out.println(outString);
        } else { 

Better Solution

This however leaves the problem that only the first instance of the letter is shown. This can be solved using annother stack overflow answer in which we see that we can get all the occurances of a character using a function

public static ArrayList<Integer> getAllIndexes(String testChar, String string){
    int index=string.indexOf(testChar);


    ArrayList<Integer> indexes=new ArrayList<Integer>();
    while(index>0){
        indexes.add(index);
        index=string.indexOf(testChar,index+1);
    }

    return indexes;
}

Then using that function to find all the indexes at which the letter occurs we can deal with repeated letters

        if (SecretWord.indexOf(guess) >= 0) {
            int guessedIndex=SecretWord.indexOf(guess);

            ArrayList<Integer> indexes=getAllIndexes(guess,SecretWord);

            String outString="";

            for(int i=0;i<SecretWord.length();i++){
                if (indexes.contains(i)){ 
                    outString+=guess; //if its one of the guessed letters, put that in
                }else{
                    outString+=dash; //otherwise add a dash
                }

            }



            System.out.println(outString);
        } else {

Now a word of hello and a guess of l correctly outputs --LL-

Notes

  • It is usual to follow the naming convention that variable names are in lower camel case, meaning they start with a lower case letter, as such SecretWord should be secretWord. As it is currently written it looks like SecretWord is a class, which are usually writen in upper camel case.
  • It would be nice, if once you've guessed a letter it stops putting a dash in and starts putting the letter in every time after that, this could be achieved by using an array of booleans to check if the letter has been guessed but that is beyond the scope of this question
  • All of these solutions have appended strings, which can be slow for huge numbers, in your case this is the right thing to do, but is joining lots of strings together in a loop consider using a StringBuilder to remove the overhead of creating loads of intermediate strings
Community
  • 1
  • 1
Richard Tingle
  • 16,906
  • 5
  • 52
  • 77
2

Solution

If the secret word is pony, the String dash should be equal to ----. The problem is that you never actually change dash from being equal to -. Therefore, when you do things like dash.substring(SecretWord.indexOf(guess) + 1, dash.length()), you get errors because dash only contains one character. Here's how I'd make dash the same length as the secret word:

    for(int i = 0; i < NumWord; i++) {
        dash += "-";
    }

With this one change inserted directly before your do-while loop, your program works like a charm. Below are some other things to consider in order to further improve your program.

Improving readability

  1. Java convention dictates that the first word of method and variable names is lowercase. So NumWord should be numWord, SecretWord should be secretWord, etc.
  2. SecretWord.indexOf(guess) >= 0 should be changed to SecretWord.contains(guess)

Gameplay suggestions

  1. As in hang man, you should probably show all the spots where the guessed letter occurs. For example, if the secret word is happy, a guess of p should produce the output of --PP- instead of --P--.

  2. As a rule, never accept bad input even if it doesn't cause errors. The program shouldn't allow any of the scenarios below:

    • A user enters a String containing non-alphabetic characters or multiple words as the secret word
    • When making guesses, non-alphabetic characters are input (excluding !)
    • When guessing letters, multiple characters are input.
Joel Christophel
  • 2,604
  • 4
  • 30
  • 49
0

I have made a couple of modifications to your code, it seems to work fine now. First though, I added an extra method, just to make it a little easier:

public static String printOutWord(String[] UpWord){
    String out = "";
    for(int i = 0; i < UpWord.length; i++){
        out += UpWord[i];
    }
    return out;
}

Here are the first few changes to you code:

String[] UpWord = new String[NumWord];
    for(int i = 0; i < NumWord; i++){
        UpWord[i] = "-";
    }
printOutWord(UpWord);
System.out.println("\nWordGuess game!");

So, you no longer need the variable dash, and the variable UpWord has been changed to an array of Strings.

And this is the rest of it:

 do {
            System.out.println("Enter a letter (! to guess entire word): ");
            guess = input.next().toUpperCase().trim();
            Numguesses++;
            if(guess.length() > 1){
                System.out.println("Please only enter one letter at a time");
            }else if (SecretWord.indexOf(guess) >= 0) {
                int index = SecretWord.indexOf(guess);
                UpWord[index] = guess;
                while(SecretWord.indexOf(guess, index+1) >= index){
                    index = SecretWord.indexOf(guess, index+1);
                    System.out.println(index);
                    UpWord[index] = guess;
                }
                System.out.println(printOutWord(UpWord));
                if(printOutWord(UpWord).equals(SecretWord)){
                    System.out.println("You won!\n" + "The secret word is " + SecretWord);
                    return;
                }
            } else {
                if (guess.contains("!")) {
                    System.out.println("What is your guess? ");
                    guess = input.next().toUpperCase();
                    if (guess.equals(SecretWord)) {
                        System.out.println("You won!\n" + "The secret word is " + SecretWord);
                        System.out.println("You made " + Numguesses + " guesses");
                    } else if (!guess.equals(SecretWord)) {
                        System.out.println("You Lose!");
                        System.out.println("You made " + Numguesses + " guesses");
                    }
                }
            }
        } while (!SecretWord.equals(guess));
        input.close();
    }

Most of the changes are within the first if statement. I hope this helped, if any clarification is needed about anything, just ask, I'd be happy to help :)

Mesmetic
  • 23
  • 3