运行hangman(Java)的程序中的逻辑出错
Posted
技术标签:
【中文标题】运行hangman(Java)的程序中的逻辑出错【英文标题】:Logic going awry in a program that runs hangman (Java) 【发布时间】:2014-10-23 16:39:12 【问题描述】:所以这里还有一个刽子手问题要添加到这里的库中。除了一个名为revealLetter() 的方法外,我的实体和边界类几乎都是完整的,该方法用正确猜测的字母替换空白。它还计算正确猜到的字母(如果有)的数量,并将该整数返回给驱动程序以确定它是否命中或命中。如果用户输入了错误的字母,revealLetter() 将返回零,否则它将返回正确字母的数量以确定正确的字母。我的问题是,revealLetter() 总是返回零,尽管填写了正确的字母。我已经投入了一些 sout 来隔离正在发生的事情,并且在退出我的 for 循环后,计数器似乎设置为零。我还在学习 Java,所以很有可能它很简单,但目前对我来说似乎很复杂。这是驱动程序:
package hangman;
import java.util.Scanner;
public class Hangman
public static int NUMBER_MISSES = 5;
public static void main(String[] args)
String guessedLetter;
WordHider hider = new WordHider();
Dictionary dictionary = new Dictionary();
Scanner Keyboard = new Scanner(System.in);
hider.setHiddenWord(dictionary.getRandomWord());
System.out.println(hider.getHiddenWord().length());
System.out.println(hider.getHiddenWord());
do
hider.wordFound();
System.out.printf(hider.getPartiallyFoundWord() + " Chances Remaing: %d \nMake a guess: ", NUMBER_MISSES);
guessedLetter = Keyboard.nextLine();
hider.revealLetter(guessedLetter.toLowerCase());
if (hider.revealLetter(guessedLetter)== 0)
NUMBER_MISSES--;
if (NUMBER_MISSES == 4)
System.out.println("Swing and a miss!");
else if (NUMBER_MISSES == 3)
System.out.println("Yup. That. Is. A. Miss.");
else if (NUMBER_MISSES == 2)
System.out.println("MISS! They say third time is a charm.");
else if (NUMBER_MISSES == 1)
System.out.println("Ouch. One guess left, think carefully.");
else
System.out.println("That's a hit!");
if (hider.wordFound() == true)
NUMBER_MISSES = 0;
while (NUMBER_MISSES > 0);
if ((NUMBER_MISSES == 0) && (hider.wordFound() == false))
System.out.println("Critical Failure. The word was " + hider.getHiddenWord() + " try harder next time and you'll win.");
else if ((NUMBER_MISSES == 0) && (hider.wordFound() == true))
System.out.println(hider.getHiddenWord() + "\nBingo! You win!");
这是将单词从 .txt 存储到数组并生成随机单词的类:
package hangman;
import java.util.Random;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Dictionary
//Random randomizer = new Random();
private static String randomWord;
String[] dictionary = new String[81452];
private static String FILE_NAME = "dictionarycleaned.txt";
Dictionary()
int words = 0;
Scanner infile = null;
try
infile = new Scanner(new File(FILE_NAME));
while (infile.hasNext())
dictionary[words] = infile.nextLine();
words++;
//System.out.println(dictionary[81451]);
catch (FileNotFoundException e)
System.err.println("Error opening the file " + FILE_NAME);
System.exit(1);
public String getRandomWord()
//randomWord = (dictionary[randomizer.nextInt(dictionary.length)]); //Are either of these techniques better than the other?
randomWord = (dictionary[new Random().nextInt(dictionary.length)]);
return randomWord;
这是包含revealLetter()的类,它也处理随机词:
package hangman;
public class WordHider
private static String hiddenWord;
private static String partiallyFoundWord;
WordHider()
hiddenWord = "";
partiallyFoundWord = "";
public String getHiddenWord()
return hiddenWord;
public String getPartiallyFoundWord()
return partiallyFoundWord;
public void setHiddenWord(String newHiddenWord)
int charCount;
hiddenWord = newHiddenWord;
for (charCount = 0; charCount < hiddenWord.length(); charCount++)
partiallyFoundWord += "*";
public int revealLetter(String letter)
int correctChars = 0;
if (letter.length() < 1 || letter.length() > 1)
correctChars = 0;
return correctChars;
else
String tempString = "";
for (int i = 0; i < hiddenWord.length(); i++)
if ((letter.charAt(0) == hiddenWord.charAt(i)) && (partiallyFoundWord.charAt(i) == '*'))
correctChars++;
tempString += Character.toString(hiddenWord.charAt(i));
else
tempString += partiallyFoundWord.charAt(i);
partiallyFoundWord = tempString;
return correctChars;
public boolean wordFound()
boolean won = false;
if (partiallyFoundWord.contains(hiddenWord))
won = true;
return won;
public void hideWord()
for (int i = 0; i < hiddenWord.length(); i++)
partiallyFoundWord += "*";
还值得注意的是,我正在上 CS 大学课程,并且对于复制不属于我的代码有严格的法律。因此,如果有任何善良的灵魂发生在这件事上,可以你用英语解释我做错了什么。我仍然想弄清楚代码,我只是逻辑上卡住了。在此先感谢
【问题讨论】:
我将您关于复制代码的通知加粗,以免人们不小心忽略它并为您提供完整的解决方案。话虽如此,您是否尝试过在调试器中运行代码,例如 Eclipse、Netbeans 或 IntelliJ IDEA 等 IDE 中可能包含的调试器? 谢谢你!是的,我专门在 revelLetter() 方法调用上运行了调试器(在 Netbeans 中),它似乎通过了 for 循环,它会正确添加字母,但我不知道在 for 循环之后发生了什么。如果我在返回的正确字符上方放置一个 sout 语句,它会打印正确猜测的字母的数量(无论是 1、2 还是 3),但它也会打印零。这让我认为某处有第二次迭代正在重置我的变量。但我似乎无法隔离问题。 我无法发现具体问题,但我建议将revealLetter
中的 if 条件简化为仅(letter.charAt(0) == hiddenWord.charAt(i))
,因为显示已显示的字母应该是无操作的。另外,为什么hiddenWord
和partiallFoundWord
是静态的,而你的类中的方法是非静态的?
我有复合布尔值,以便它检查位置 (i) 是否是星号,如果是并且猜到的字母是正确的,它会将该字母与其他未填充的字符串一起添加到新字符串 tempString空白。我也忘了,在我的 for 的 else 中,correctChars 被设置为零。我会编辑那个。至于静态/非静态;我不确定,正如我所说的我还在学习,所以这可能只是我对事物的看法。那些是静态的有帮助吗?
静态意味着它在您的应用程序中是相同的。非静态意味着您为类的每个实例都获得了一个单独的值。如果您使用像new WordHider()
这样的构造函数,那么通常非静态是要走的路。详情请参阅this question and answers。
【参考方案1】:
在您的驱动程序main()
中,您有:
hider.revealLetter(guessedLetter.toLowerCase());
if (hider.revealLetter(guessedLetter)== 0)
这就是为什么你接到一个成功的电话,然后第二次就没有什么可做的了。我可以强调一些风格问题,但一个重要的问题是:
if (letter.length() < 1 || letter.length() > 1)
correctChars = 0;
return correctChars;
else
为什么不只是letter.length() != 1
,因为correctChars
已经初始化为零,你不需要再做一次,所以整个“then”部分可以被删除,if
变成letter.length() == 1
。
还有:
tempString += Character.toString(hiddenWord.charAt(i));
还有:
tempString += partiallyFoundWord.charAt(i);
两者都做同样的事情,所以选择一种风格或另一种风格。
【讨论】:
感谢您的建议,非常感谢。我的 if 语句的这种简短表达方式确实看起来好多了,不那么笨重了。不过,关于我的 main() 中的 if 。那么,该语句总是接收零作为返回值,这就是为什么它永远不会转到 else 的原因? 关于 tempString += 你的意思是两者都做同样的事情,还是因为它们是两种不同的风格技术来实现相同的预期结果? += 是实现相同结果的两种不同方式,因此请选择较短的形式。您也可以考虑使用StringBuilder
,因为这会带来轻微的性能优势,并且可能会从您的教练那里获得加分!
我明白了,谢谢你的分享!我快速阅读了 StringBuilder 的用法,我绝对可以看到它的好处。好先生,如果您这么客气的话,您还有最后一件事。您能否详细说明您对我的 main() 中的语句的含义?我一直在修补它,但我仍然有点卡住。我还在学习,我的批判性思维还在发展,所以我有点错过你的观点。
没关系!我重新阅读了您的评论,然后将我的 else 从 main 中删除,现在它很好,很漂亮。感谢您的所有帮助。以上是关于运行hangman(Java)的程序中的逻辑出错的主要内容,如果未能解决你的问题,请参考以下文章