6
public class Hangman {

    public static void ttt(String inputWord) {                          //setting up the game and declaring the secret word to be the input
        int wordLength = inputWord.length();                            //making new integer variable for length of word
        String blanks = "";                                             //creating blanks string
        for(int i = 0; i < wordLength; i++) {                           //making one blank for every letter of the word
            blanks = blanks.concat("_ ");
        }
        System.out.println(blanks);                                     //initially just to show user how many blanks/letters there are to guess
        int points = 0;                                                 //setting up points int, one is awarded for each correct letter
        int counter = 0;                                                //setting up counter int,  used to keep track of lives, reference lines 58+
        ArrayList<String> usedChars = new ArrayList<String>();          //creating new array to store used letters
        ArrayList<String> allChars = new ArrayList<String>();           //creating new array to store all letters
        for(int i = 0; i < wordLength; i++) {                           //filling allChars with all the letters
            allChars.add(inputWord.substring(i, i + 1));
        }
        while(points < wordLength) {                                    //the entire game is run off of the points system, user needs as many points as number of letters to exit the while loop
            Scanner reader = new Scanner(System.in);                    //making scanner thing
            System.out.println("Guess: ");                              //asking user to guess a letter
            String guess = reader.nextLine();                           //string guess is set to the input
            int checker = 0;                                            //setting up checker int, used to check for duplicate answers
            for(int k = 0; k < usedChars.size(); k++) {                 //for loop iterates through every item in usedChars and checks them against the user guess
                if(!usedChars.get(k).equals(guess)) {                   //if the guess is different from that used letter
                    checker = checker + 1;                              //add one to the checker
                }
                else {}                                                 //or else nothing happens, this probably isn't necessary
            }
            if(checker == usedChars.size()) {                           //if statement protects the for loop inside, only runs if the checker got a point for every used letter (proving the guess was unique)
                for(int i = 0; i < wordLength; i++) {                   //for loop iterates through every letter of the secret word, checking each against the guess
                    if(guess.equals(inputWord.substring(i, i + 1))) {
                        points = points + 1;                            //one point is added for every matching letter, refer back to line 20
                        System.out.println("Correct!");                 //prints correct for every matching letter
                    }
                    else {}                                             //again this probably isn't necessary
                }
                usedChars.add(guess);                                   //after the guess is checked against the secret word, the guess is added to the used letters array
                ArrayList<String> tempList = new ArrayList<String>();   //a temporary list is created to store the letters that haven't yet been guessed
                for(int i = 0; i < allChars.size(); i++) {              //for loop iterates through every string in the all letters array
                    for(int k = 0; k < usedChars.size(); k++) {         //nested for loop iterates through every string in the used letters array
                        if(!allChars.get(i).equals(usedChars.get(k))) { //every string in allChars is checked against every string in usedChars
                            tempList.add(allChars.get(i));              //the temporary list is filled with the letters in allChars that were not found in usedChars
                        }
                    }
                }
                String inputWord2 = inputWord;                                  //inputWord is duplicated, the copy will be manipulated but the original is still used in the above code
                for(int i = 0; i < tempList.size(); i++) {                      //for loop iterates through every string in tempList (the list with the letters the user hasn't guessed yet)
                    inputWord2 = inputWord2.replace(tempList.get(i), "_");      //the full word has every letter it shares with tempList replaced with _ for the user to guess
                }
                System.out.println(inputWord2);                                 //the word censored for any letters not guessed yet is printed
                System.out.println("Used letters: " + usedChars);               //the user is reminded which letters have already been used
            }
            else {
                System.out.print("Sorry, that letter has already been used\n"); //if the checker didn't end up being equal to the number of items in usedChars then the guess was a repeat (found in usedChars)
            }
            counter = counter + 1;                                              //tracking lives by adding one to counter after each guess
            if(counter == 5) {                                                  //when the counter reaches x tries, user runs out of lives
                points = wordLength;                                            //this forcibly exits the while loop by satisfying the condition of points being equal to the number of letters
            }
        }   
        System.out.println("The word was " + inputWord);                        //prints the secret word
        System.out.println("Game over");                                        //prints game over
    }

    public static void main(String[] args) {
        ttt("barbarian");

    }   
}

I know it has to be a lot of effort to go through people's code, especially mine since it's so long and amateurish, so I did my best to comment out all my code to try to explain what I'm thinking. The hangman game is pretty much refined, and I am just trying to have it print the blanks but with guessed letters filled in.

So for example, the secret word is java

I guess j

output: j___

my code actually gets that far, but for any more guesses the output is just: ______

My question would be essentially, how do I get that for replacing loop to actually keep working after the first time?

Again, I want to thank everyone that answers in advance and again when I read them tomorrow morning.

