试图用Java实现基于文本的Hangman游戏

时间:2014-03-08 01:35:10

标签: java

我需要检查用户输入的字母以及他们猜测的空格是否位于隐藏字的特定位置。

变量1等于用户猜测的空间索引..而letterGuess是他们猜测的字母。我的代码怎么错?

示例:密码是hello

hidden word is ==  -----

用户猜测h 0 1 2 3 所以,它需要检查单词hello的索引0 1 2 3处的空格是否包含用户猜测的" h" 如果是,则需要将-----替换为h----

                 String firstSpace = guessedSpaces.substring(0,1);
                String secondSpace = guessedSpaces.substring(2,3);
                String thirdSpace = guessedSpaces.substring(4,5);
                String fourthSpace = guessedSpaces.substring(6,7);

                int one = Integer.parseInt(firstSpace);


                int two = Integer.parseInt(secondSpace);
                int three = Integer.parseInt(thirdSpace);
                int four = Integer.parseInt(fourthSpace);



     (secretWord.charAt(one)==letterGuess)
     (secretWord.charAt(one)==letterGuess)
    (secretWord.charAt(one)==letterGuess)
    (secretWord.charAt(one)==letterGuess)

4 个答案:

答案 0 :(得分:5)

以下是一个完整的刽子手程序的简短代码:

static int MAX_MISSES = 5;
static String[] WORDS = { "QUICK", "BROWN", "JUMPS" }; // etc

public static void main(String[] args) throws Exception {
    String word = WORDS[new Random().nextInt(WORDS.length)], guesses = " ";
    int misses = -1;
    for (Scanner in = new Scanner(System.in); !word.matches("[" + guesses + "]+") & (misses += word.contains(guesses.substring(0, 1)) ? 0 : 1) <= MAX_MISSES; guesses = in.nextLine().toUpperCase().charAt(0) + guesses)
        System.out.println(word.replaceAll("(?<=.)", " ").replaceAll("[^" + guesses + "]", "_"));
    System.out.println(word + (misses > MAX_MISSES ? " not" : "") + " solved with " + misses + " incorrect guesses");
}

一些注意事项:

  • 正则表达式用于检查解决方案并显示当前猜测状态
  • 在循环终止中使用
  • &代替&&来强制执行逻辑的两面 - 因此总是正确地更新未命中
  • 已经使用各种其他技巧来故意增加代码密度

输入没有错误检查。如果用户输入了多个字母,则仅使用第一个字母。如果没有输入字母,它将会爆炸。可以在不添加更多代码的情况下添加错误检查,但for行将是一个巨大的 - 我将其留作读者的练习。

此外,没有检查多次错误地猜测同一个字母。有了这段代码,如果你猜两次正确的字母,没有什么不好的事情发生,但如果你猜两次错误的字母,那就算是一个单独的“未命中”,所以你会烧掉你的一个机会。

答案 1 :(得分:1)

My other answer

我对此有点太有趣了。

主要班级:

public class HangmanWord  {
   private static final char MASK_CHAR = '-';
   private final String word;
   private final char[] maskedWordChars;
   private int totalMatched;
   public HangmanWord(String alphaNum_secretWord)  {
      int wordLen = -1;
      try  {
         wordLen = alphaNum_secretWord.length();
      }  catch(NullPointerException npx)  {
         throw  new NullPointerException("alphaNum_secretWord");
      }

      if(wordLen == 0)  {
         throw  new IllegalArgumentException("alphaNum_secretWord is non-null, but empty.");
      }

      //default is automatically false
      maskedWordChars = new char[wordLen];
      Arrays.fill(maskedWordChars, MASK_CHAR);
      totalMatched = 0;

      if(!Pattern.compile("^\\w+").matcher(alphaNum_secretWord).matches())  {
         throw  new IllegalArgumentException("alphaNum_secretWord (\"" + alphaNum_secretWord + "\") must contain only letters and digits.");
      }
      word = alphaNum_secretWord;
   }
   public int length()  {
      return  maskedWordChars.length;
   }
   public int getTotalMatchedCount()  {
      return  totalMatched;
   }
   public boolean didWin()  {
      return  (getTotalMatchedCount() == length());
   }

HangmanWord的主要逻辑功能:

