刽子手代码卡在三个不同的问题上

Posted

技术标签:

【中文标题】刽子手代码卡在三个不同的问题上【英文标题】:Hangman code stuck on three different problems 【发布时间】:2015-12-07 00:16:16 【问题描述】:

我正在尝试制作一个刽子手游戏。在每一轮,用户猜测一个字母。如果他们猜对了,他们可以再猜一次。否则,他们剩余的可用猜测值会减一,并将猜测到的字母放入一个数组中。

当用户的剩余猜测数为零时,程序应该询问他们是否想再玩一次。如果他们回答是,则应该重新启动游戏,如果他们回答不是,则程序结束。

我遇到的问题是保存猜测的数组以及重新启动游戏。

另外,程序在启动时会偶尔出错。错误是

Hangman1.main(Hangman1.java:27) 的线程“main”java.lang.NullPointerException 中的异常

尝试重新启动游戏时的错误是

Hangman1.main(Hangman1.java:101) 的线程“main”java.lang.NullPointerException 中的异常

searchArray 是应该采用 char 数组的位置并将其复制到星号数组并返回星号数组的方法,这似乎不起作用。运行调试似乎导致程序崩溃的问题是单词有时会以null结尾,但只是有时,我真的不知道为什么

import java.util.*;
import java.io.*;

public class Hangman1 

    static Scanner keyboard = new Scanner(System.in);
    public static final int MAXSIZE = 15000;
    public static final int NUM_GUESS = 8;
    public static final int WORD_LENGTH = 20;

    public static void main(String[] args) 
        int random = pickrandom(MAXSIZE); 

        try 
            // Set up connection to the input file
            Scanner input = new Scanner(new FileReader("dictionary.txt"));

            instructions();
            keyboard.nextLine(); 
            clearScreen();

            String word = randomWord(input, random);

            System.out.println(word);
            String[] charArray = word.split("");

            System.out.print("\n");
            String[] asterisk = asteriskLine(word);

            String decision = "Y"; 
            //decision = keyboard.nextLine().toUpperCase();

            System.out.println("Word to guess :");
            for (int count = 0; count < word.length(); count++)  
                System.out.print(asterisk[count]); 
            
            System.out.print("\n");

            int tries = NUM_GUESS; 

            System.out.println("Enter a letter to guess or 9 to quit");
            String guess = keyboard.next();
            String[] wrongGuesses = new String [NUM_GUESS];

            int guessMade = 0;
            do 
                //System.out.println(tries); 
                while (!(guess.equals("9")) && !(guess.equals(word))  && (tries > 0))
                
                    String letter = guess.substring(0,1); 

                    if (word.indexOf(letter) < 0) 
                        clearScreen();

                        tries--;

                        wrongGuesses = wrongGuesses(guessMade, wrongGuesses, letter);

                        printArray(asterisk, charArray, word, tries, wrongGuesses, guessMade);
                        guessMade++;
                        guess = keyboard.next();
                    
                    else   
                        clearScreen();
                        asterisk = searchArray(charArray, asterisk, guessMade, letter, word);
                        printArray(asterisk, charArray, word, tries, wrongGuesses, guessMade); 
                        guess = keyboard.next();
                    

                    if (charArray == asterisk) 
                        System.out.println("You won!");
                    

                    if (tries == 0) 
                        System.out.println("You have no more guesses left"); 
                    

                
                if (guess.equals("9")) 
                    System.out.println("Thanks for playing");
                

                System.out.println("Play again? Y/N");

                decision = keyboard.next().toUpperCase();
                if (decision.equals("Y")) 
                    random = pickrandom(MAXSIZE);
                    word = randomWord(input, random);
                    charArray = word.split("");

                    System.out.print("\n");
                    asterisk = asteriskLine(word);
                    guess = keyboard.next();
                


             while (decision.equals("Y"));
            //System.out.println("Play again? Y/N");
            //decision = keyboard.nextLine().toUpperCase();
        

        catch (FileNotFoundException e) 
            System.out.println("There was an error opening one of the files.");
        
    

    //Clears screen after introduction 
    private static void clearScreen() 
        for (int blanks = 0; blanks < 80; blanks++) 
            System.out.println();
        
    

    // This method returns a randomly selected integer
    // between 0 and count-1
    public static int pickrandom(int count) 
        Random generator = new Random();
        return generator.nextInt(count);
    

    // Places asterisks in place of the letters in the word
    // Parameter is the string word. it holds mystery word

    public static String[] asteriskLine(String word) 
        int i;
        String[] asteriskArray = new String [word.length()];
        for (i = 0; i < word.length(); i++) 

            asteriskArray[i] = "* ";
        
        return asteriskArray;
    

    public static void instructions() 
        System.out.println("              H A N G M A N. "
            + "\n This is a word guessing game. "
            + "\n A word will be selected at random and kept hidden. You will try to figure out the secret word by"
            + "\n guessing letters which you think are in the word. "
            + "\n You will guess one letter at a time. "
            + "\n If the letter you guess is correct, the position(s) of the letter in the secret word will be shown. "
            + "\n You will be allowed "
            + NUM_GUESS
            + " wrong guesses  If you guess incorrectly "
            + NUM_GUESS
            + " times, you lose the game. "
            + "\n If you guess all of the letters in the word, you win."
            + "\n\n Press enter to continue ");
    

    public static String randomWord(Scanner input, int random) 
        String[] dictionaryWords = new String [MAXSIZE];
        int usedsize = 0;
        while (usedsize < MAXSIZE && input.hasNextLine()) 
            dictionaryWords[usedsize] = input.nextLine();
            usedsize++; 
        

        String word = dictionaryWords[random];
        return word;
    

    //Replaces correct guess in blanks 
    public static String correctWord(String guess, String word, String asterisk, char letter)  
        return null;
    

    public static void printArray(String[] asterisk, String[] charArray, String word, int tries, String[] wrongGuesses, int guessMade) 
        System.out.println("Word to guess");
        for (int count = 0; count < word.length(); count++)  
            System.out.print(asterisk[count]); 
        

        System.out.println("\nGuesses remaining: " + tries);

        System.out.print("Incorrect letters tried: ");
        for (int count = 0; count <= guessMade; count++)  
            System.out.print(wrongGuesses[count] + " "); 
        
        System.out.println("\nEnter a letter to guess or 9 to quit");

    

    public static String[] wrongGuesses(int guessMade, String [] wrongGuesses, String letter) 
        wrongGuesses[guessMade] = letter;
        return wrongGuesses;
    

    public static String[] searchArray(String[] charArray, String[] asterisk, int guessMade, String letter, String word) 
        int[] a = new int[word.length()];
        for (int count = 0; count < word.length(); count++)  
            if (letter == charArray[count]) 
                asterisk[count] = charArray[count]; 
            
        
        return asterisk;

    