7
  • 1
    OT, it's good to document, but bad if it's not readable. Commented Sep 22, 2017 at 6:09
  • 4
    You've got a couple of good answers, so I don't have anything to add there, but just wanted to say that you're being a bit harsh on yourself with apologising for 'amateurish' code - sure, it's obviously written by someone new to programming, but it's formatted well, you've used variable names appropriately and it's structured in a logical and sane way. I didn't need to refer to your comments at all. This puts it well into the top 10% of all code posted on SO, and much, much better than lots of people who post here and appear to be being paid for what they do! Commented Sep 22, 2017 at 6:48
  • 1
    A couple of minor stylistic things that might be helpful: 1 - You don't need the else {}'s - if you don't need an else just don't include it at all, only the if will be executed. 2 - Look at the documentation for ArrayList.contains() - you can probably simplify your code a bit and remove several of the loops. 3 - ditto for String.contains() Commented Sep 22, 2017 at 6:52
  • Hey @nullpointer, could you clarify what was unreadable about my comments? I am hearing that commenting code is unnecessary so I will try and just focus on the code next time 👍 And DaveyDaveDave thanks, I'm still in the first month of my java class so I assumed my code wouldn't be that good. Commented Sep 22, 2017 at 11:25
  • 2
    @nullpointer, one should strive to write such clear code that comments are not needed. In some cases that's really hard, and then sure, add comments. Commented Sep 22, 2017 at 11:45

3 Answers 3

3

You are incorrectly building up tempList.

In the second for-loop, for each used character, it adds all characters of allChars to tempList that do not match this specific used character. Besides the effect of adding duplicates in next iterations of the loop, this might also add characters that are already in usedChars.

Change

ArrayList<String> tempList = new ArrayList<String>();   
for(int i = 0; i < allChars.size(); i++) {             
    for(int k = 0; k < usedChars.size(); k++) {        
        if(!allChars.get(i).equals(usedChars.get(k))) { 
            tempList.add(allChars.get(i));             
        }
    }
}

to

ArrayList<String> tempList = new ArrayList<String>();
for(int i = 0; i < allChars.size(); i++) {             
    if (!usedChars.contains(allChars.get(i))) {
        tempList.add(allChars.get(i));                  
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1
ArrayList<String> tempList = new ArrayList<String>();   //a temporary list is created to store the letters that haven't yet been guessed
            for(int i = 0; i < allChars.size(); i++) {              //for loop iterates through every string in the all letters array
                for(int k = 0; k < usedChars.size(); k++) {         //nested for loop iterates through every string in the used letters array
                    if(!allChars.get(i).equals(usedChars.get(k))) { //every string in allChars is checked against every string in usedChars
                        tempList.add(allChars.get(i));              //the temporary list is filled with the letters in allChars that were not found in usedChars
                    }
                }
            }

Your problem is that !allChars.get(i).equals(usedChars.get(k)) will always add every character to your tempList because every letter is checked against every letter. try this:

ArrayList<String> tempList = new ArrayList<String>();  
            for(int i = 0; i < allChars.size(); i++) {
                boolean tmp = false;          
                for(int k = 0; k < usedChars.size(); k++) {         
                    if(allChars.get(i).equals(usedChars.get(k))) { 
                        tmp = true;             
                    }
                }
                if(!tmp) {
                   tempList.add(allChars.get(i)); 
                }
            }

Comments

1

Replace:

ArrayList<String> tempList = new ArrayList<String>();
for(int i = 0; i < allChars.size(); i++) {
    for(int k = 0; k < usedChars.size(); k++) {
        if(!allChars.get(i).equals(usedChars.get(k))) {
            tempList.add(allChars.get(i)); in usedChars
        }
    }
}
String inputWord2 = inputWord;
for(int i = 0; i < tempList.size(); i++) {
    inputWord2 = inputWord2.replace(tempList.get(i), "_");
}
System.out.println(inputWord2);

With:

String maskedInputWord = inputWord;
for (String s : allChars) {
    if (!usedChars.contains(s)) {
        maskedInputWord = maskedInputWord.replace(s, "_");
    }
}
System.out.println(maskedInputWord);

Like other answers have been saying, you were building tempList incorrectly. Turns out you don't even need it :).

Two bonus tips:

  • Don't comment your code like that. Best practice is to name your methods/variables in such a way that it is clear what they are/do without any comments. So no inputWord2, call it e.g. maskedInputWord. mistakeCounter instead of counter.
  • Your counter (which I assume should only count mistakes) also increments on good guesses. The way it is now, you can't ever guess a word with 6 or more unique characters correctly.

1 Comment

Thanks I'll make the variable name changes like you suggested!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.