   public int getMatchedCountFromGuess(char guessChar, int... idxGuesses)  {
      if(idxGuesses.length == 0)  {
         throw  new IllegalArgumentException("idxGuesses.length is zero.");
      }
      int guessedCount = 0;
      for(int idx : idxGuesses)  {
         try  {
            if(maskedWordChars[idx] == MASK_CHAR  &&  word.charAt(idx) == guessChar)  {
               maskedWordChars[idx] = guessChar;
               guessedCount++;
            }
         }  catch(ArrayIndexOutOfBoundsException abx)  {
            throw  new IllegalArgumentException("Index " + idx + " is invalid, given length() is " + length(), abx);
         }
      }
      totalMatched += guessedCount;
      return  guessedCount;
   }
   public String getMasked()  {
      return  (new String(maskedWordChars));
   }

和演示用法,它利用了下面的HangmanGuess类。

请注意,此接受用户输入。因此上面的猜测类,我可以存储模拟输入。下面有一系列猜测对象。

(使用用户输入测试这样一个重要的程序是一场噩梦。我实际创建了用户输入的代码,但是偶然删除了。我打算把它放在一个单独的函数中,所以它可以选择使用,但是在我粘贴它之前就分心了。每次运行它都是 如此臭兮兮的 手动输入所有这些数据。我只是不明白为什么用户 - 在CS教育中/新手选择的输入非常需要,除了最琐碎的程序之外,还可以用于其他任何内容。)

   public static final void main(String[] idx0_alphaNumSecretWord)  {
      HangmanWord hword = null;
      try  {
         hword = new HangmanWord(idx0_alphaNumSecretWord[0]);
      }  catch(ArrayIndexOutOfBoundsException abx)  {
         throw  new IllegalArgumentException("Missing one required parameter: The alpha-numeric secret word.");
      }

      //TESTING ONLY:
         //#=matches in guess
         HangmanGuess[] testGuesses = new HangmanGuess[]{ //012345678901
            new HangmanGuess('t', 2, 3, 4),               //onomatopoeia
            new HangmanGuess('e', 6, 7, 8, 9), //1
            new HangmanGuess('a', 6, 7, 8),
            new HangmanGuess('a', 4),          //1
            new HangmanGuess('o', 0, 3),       //1
            new HangmanGuess('o', 0, 2, 8 ,6), //3
            new HangmanGuess('p', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11),  //1
            new HangmanGuess('n', 1),          //1
            new HangmanGuess('t', 4, 5),       //1
            new HangmanGuess('z', 0),
            new HangmanGuess('m', 3, 4),       //1
            new HangmanGuess('i', 10),         //1
            new HangmanGuess('a', 11)          //1
         };
         int testIdx = 0;

主要用途 - 逻辑:

      while(!hword.didWin())  {
         System.out.print("The secret word is: " + hword.getMasked() + ". Guess (char idx idx idx ...): ");

         //LIVE only:  (must create!)
         //  HangmanGuess hguess = getGuessFromUserInput();
         //Testing only...START
            HangmanGuess hguess = testGuesses[testIdx++];
            System.out.print(hguess);
         //Testing only...END

         int matchesThisGuess = hword.getMatchedCountFromGuess(hguess.chr, hguess.idxGuesses);

         System.out.println();

         if(matchesThisGuess == 0)  {
            System.out.println("No characters guessed.");
         }
      }
      System.out.println("SUCCESS: " + hword.getMasked());

   }
}

猜猜课:

class HangmanGuess  {
   public final char chr;
   public final int[] idxGuesses;
   public HangmanGuess(char chr, int... idxGuesses)  {
      this.chr = chr;
      this.idxGuesses = idxGuesses;
   }
   public String toString()  {
      StringBuilder bldr = (new StringBuilder()).append(chr).append(" ");
      for(int i : idxGuesses)  {
         bldr.append(i + " ");
      }
      return  bldr.toString();
   }
}

输出:

[C:\java_code\]java HangmanWord onomatopoeia
The secret word is: ------------. Guess (char idx idx idx ...): t 2 3 4
No characters guessed.
The secret word is: ------------. Guess (char idx idx idx ...): e 6 7 8 9
The secret word is: ---------e--. Guess (char idx idx idx ...): a 6 7 8
No characters guessed.
The secret word is: ---------e--. Guess (char idx idx idx ...): a 4
The secret word is: ----a----e--. Guess (char idx idx idx ...): o 0 3
The secret word is: o---a----e--. Guess (char idx idx idx ...): o 0 2 8 6
The secret word is: o-o-a-o-oe--. Guess (char idx idx idx ...): p 0 1 2 3 4 5 6 7 8 9 10 11
The secret word is: o-o-a-opoe--. Guess (char idx idx idx ...): n 1
The secret word is: ono-a-opoe--. Guess (char idx idx idx ...): t 4 5
The secret word is: ono-atopoe--. Guess (char idx idx idx ...): z 0
No characters guessed.
The secret word is: ono-atopoe--. Guess (char idx idx idx ...): m 3 4
The secret word is: onomatopoe--. Guess (char idx idx idx ...): i 10
The secret word is: onomatopoei-. Guess (char idx idx idx ...): a 11
SUCCESS: onomatopoeia

完整的源代码:

   import  java.util.Scanner;
   import  java.util.regex.Matcher;
   import  java.util.regex.Pattern;
   import  java.util.Arrays;
/**
   <P>{@code java HangmanWord onomatopoeia}</P>
 **/
public class HangmanWord  {
   private static final char MASK_CHAR = '-';
   private final String word;
   private final char[] maskedWordChars;
   private int totalMatched;
   public HangmanWord(String alphaNum_secretWord)  {
      int wordLen = -1;
      try  {
         wordLen = alphaNum_secretWord.length();
      }  catch(NullPointerException npx)  {
         throw  new NullPointerException("alphaNum_secretWord");
      }

      if(wordLen == 0)  {
         throw  new IllegalArgumentException("alphaNum_secretWord is non-null, but empty.");
      }

      //default is automatically false
      maskedWordChars = new char[wordLen];
      Arrays.fill(maskedWordChars, MASK_CHAR);
      totalMatched = 0;

      if(!Pattern.compile("^\\w+").matcher(alphaNum_secretWord).matches())  {
         throw  new IllegalArgumentException("alphaNum_secretWord (\"" + alphaNum_secretWord + "\") must contain only letters and digits.");
      }
      word = alphaNum_secretWord;
   }
   public int length()  {
      return  maskedWordChars.length;
   }
   public int getTotalMatchedCount()  {
      return  totalMatched;
   }
   public boolean didWin()  {
      return  (getTotalMatchedCount() == length());
   }
   public int getMatchedCountFromGuess(char guessChar, int... idxGuesses)  {
      if(idxGuesses.length == 0)  {
         throw  new IllegalArgumentException("idxGuesses.length is zero.");
      }
      int guessedCount = 0;
      for(int idx : idxGuesses)  {
         try  {
            if(maskedWordChars[idx] == MASK_CHAR  &&  word.charAt(idx) == guessChar)  {
               maskedWordChars[idx] = guessChar;
               guessedCount++;
            }
         }  catch(ArrayIndexOutOfBoundsException abx)  {
            throw  new IllegalArgumentException("Index " + idx + " is invalid, given length() is " + length(), abx);
         }
      }
      totalMatched += guessedCount;
      return  guessedCount;
   }
   public String getMasked()  {
      return  (new String(maskedWordChars));
   }

