Search code examples
javaeclipsenew-operator

Beginning CS student trying to make a hangman game in java


So I kinda got the code to do what I want it to do.

Take in an user inputted char compare it to each char in a random array if they equal each other save the location of when they equal each other to a variable Save the character that was correctly guessed to a blank char array in the same location. repeat...

The problem I am having is when looping, the program loops 3 times instead of just asking for another input after first loop.

***Ex.(What code prints):***
Enter A letter: 
a
[a, , , , ]
Enter A letter:
[a, , , , ]
Enter A letter:
[a, , , , ]
Enter A letter:

**Ex.(What I would like code to print)***
Enter A letter:
a
[a, , , , ]
Enter A letter:
p
[a, p, p, , ]

String[] str = {"apple", "apple"};
int attempts = 0;

String randStr = str[rand.nextInt(str.length)];
    
    char [] ans = randStr.toCharArray();
    char [] guess = new char[ans.length];

while(attempts<=10){
    System.out.println("Enter A letter: ");
    char userAns = (char) System.in.read();
    
    for(int i = 0;i<ans.length;i++) 
    {
        if(ans[i]==userAns) 
        {
            int loc = i;
            guess[loc] = ans[loc];
            correct++;
        }
    }
    attempts++;
    System.out.println(Arrays.toString(guess)); 
}

Solution

  • The problem you have lies with the use of System.in.read(). You think you're reading one character, but you're actually getting more. You type 'a' and then you hit [Enter]. What's actually happening is that the [Enter] key is generating two additional non-printing chars: \r (carriage return) and '\n' (newline), which is standard behavior for Windows. System.in.read() doesn't specifically read the next char, but rather, the next byte of data, whatever that may be. What looks like two extra iterations of the loop is actually the call to read() consuming the two characters created by pressing [Enter].

    The easiest fix for this problem is to use the Scanner class to read input, which is pretty much standard for reading user data from console.

    You want to import Scanner, create an instance of Scanner and then use it to take a String from the user. Then use String.charAt() to get the first char from whatever String the user enters (because there's no direct way to read char type input from Scanner).

    import java.util.Arrays;
    import java.util.Random;
    import java.util.Scanner;
    
    public class Test
    {
      public static void main(String[] args)
      {
        Random rand = new Random();
        String[] str = {"apples", "apples"};
        int attempts = 0;
        int correct = 0;
    // New code (one line)
        Scanner scanner = new Scanner(System.in);
    
        String randStr = str[rand.nextInt(str.length)];
    
        char userAns = '\0';
        char [] ans = randStr.toCharArray();
        char [] guess = new char[ans.length];
    
        while(attempts < 10)
        {
            System.out.println("Enter A letter: ");
    // New code (one line)
            userAns = (scanner.nextLine()).charAt(0);
    
            for(int i = 0; i < ans.length; i++)
            {
                if(ans[i] == userAns)
                {
                    int loc = i;
                    guess[loc] = ans[loc];
                    correct++;
                }
            }
            attempts++;
    
            System.out.println(Arrays.toString(guess));
        }
      }
    }
    

    If you can't use Scanner (because your instructor hasn't introduced it), well... welcome to Kludgeville. You're going to need to read the extraneous non-printing characters and throw them away silently.

    Instead of:

    char userAns = (char) System.in.read();
    

    you'll do:

    char userAns = (char) System.in.read();
    char garbage = (char) System.in.read();
    char trash = (char) System.in.read();
    

    You also need to fix the fact that your program never ends, even after the user guesses the correct word. HINT: fix it by altering the condition of your while loop to detect when correct is equal to the number of characters in the answer. There are more elegant ways to address that problem, but that approach will work OK for your purposes.