Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 5 of 5

Thread: Hangman Program Java: Comparing the User's Guess with Another String Letter by Letter

  1. #1
    Junior Member
    Join Date
    Jun 2013
    Posts
    9
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Question Hangman Program Java: Comparing the User's Guess with Another String Letter by Letter

    I'm making a Hangman program to test my knowledge of GUI's. However my program is not checking letters correctly. This is my code for a Field Listener that checks the user's input with the word. I'm not posting all of the code because it is not all relevant to the issue and is working fine. The field listener is called after the user inputs text and presses the enter key. The object word.letters is a random String from a dictionary file. My problem has two parts: if the user inputs a correct letter the for loop never runs and the letter is instead counted as wrong in the else statement. My second problem is that if the user inputs the correct word it doesn't say it is correct instead it says it is an invalid guess. I hope this is enough.

    The listener does handle invalid guesses correctly and wrong letters (but counts right letters as wrong).

    class fieldListener implements ActionListener {
         @Override
         public void actionPerformed(ActionEvent ae) {
             if (guesses > 0) {
                String guess = field.getText(); //gets the text from field
                if (guess.length() == 1 && gc.contains(guess) == false && Arrays.asList(word.letters.toCharArray()).contains(guess)) { //if the guess is one letter long and is not found in the ArrayList gc containing guessed letters and word.letters contains the letter
                    for (int i = 0; i < word.letters.length(); i++) { //for every letter in word.letters
                        String str = ""; //this represents a JLabel that uses underscores for every letter of word.letters
                        if (guess.equals(word.letters.charAt(i) + "")) { //if one letter is equal
                            str += guess + " "; //change the underscore to the letter
                            word.flags[i] = true; //set that letters flag to true meaning it has been found
                            area.setText("You guessed a correct letter."); //print the result
                            gc.addElement(guess); //add the letter to the found list
                            list = new JList(gc); //refresh the JList
                            field.setText(""); //empty the guess field
                        }
                        else if (word.flags[i] == true){ //otherwise if that letters flag is true
                            str += word.letters.charAt(i) + " "; //add the letter to the label
                        }
                        else {
                            str += "_ "; //otherwise add an underscore representing no found letter
                        }
                        t.setText(str); //set the label to the value of str
                    }
                }
                else if (guess.equals(word.letters)) {
                    win(); //if the guess equals the random word execute the win function
                    list = new JList(gc); //update the JList
                    field.setText(""); //empty field
                }
                else if (guess.length() > 1 && (guess.length() < word.letters.length() || guess.length() > word.letters.length())) {
                    area.setText("Only guess letters or the entire word."); //if the guess is not one letter or the length of the word tell the user he made an invalid guess
                    field.setText(""); //empty
                }
                else if (gc.contains(guess)) { //self explanatory
                    area.setText("You already guessed that.");
                    field.setText("");
                }
                else { //if its a wrong letter or wrong word
                    guesses--; //decrement the guesses
                    gc.addElement(guess.toLowerCase()); //add the word/letter to the scroller 
                    area.setText("Wrong, guess another letter or the word."); //result
                    list = new JList(gc); //update list
                    f.repaint(); //repaint the frame to add the next body part
                    field.setText("");
                }
     
                if (!Arrays.asList(word.flags).contains(false)) {
                    win(); //if there are no more false flags left execute win
                }
             }
             if (guesses == 0) {
                 lose(); //if guesses = 0 execute lose
             }
         }
    }


  2. #2
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    987
    Thanks
    6
    Thanked 206 Times in 182 Posts

    Default Re: Hangman Program Java: Comparing the User's Guess with Another String Letter by Letter

    Hi theonlydvr, welcome to the forums!

    if the user inputs a correct letter the for loop never runs
    Arrays.asList(word.letters.toCharArray()).contains(guess)

    Assuming that word.letters is a String, it seems to me that this expression will never be true. toCharArray() returns an array of char and asList() will produce some sort of List whose members are of the Character type. This list will never contain guess because guess is declared as a String not a Character or char.

    if the user inputs the correct word it doesn't say it is correct
    I have no idea why "guess.equals(word.letters)" doesn't evaluate to true. Presumably it is because of how you declared words.letters and what values you assigned to it in the code you haven't posted. You could print the two strings to System.out at some point to check what's going on.

    @Override
    public void actionPerformed(ActionEvent ae) {
        if (guesses > 0) {
            String guess = field.getText(); //gets the text from field
            System.out.println("At field listener actionPerformed() guesses=" + guesses);
            System.out.println("guess=|" + guess + "|");
            System.out.println("word.letters=|" + word.letters + "|");
     
            // etc

    (The reason for the | symbols is because you want to be able to see any whitespace that might be frustrating the string comparison.)

  3. The Following User Says Thank You to pbrockway2 For This Useful Post:

    theonlydvr (June 29th, 2013)

  4. #3
    Junior Member
    Join Date
    Jun 2013
    Posts
    9
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Re: Hangman Program Java: Comparing the User's Guess with Another String Letter by Letter

    Thanks pbrockway2! I already took that part out of my code in previous debugging attempts. In doing this guesses just stayed on the screen. What I think happened is that the guess satisfied the if statement but could not go into the for loop.

    I fixed the second part. When I was loading the words from the dictionary it was including the \n symbol. So I wrote a StringBuilder and removed it and now it works. Your debugger code really helped.

    I saw that if I input a String of the same length as word.letters which is incorrect that this if statement runs: else if (guess.length() > 1 && (guess.length() < word.letters.length() || guess.length() > word.letters.length()))

    Can you possibly help explain what is going wrong?

    I found out that I was accidentally using an array of type wrapper Boolean instead of primitive boolean. Now I have a NullPointerException.

    Furthermore, this is the result of when I input a letter into the field:

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at NewClass$fieldListener.actionPerformed(NewClass.ja va:112)
    at javax.swing.JTextField.fireActionPerformed(Unknown Source)
    at javax.swing.JTextField.postActionEvent(Unknown Source)
    at javax.swing.JTextField$NotifyAction.actionPerforme d(Unknown Source)
    at javax.swing.SwingUtilities.notifyAction(Unknown Source)
    at javax.swing.JComponent.processKeyBinding(Unknown Source)
    at javax.swing.JComponent.processKeyBindings(Unknown Source)
    at javax.swing.JComponent.processKeyEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.KeyboardFocusManager.redispatchEvent(Unkn own Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEv ent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKe yEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAsse rtions(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent (Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$1.run(Unknown Source)
    at java.awt.EventQueue$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectio nPrivilege(Unknown Source)
    at java.security.AccessControlContext$1.doIntersectio nPrivilege(Unknown Source)
    at java.awt.EventQueue$2.run(Unknown Source)
    at java.awt.EventQueue$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectio nPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilter s(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(U nknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarch y(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

    This is line 112: word.flags[i] = true;

    This isn't normal is it?

    This is my code for the Word class:

    class Word { //word
        String letters; //the random string
        boolean[] flags; //the array of flags for chekcing if all letters have been found
    }

    Thanks for the help.
    Last edited by theonlydvr; June 29th, 2013 at 01:56 PM. Reason: Error

  5. #4
    Junior Member
    Join Date
    Jun 2013
    Posts
    9
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Re: Hangman Program Java: Comparing the User's Guess with Another String Letter by Letter

    I fixed the program!!! My problem was that I wasn't initializing word.flags. Thank you so much pb!

  6. #5
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    987
    Thanks
    6
    Thanked 206 Times in 182 Posts

    Default Re: Hangman Program Java: Comparing the User's Guess with Another String Letter by Letter

    You're welcome. I'm glad you got it sorted out.

    Did you System.out.println(words.flags)? That would be my response to the null pointer exception.

    ---

    Ignore this if you are happy with the program as it is...

    I would consider making the Word class a bit less "passive".

        /**
         * A class representing a word letters of which have been guessed.
         */
    class Word { 
        private String letters;
        private boolean[] flags;
     
        public Word(String letters) {
            this.letters = letters;
            flags = new boolean[letters.length]; // !
        }    
     
            /**
             * Updates the flags for a given guess.
             *
             * Returns 0 if the given character wasn't present, -1 if it had already been
             * guessed and 1 if the flags array was changed.
             */
        public int updateFlags(char ch) {
            // ...
        }
     
        // and maybe getter methods
    }

    That's just a sketch of course, but it seems a good place to put the code that does the guess checking. In general gui code (with its listeners etc) is quite complex enough without involving other things.

    And notice how flags can't help but be initialised correctly when it is placed inside a constructor.

Similar Threads

  1. Java Program - Letter Frequencies - HELP!
    By kbrady481 in forum What's Wrong With My Code?
    Replies: 24
    Last Post: March 13th, 2013, 08:29 PM
  2. can i ask how can a letter with value can be recognize in a program??
    By w0ooop in forum What's Wrong With My Code?
    Replies: 3
    Last Post: February 20th, 2013, 09:26 AM
  3. Finding the count of a letter in a String?
    By vlkn448 in forum Algorithms & Recursion
    Replies: 7
    Last Post: July 15th, 2012, 11:55 AM
  4. Switching letter-cases from user input; why is not working?
    By Kimiko Sakaki in forum What's Wrong With My Code?
    Replies: 2
    Last Post: March 27th, 2011, 07:48 AM
  5. Incrementing every letter in a string that occupies an odd position.
    By haktheplanet in forum What's Wrong With My Code?
    Replies: 4
    Last Post: March 22nd, 2010, 04:45 AM

Tags for this Thread