   public static final void main(String[] idx0_alphaNumSecretWord)  {
      HangmanWord hword = null;
      try  {
         hword = new HangmanWord(idx0_alphaNumSecretWord[0]);
      }  catch(ArrayIndexOutOfBoundsException abx)  {
         throw  new IllegalArgumentException("Missing one required parameter: The alpha-numeric secret word.");
      }

      //TESTING only
         //#=matches in guess
         HangmanGuess[] testGuesses = new HangmanGuess[]{ //012345678901
            new HangmanGuess('t', 2, 3, 4),               //onomatopoeia
            new HangmanGuess('e', 6, 7, 8, 9), //1
            new HangmanGuess('a', 6, 7, 8),
            new HangmanGuess('a', 4),          //1
            new HangmanGuess('o', 0, 3),       //1
            new HangmanGuess('o', 0, 2, 8 ,6), //3
            new HangmanGuess('p', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11),  //1
            new HangmanGuess('n', 1),          //1
            new HangmanGuess('t', 4, 5),       //1
            new HangmanGuess('z', 0),
            new HangmanGuess('m', 3, 4),       //1
            new HangmanGuess('i', 10),         //1
            new HangmanGuess('a', 11)          //1
         };
         int testIdx = 0;

      while(!hword.didWin())  {
         System.out.print("The secret word is: " + hword.getMasked() + ". Guess (char idx idx idx ...): ");

         //LIVE only:  (must create!)
         //  HangmanGuess hguess = getGuessFromUserInput();
         //Testing only...START
            HangmanGuess hguess = testGuesses[testIdx++];
            System.out.print(hguess);
         //Testing only...END

         int matchesThisGuess = hword.getMatchedCountFromGuess(hguess.chr, hguess.idxGuesses);

         System.out.println();

         if(matchesThisGuess == 0)  {
            System.out.println("No characters guessed.");
         }
      }
      System.out.println("SUCCESS: " + hword.getMasked());

   }
}
class HangmanGuess  {
   public final char chr;
   public final int[] idxGuesses;
   public HangmanGuess(char chr, int... idxGuesses)  {
      this.chr = chr;
      this.idxGuesses = idxGuesses;
   }
   public String toString()  {
      StringBuilder bldr = (new StringBuilder()).append(chr).append(" ");
      for(int i : idxGuesses)  {
         bldr.append(i + " ");
      }
      return  bldr.toString();
   }
}

答案 2 :(得分:1)

My other answer

我已经采取Bohemian's dense-and-great answer,并将其作为我自己的。它并不是更好,我只是为了学习它而做到了。虽然它不符合OP的规范,但规范与普通的hangman非常不同(您必须明确指定猜测字母适用的索引)。此应用程序更接近正常的Hangman规则。

与波希米亚代码的主要区别在于

  • 这是do-while,而不是for循环。
  • 它仅保留唯一字符,并与单独的currCharGuessAsStr进行比较,而不是allGuessCharsStr中的第一个字符。
  • 它会通知用户输入错误(没有字符)而不是崩溃,并且需要输入为单个字母。
  • 显示每一步的状态。

预循环:

public class Hangman  {
   static int MAX_BAD_GUESSES = 10;
   static String[] WORDS = { "QUICK", "BROWN", "JUMPS" }; // etc

   public static void main(String[] args) throws Exception {
      String word = WORDS[new Random().nextInt(WORDS.length)];
      Scanner in = new Scanner(System.in);
      int badGuessCount = 0;
      String guessInput = null;

      //Could be character key, but a ONE-CHARACTER STRING instead
      //To avoid having to translate back and forth between string
      //and char.
      Map<String,Object> unqGuessedCharsAsStrMap = new TreeMap<String,Object>();

      //Must be initialized to the empty string. Initializing to null
      //Will result in the literal string "null" being added to it.
      String allGuessCharsStr = "";
      String currCharGuessAsStr = " ";

循环:

      do  {

         System.out.print(getMasked(word, allGuessCharsStr) + " Guess a character [Bad guesses: " + badGuessCount + " of " + MAX_BAD_GUESSES + "]: ");

         guessInput = in.nextLine();

         if(guessInput != null)  {  //null on first iteration only
            if(!guessInput.matches("^[a-zA-Z]$"))  {
               System.out.println("Bad input. Must a single letter.");
               badGuessCount++;

            }  else  {
               //Definitely valid input, and exactly one character
               currCharGuessAsStr = guessInput.toUpperCase();

               if(unqGuessedCharsAsStrMap.containsKey(currCharGuessAsStr))  {
                  //Trim to eliminate initialization space
                  System.out.println("Already guessed that letter. All guesses: " + allGuessCharsStr.trim());

               }  else  {
                  unqGuessedCharsAsStrMap.put(currCharGuessAsStr, null);

                  //Prepend just-guessed character and sort it.
                  allGuessCharsStr += currCharGuessAsStr;
                  char[] allGuessedChars = allGuessCharsStr.toCharArray();
                  Arrays.sort(allGuessedChars);
                  allGuessCharsStr = new String(allGuessedChars);
               }

               if(!word.contains(currCharGuessAsStr))  {
                  badGuessCount++;
               }
            }
         }

      }  while(!word.matches("[" + allGuessCharsStr + "]+")  &&
                  badGuessCount <= MAX_BAD_GUESSES);

后循环和getMasked(s,s)函数:

      System.out.println(getMasked(word, allGuessCharsStr));

      System.out.println(word + (badGuessCount > MAX_BAD_GUESSES ? " not" : "") + " solved with " + badGuessCount + " incorrect guesses (max allowed=" + MAX_BAD_GUESSES + ").");
   }

