我在使用嵌套的for循环和String替换函数时遇到了麻烦

时间:2017-09-22 06:07:53

标签: java while-loop

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");

    }   
}

我知道通过人们的代码需要付出很多努力,尤其是我的代码,因为它太长而且非常业余,所以我尽力评论我的所有代码,试图解释我在想什么。刽子手游戏非常精致,我只是想让它打印空白,但填写了猜测字母。

例如,秘密词是java

我猜j

输出:j ___

我的代码实际上已经走得那么远了,但是对于更多的猜测,输出只是:______

我的问题基本上是,如何在第一次更换循环后实际继续工作?

再次,我要感谢所有人提前和明天早上再次阅读时的答案。

3 个答案:

答案 0 :(得分:3)

您错误地构建了tempList

在第二个for循环中,对于每个使用过的字符,它会将allCharstempList的所有字符添加到与此特定使用字符不匹配的位置。除了在循环的下一次迭代中添加重复项的效果之外,这还可能添加已在usedChars中的字符。

更改

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));             
        }
    }
}

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));                  
    }
}

答案 1 :(得分: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
                    }
                }
            }

您的问题是!allChars.get(i).equals(usedChars.get(k))将始终将每个字符添加到您的tempList,因为每个字母都会针对每个字母进行检查。试试这个:

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)); 
                }
            }

答案 2 :(得分:1)

替换:

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);

使用:

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

就像其他答案一样,你正在错误地构建tempList。事实证明你甚至不需要它:)。

两个奖金提示:

  • 不要那样评论您的代码。最佳做法是以一种方式命名您的方法/变量,以便在没有任何注释的情况下清楚它们是什么/做什么。所以没有inputWord2,请将其称为maskedInputWordmistakeCounter代替counter
  • 您的counter(我认为应该只计算错误)也会在良好的猜测中递增。现在的样子,你不能正确猜出一个包含6个或更多独特字符的单词。