【问题讨论】:

如果您对解决 NullPointerException (NPE) 进行了一些搜索,那么您就会知道我们需要的最重要的信息是异常的相关堆栈跟踪和一些确切的标识导致它的行,堆栈跟踪会告诉你的东西。请发布此信息,以便我们为您提供帮助。 为什么这如此重要? NullPointerExceptions 的启发式方法几乎总是相同的。 您应该认真阅读异常的堆栈跟踪,找出出错的代码行、引发异常的行,然后仔细检查该行,找出哪个变量为空,然后回溯到您的代码看看为什么。你会一次又一次地遇到这些,相信我。以后,请在发帖前搜索该主题,因为这个问题太常见了,不能再发一个 NPE 问题。 我把它放在帖子的最后,说这个词变成了空值,我是一个初学者,所以我不太确定堆栈跟踪是什么,但错误是第 27 行。有人告诉我那是因为我在 [0, MAXSIZE) 范围内选择了一个随机数,但数组中的字数可能少于 MAXSIZE,但不是如何修复它,这不是我唯一的问题 请发布实际堆栈跟踪,错误消息的完整文本。 这就是出错时弹出的所有内容,这是当用户点击 Y 重新启动游戏时出现的错误。线程“main”中的异常 java.lang.NullPointerException at Hangman1.main( Hangman1.java:101) 【参考方案1】:

您需要做的一件事是一次且仅一次读取所有单词,并将它们全部存储到 ArrayList 中。您当前的代码尝试重新使用已使用的 Scanner 对象,这将失败。而是从ArrayList&lt;String&gt; 获取您的随机词。

【讨论】:

我必须为我的班级的程序使用 randomGenerator。大多数情况下,我所做的一切都是老师解释如何做的(初学者),所以事情越深入,我就越困惑 @SillyRabbit-3:当然,使用随机生成器,但要使用一个使用ArrayList&lt;String&gt; 的随机生成器,它是在程序启动时创建的。否则,您要么重复 NPE,要么需要一遍又一遍地从头开始重新读取文件。 我必须使用该方法,具体是我无法更改的地方。如果您知道如何在随机生成器方法之后修复它,那将是涂料【参考方案2】:

运行调试似乎导致程序崩溃的问题是 这个词有时会以空结尾,但只是有时,我不会 真的知道为什么

 public static String randomWord(Scanner input, int random) 
        String[] dictionaryWords = new String [MAXSIZE];
        int usedsize = 0;
        while (usedsize < MAXSIZE && input.hasNextLine()) 
            dictionaryWords[usedsize] = input.nextLine();
            usedsize++; 
        

        String word = dictionaryWords[random];
        return word;
    

有时random 会大于usedsize。 所以你需要把这条线从循环外移开

 int random = pickrandom(MAXSIZE); 

进入这个函数,并且有最大值被使用大小(或usedsize-1)。

您可以通过编写单元测试来保护自己免受此错误的影响,并确定您应该使用 usedsize 还是 usedsize-1。查看 Junit 教程。

在您的 junit 测试中,调用 randomword 并为它传递一个非常高的随机值。那么

assert(word!= null)

当 random 长于字典长度时,Word 为空。

【讨论】:

以上是关于刽子手代码卡在三个不同的问题上的主要内容,如果未能解决你的问题,请参考以下文章

刽子手实现[重复]

JFrame 中的所有组件均未显示

当单击不同数组中的另一个单独项目同时从第一个数组中删除该项目时,从一个数组中随机显示项目?

初学者的python刽子手代码

基本的 C 刽子手代码问题

如何在标签中显示数组