   /**
      @param  all_guessesStrESIfNone  May not be null. If empty, no guesses have been made yet.
      @exception  PatternSyntaxException  If all_guessCharsStr is empty.
    **/
   private static final String getMasked(String secret_word, String all_guessesStrESIfNone)  {
      try  {
         if(all_guessesStrESIfNone.length() == 0)  {
            all_guessesStrESIfNone = " ";   //Any non-letter will suffice
         }
      }  catch(NullPointerException npx)  {
         throw  new NullPointerException("all_guessesStrESIfNone");
      }

      //Mask all not-yet-guessed characters with an underscore.
      secret_word = secret_word.replaceAll("[^" + all_guessesStrESIfNone + "]", "_");

      //Insert a space between every character (trim eliminates the final).
      return  secret_word.replaceAll("(.)", "$1 ").trim();
   }
}

解决输出:

[C:\java_code]java Hangman
_ _ _ _ _ Guess a character [Bad guesses: 0 of 10]: a
_ _ _ _ _ Guess a character [Bad guesses: 1 of 10]: b
_ _ _ _ _ Guess a character [Bad guesses: 2 of 10]: c
_ _ _ _ _ Guess a character [Bad guesses: 3 of 10]: d
_ _ _ _ _ Guess a character [Bad guesses: 4 of 10]: e
_ _ _ _ _ Guess a character [Bad guesses: 5 of 10]: f
_ _ _ _ _ Guess a character [Bad guesses: 6 of 10]: j
J _ _ _ _ Guess a character [Bad guesses: 6 of 10]: q
J _ _ _ _ Guess a character [Bad guesses: 7 of 10]: m
J _ M _ _ Guess a character [Bad guesses: 7 of 10]: p
J _ M P _ Guess a character [Bad guesses: 7 of 10]: u
J U M P _ Guess a character [Bad guesses: 7 of 10]: s
J U M P S
JUMPS solved with 7 incorrect guesses (max allowed=10).

未解决的输出:

[C:\java_code]java Hangman
_ _ _ _ _ Guess a character [Bad guesses: 0 of 10]: a
_ _ _ _ _ Guess a character [Bad guesses: 1 of 10]: b
_ _ _ _ _ Guess a character [Bad guesses: 2 of 10]: c
_ _ _ C _ Guess a character [Bad guesses: 2 of 10]: d
_ _ _ C _ Guess a character [Bad guesses: 3 of 10]: e
_ _ _ C _ Guess a character [Bad guesses: 4 of 10]: f
_ _ _ C _ Guess a character [Bad guesses: 5 of 10]: j
_ _ _ C _ Guess a character [Bad guesses: 6 of 10]: e
Already guessed that letter. All guesses: ABCDEFJ
_ _ _ C _ Guess a character [Bad guesses: 7 of 10]:
Bad input. Must a single letter.
_ _ _ C _ Guess a character [Bad guesses: 8 of 10]: tt
Bad input. Must a single letter.
_ _ _ C _ Guess a character [Bad guesses: 9 of 10]: q
Q _ _ C _ Guess a character [Bad guesses: 9 of 10]: k
Q _ _ C K Guess a character [Bad guesses: 9 of 10]: l
Q _ _ C K Guess a character [Bad guesses: 10 of 10]: z
Q _ _ C K
QUICK not solved with 11 incorrect guesses (max allowed=10).

