我正在尝试创建一个刽子手游戏。到目前为止,除了一种方法之外,我还能按照自己的意愿工作。此方法称为processGuess
,并将String字母和两个String数组作为参数。第一个数组是一个名为spaceArray
的数组,包含与猜测的单词长度相匹配的下划线(例如:hello产生[ _ , _ , _ , _ , _ ]
)。第二个数组称为wordArray
,包含用户试图猜测的单词。
我设想我的方法工作的方式如下:
guessArray
)guessCounter
)spaceArray
spaceArray
与wordArray
进行比较
一个。如果相等,打印一些说他们赢得x次猜测的东西spaceArray
问题在于,当我回想起这个方法时,它不包含新的字母,但仍包含旧字母。我不确定我做错了什么。这是我第一次尝试在方法中使用方法。
这是我的方法:
public static void main(String[] args) throws FileNotFoundException {
Scanner file = new Scanner(
new File("C:/FilesForJava/ScrabbleDictionary.txt"));
instructions();
String[] dictionary = createDictonaryArray(file);
String[] randomWord = getRandomWord(dictionary);
String[] underscoreArray = showSpaces(randomWord);
String letter = getGuesses();
processGuess(letter, underscoreArray, randomWord);
}
public static void instructions() {
System.out.println("Let's play hangman!");
System.out.println();
}
public static String[] createDictonaryArray(Scanner inputFile)
throws FileNotFoundException {
int wordCount = 0;
while(inputFile.hasNext()) {
String word = inputFile.next();
wordCount++;
}
String[] scrabbleDictionary = new String[wordCount];
Scanner file = new Scanner(
new File("C:/FilesForJava/ScrabbleDictionary.txt"));
while(file.hasNext()) {
for(int i = 0; i < wordCount; i++) {
scrabbleDictionary[i] = file.next();
}
}
file.close();
return scrabbleDictionary;
}
public static String[] getRandomWord(String[] dict) {
String word = dict[(int)(Math.random() * dict.length)];
String[] wordArray = new String[word.length()];
for(int i = 0; i < wordArray.length; i++) {
wordArray[i] = word.trim().substring(0, 1);
word = word.trim().substring(1);
}
return wordArray;
}
public static String[] showSpaces(String[] word) {
String[] spaceArray = new String[word.length];
for(int i = 0; i < word.length; i++) {
spaceArray[i] = "_";
}
System.out.println(Arrays.toString(spaceArray));
System.out.println();
return spaceArray;
}
public static String getGuesses() {
Scanner guess = new Scanner(System.in);
System.out.println("Guess a letter: ");
String letter = guess.next();
System.out.println();
//guess.close();
return letter;
}
public static void processGuess(String letter, String[] spaceArray,
String[] wordArray) {
int guessCounter = 0;
String[] guessArray = new String[spaceArray.length];
for(int i = 0; i < spaceArray.length; i++) {
guessCounter++;
guessArray[i] = letter;
String indexLetter = wordArray[i];
if(indexLetter.equalsIgnoreCase(letter)) {
spaceArray[i] = letter;
}
}
if(spaceArray.equals(wordArray)) {
System.out.println("Yes! You won in " + guessCounter + "guesses!");
}else {
System.out.println(Arrays.toString(spaceArray));
getGuesses();
processGuess(letter, spaceArray, wordArray);
}
}
答案 0 :(得分:1)
您需要将新猜测传递给processGuess
方法。尝试这样的事情:
else {
System.out.println(Arrays.toString(spaceArray));
String newLetter = getGuesses();
processGuess(newLetter, spaceArray, wordArray);
}
答案 1 :(得分:1)
我认为这种方法试图做得太多。它很奇怪,它读取新的输入并递归调用自己 - 我本来希望它的调用者使用一个循环来征求玩家的猜测并调用这个方法(不会递归)。该方法可以通过返回值指示用户是否赢了。
此外,代码似乎过于复杂。例如,guessArray
的重点是什么,你实例化并初始化但从不用于任何东西?
此外,使用字符串数组而不是字符数组很奇怪,因为所有字符串似乎都包含单个字符。 (如果你想要容纳代理人对,那实际上可能是合适的,但是对于任务的水平来说,这样的考虑似乎有点不合时宜。)
无论如何,对你的方法的递归调用只看到猜到的第一个字母的原因是你传递给他们的那个。 getGuesses()
方法不会修改本地letter
变量(它也不能),并且方法本身只传递传递给它的任何内容。
答案 2 :(得分:1)
您已将该方法编写为递归方法(可能不是最好的方法)。问题在于,当递归方法声明局部变量时,递归方法的每次调用都有自己的局部变量副本。
因此,您拨打processGuess
,即可创建guessArray
。然后processGuess
再次调用自己,它有自己的guessArray
,在这发生几次之后,你会有一个看起来像这样的堆栈:
+--------------------------------------------------------+
+ processGuess#1 +
+ local variables: guessCounter#1, guessArray#1, i#1 +
+--------------------------------------------------------+ --> calls:
+ processGuess#2 +
+ local variables: guessCounter#2, guessArray#2, i#2 +
+--------------------------------------------------------+ --> which calls:
+ processGuess#3 +
+ local variables: guessCounter#3, guessArray#3, i#3 +
+--------------------------------------------------------+ --> which calls:
+ processGuess#4 +
+ local variables: guessCounter#4, guessArray#4, i#4 +
+--------------------------------------------------------+
当processGuess#4
修改guessArray
时,它会更改guessArray#4
。但这对guessArray#3
,guessArray#2
或guessArray#1
有无效果。所有这些都是单独的局部变量,它们是引用四个不同对象的引用。因此,当processGuess#4
,processGuess#3
和processGuess#2
都返回时,他们对自己的guessArray
所做的更改将会丢失,并且{ {1}}只会看到它本身对其processGuess#1
所做的更改。
正如我所说,我不会使用递归来解决这个问题。但在递归是正确的做事方式的其他情况下,这肯定是一个问题。解决方案是:(1)将变量或对象声明在外面作为对象中的实例字段 - 然后它们都将访问同一个变量;或者(2)在递归方法中添加一个参数,以便递归调用可以共享对同一对象的引用。
[注意:我添加的guessArray
,#1
数字只是为了帮助解释事情;它们不是任何语言语法或类似内容的一部分。]
答案 3 :(得分:1)
好吧,看起来你可能会遇到一些问题。
首先,对于这种方法,递归是一个非常糟糕的选择,我认为你正在寻找的是一个while循环,当字符串相等时条件会发生变化。当你调用越来越多的方法时,在这里使用递归会不必要地增加堆栈的大小,但永远不会从它们返回。
现在关于你的问题,在你给我们的代码中,变量字母永远不会改变。我假设get猜测返回一个字符串?如果那是真的那么你需要设置相等的字母。
我还建议您使用char而不是字符串。
public static void processGuess(String letter, String[] spaceArray,
String[] wordArray) {
while(true) {
int guessCounter = 0;
String[] guessArray = new String[spaceArray.length];
for (int i = 0; i < spaceArray.length; i++) {
guessCounter++;
guessArray[i] = letter;
String indexLetter = wordArray[i];
if (indexLetter.equalsIgnoreCase(letter)) {
spaceArray[i] = letter;
}
}
if (spaceArray.equals(wordArray)) {
System.out.println("Yes! You won in " + guessCounter + "guesses!");
break;
} else {
System.out.println(Arrays.toString(spaceArray));
letter = getGuesses();
}
}
}