完整代码:

   import  java.util.Arrays;
   import  java.util.Map;
   import  java.util.TreeMap;
   import  java.util.Random;
   import  java.util.Scanner;
/**
   <P>{@code java Hangman}</P>
 **/
public class Hangman  {
   static int MAX_BAD_GUESSES = 10;
   static String[] WORDS = { "QUICK", "BROWN", "JUMPS" }; // etc

   public static void main(String[] args) throws Exception {
      String word = WORDS[new Random().nextInt(WORDS.length)];
      Scanner in = new Scanner(System.in);
      int badGuessCount = 0;
      String guessInput = null;

      //Could be character key, but a ONE-CHARACTER STRING instead
      //To avoid having to translate back and forth between string
      //and char.
      Map<String,Object> unqGuessedCharsAsStrMap = new TreeMap<String,Object>();

      //Must be initialized to the empty string. Initializing to null
      //Will result in the literal string "null" being added to it.
      String allGuessCharsStr = "";
      String currCharGuessAsStr = " ";

      do  {

         System.out.print(getMasked(word, allGuessCharsStr) + " Guess a character [Bad guesses: " + badGuessCount + " of " + MAX_BAD_GUESSES + "]: ");

         guessInput = in.nextLine();

         if(guessInput != null)  {  //null on first iteration only
            if(!guessInput.matches("^[a-zA-Z]$"))  {
               System.out.println("Bad input. Must a single letter.");
               badGuessCount++;

            }  else  {
               //Definitely valid input, and exactly one character
               currCharGuessAsStr = guessInput.toUpperCase();

               if(unqGuessedCharsAsStrMap.containsKey(currCharGuessAsStr))  {
                  //Trim to eliminate initialization space
                  System.out.println("Already guessed that letter. All guesses: " + allGuessCharsStr.trim());

               }  else  {
                  unqGuessedCharsAsStrMap.put(currCharGuessAsStr, null);

                  //Prepend just-guessed character and sort it.
                  allGuessCharsStr += currCharGuessAsStr;
                  char[] allGuessedChars = allGuessCharsStr.toCharArray();
                  Arrays.sort(allGuessedChars);
                  allGuessCharsStr = new String(allGuessedChars);
               }

               if(!word.contains(currCharGuessAsStr))  {
                  badGuessCount++;
               }
            }
         }

      }  while(!word.matches("[" + allGuessCharsStr + "]+")  &&
                  badGuessCount <= MAX_BAD_GUESSES);

      System.out.println(getMasked(word, allGuessCharsStr));

      System.out.println(word + (badGuessCount > MAX_BAD_GUESSES ? " not" : "") + " solved with " + badGuessCount + " incorrect guesses (max allowed=" + MAX_BAD_GUESSES + ").");
   }

   /**
      @param  all_guessesStrESIfNone  May not be null. If empty, no guesses have been made yet.
      @exception  PatternSyntaxException  If all_guessCharsStr is empty.
    **/
   private static final String getMasked(String secret_word, String all_guessesStrESIfNone)  {
      try  {
         if(all_guessesStrESIfNone.length() == 0)  {
            all_guessesStrESIfNone = " ";   //Any non-letter will suffice
         }
      }  catch(NullPointerException npx)  {
         throw  new NullPointerException("all_guessesStrESIfNone");
      }

      //Mask all not-yet-guessed characters with an underscore.
      secret_word = secret_word.replaceAll("[^" + all_guessesStrESIfNone + "]", "_");

      //Insert a space between every character (trim eliminates the final).
      return  secret_word.replaceAll("(.)", "$1 ").trim();
   }
}

答案 3 :(得分:0)

你没告诉我们它是怎么出错的。

我猜你正试图写一个'刽子手'程序。我会猜测你忘了charAt()返回的索引从零开始。