Java刽子手程序出了可怕的错误

Java刽子手程序出了可怕的错误,java,swing,Java,Swing,我是一名Java初学者,需要为Java最终项目整合一个应用程序。我当时想做一个看起来很容易的刽子手。这对我来说非常困难。这是到目前为止我的代码。这真的是一个令人憎恶的大约10个开源的刽子手游戏扔在一起。我的问题见下文 import java.awt.event.*; import java.awt.*; import javax.swing.*; import java.util.ArrayList; public class Hangman implements ActionListen

我是一名Java初学者,需要为Java最终项目整合一个应用程序。我当时想做一个看起来很容易的刽子手。这对我来说非常困难。这是到目前为止我的代码。这真的是一个令人憎恶的大约10个开源的刽子手游戏扔在一起。我的问题见下文

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.ArrayList; 


public class Hangman implements ActionListener {
JFrame frame;
private String[] wordList = {"computer","java","activity","alaska","appearance","article", 
   "automobile","basket","birthday","canada","central","character","chicken","chosen", 
   "cutting","daily","darkness","diagram","disappear","driving","effort","establish","exact", 
   "establishment","fifteen","football","foreign","frequently","frighten","function","gradually", 
   "hurried","identity","importance","impossible","invented","italian","journey","lincoln", 
   "london","massage","minerals","outer","paint","particles","personal","physical","progress", 
   "quarter","recognise","replace","rhythm","situation","slightly","steady","stepped", 
   "strike","successful","sudden","terrible","traffic","unusual","volume","yesterday" }; 
public String mysteryWord; 
public int lives;
private boolean finished = false;
private boolean won = false;
private Button a[];
public boolean used[] = new boolean[26]; 

public static void main (String[] args) {
    Hangman gui = new Hangman();
    gui.go();
    }

class myDrawPanel extends JPanel {
    public void paintComponent(Graphics g) {
     setBackground(Color.white);
     g.setColor(Color.gray);
     g.fillRect(50, 200, 150, 20);
     g.fillRect(90,20,10,200);
     g.fillRect(90,20,60,10);
     g.setColor(Color.black);
     g.fillRect(145,20,5,25);
     g.setColor(Color.green);
        if (lives < 6 )
            g.drawOval(132,45,30,30);
        if (lives < 5 )
            g.drawLine(147,75,147,100);
        if (lives < 4 )
            g.drawLine(147,100,167,133);
        if (lives < 3 )
            g.drawLine(147,100,127,133);
        if (lives < 2 )
            g.drawLine(147,75,167,85);
        if (lives < 1 )
            g.drawLine(147,75,127,85);

            StringBuffer guessed = new StringBuffer();

            for (int cl = 0; cl < mysteryWord.length(); cl++) {
                    if (used[(int)mysteryWord.charAt(cl)-65])
                            guessed.append(mysteryWord.charAt(cl));
                    else
                            guessed.append(".");
                    }

            g.drawString(guessed.toString(),75,230);
                 //currentWordLA.setText("Current word: " + mysteryWord);



         if (lives < 1) {
            g.setColor(Color.white);
            g.fillRect(70, 200, 200, 30);
            g.setColor(Color.black);
            g.drawString(mysteryWord.toString(),75,230);
            Font fff = new Font("Helvetica",Font.BOLD,36);
            g.setFont(fff);

            g.setColor(Color.red);
            g.drawString("You lose!",200,100);

            finished = true;
            }

         if (won) {
            Font fff = new Font("Helvetica",Font.BOLD,36);
            g.setFont(fff);

//                Color red=new Color.red
            g.setColor(Color.red);

            g.drawString("You Win!",200,100);
            finished = true;
            }
  }
 }

public void go() {

///////////////////////DESIGN BEGIN//////////////////////////////////////////////
    frame = new JFrame("Hangman");
    JPanel topPanel = new JPanel();
    myDrawPanel noosePanel = new myDrawPanel();
    JPanel bottomPanel = new JPanel();
    JPanel scorePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout( new GridLayout( 2, 0) );
    bottomPanel.setLayout( new GridLayout( 0, 2) );
    scorePanel.setSize(20,100);

    noosePanel.setBorder(BorderFactory.createTitledBorder("Your progress.")); 
    topPanel.setBorder(BorderFactory.createTitledBorder("Your arsenal.")); 
    scorePanel.setBorder(BorderFactory.createTitledBorder("Your score.")); 
    frame.add(topPanel);
    frame.add(bottomPanel);
    bottomPanel.add(scorePanel);
    bottomPanel.add(noosePanel);

//Just the stats panel.
    JPanel stats = new JPanel();
    JLabel currentWordLA = new JLabel("Current word:");
    JLabel triedLettersLA = new JLabel("Tried letters:");
    JLabel triesLeftLA = new JLabel("Tries remaining:");
    JButton restart = new JButton("Reset");

        currentWordLA.setFont(new Font("Verdana", Font.PLAIN, 10));
        currentWordLA.setForeground(Color.black);
        triedLettersLA.setFont(new Font("Verdana", Font.PLAIN, 10));
        triedLettersLA.setForeground(Color.black);
        triesLeftLA.setFont(new Font("Verdana", Font.PLAIN, 10));
        triesLeftLA.setForeground(Color.black);
        restart.setFont(new Font("Verdana", Font.PLAIN, 16));
        restart.setForeground(Color.red);

            stats.setLayout(new GridBagLayout()); 
            GridBagConstraints c = new GridBagConstraints(); 
            c.gridx = 0; 
            c.gridy = 0; 
            c.insets = new Insets(20,0,0,0); 
            c.anchor = GridBagConstraints.LINE_START;
            stats.add(currentWordLA, c); 
            c.gridx = 0; 
            c.gridy = 1; 
            c.anchor = GridBagConstraints.LINE_START;
            stats.add(triedLettersLA, c); 
            c.gridx = 0; 
            c.gridy = 2; 
            c.anchor = GridBagConstraints.LINE_START;
            stats.add(triesLeftLA, c); 
            c.gridx = 0; 
            c.gridy = 3; 
            c.anchor = GridBagConstraints.LINE_START;
            stats.add(restart, c); 
            scorePanel.add(stats);
///////////////////////DESIGN END////////////////////////////////////////////// 
///////////////////////ALPHABET BEGIN//////////////////////////////////////////
    int i;
    StringBuffer buffer;
    a = new Button[26];
    topPanel.setLayout( new GridLayout( 4,0, 10, 10) );
    for (i = 0; i <26; i++) {
           buffer = new StringBuffer();
            buffer.append((char)(i+65));
            a[i] = new Button(buffer.toString());
            a[i].setSize(100,100);
            a[i].addActionListener( this );
          topPanel.add(a[i]);
        }
///////////////////////ALPHABET END//////////////////////////////////////////
//Just shows the entire window.                  
    frame.setSize(500, 500);
    frame.setResizable(false);
    frame.setVisible(true);
//////////////////////GAMEPLAY BEGIN////////////////////////////////////////
    lives = 6;
    mysteryWord = wordGen();


}


//Returns a random word from the wordList bank.
    private String wordGen() {
        return wordList[0 + (int)(Math.random() * ((63 - 0) + 1)) ]; //Make sure to set these to nonprinted chars eventually
    }

    public void consultWord(int letter) {
        if (finished == false) {
            boolean found = false;
        boolean www = false;
                if (used[letter] = false) {
                for (int cl = 0 ; cl < mysteryWord.length(); cl++) {
                if (mysteryWord.charAt(cl)==((char)(letter+65))) found = true;
            }
            if (found == false) 
                    lives = lives - 1;
                }
    used[letter] = true;
            for (int cl = 0; cl < mysteryWord.length(); cl++) {
          if (!used[(int)(mysteryWord.charAt(cl)) - 65]) www = true;
            }
            if (www = false) won = true;        
            frame.repaint();
    }
    }

    public void actionPerformed( ActionEvent e) {
        int i;
        for (i = 0; i < 26; i++) {
            if (e.getSource() == a[i]) { 
            consultWord(i); }
  }
}       
}
我不确定这条线有什么问题。另外,原作者使用了数字65。我调整了我的代码并使用了我自己的变量,以便我理解它是如何工作的。但是65这个数字和它的来源,我一辈子都搞不清楚。有什么想法吗

我需要知道导致所有线程异常的原因。GUI构建得很好。只是所有的数学和触发器把事情搞砸了。我自己制作的GUI!:

例外情况


65是字母“A”的ASCII字符代码。所讨论的行正在从ASCII序数值转换为0-25范围内的值,这允许使用的数组存储字母表中的每个字母是否已检查。

65是字母“A”的ASCII字符代码。所讨论的行正在从ASCII序号值转换为0-25范围内的值,这允许使用的数组存储字母表中的每个字母是否已被检查。

这通常不是对您问题的直接回答,但它与学习编写软件的更大问题有关。。。这是你的总体目标。在底部有一个真正的答案

你写道:

这真的是一个令人憎恶的大约10个开源的刽子手游戏扔在一起

将一堆质量可疑的现有程序混合在一起并不是创建软件的好方法

您继承了已获取的现有代码中的功能和样式问题。 您添加了一系列新的功能和样式问题,这些问题是由不同代码基之间的不匹配引起的。。。还有你的构想。 代码重用可能是一件好事,但您需要遵守规则并有选择性:

设计你自己的代码。。。遵循所学的设计原则。 使用精心设计的库,在库级别进行重用。 不要通过复制和粘贴重复使用。 不要重复使用看起来像狗的早餐的代码或库。如果作者对自己的代码风格和API设计马虎,这对于其他质量问题来说是一个坏兆头。 *事实上,代码中嵌入了像65这样的模糊数字,这表明代码质量很差。作者可以也应该把它写成“A”

事实上,这可能是你的bug的根源,因为看起来你的神秘词是小写的'-'a'是32,大于所用数组的边界


这让我们回到我的主要观点。因为,很明显,在你的代码混搭中,你没有理解你复制的代码的隐含不变量。。。并打破了它们。引发异常的有问题语句旨在处理仅大写的单词。。。但你改变了这一点

这并不是对你问题的直接回答,但它与学习编写软件这一更大的问题有关。。。这是你的总体目标。在底部有一个真正的答案

你写道:

这真的是一个令人憎恶的大约10个开源的刽子手游戏扔在一起

将一堆质量可疑的现有程序混合在一起并不是创建软件的好方法

您继承了已获取的现有代码中的功能和样式问题。 您添加了一系列新的功能和样式问题,这些问题是由不同代码基之间的不匹配引起的。。。还有你的构想。 代码重用可能是一件好事,但您需要遵守规则并有选择性:

设计你自己的代码。。。遵循所学的设计原则。 使用精心设计的库,在库级别进行重用。 不要通过复制和粘贴重复使用。 不要重复使用看起来像狗的早餐的代码或库。如果作者对自己的代码风格和API设计马虎,这对于其他质量问题来说是一个坏兆头。 *事实上,代码中嵌入了像65这样的模糊数字,这表明代码质量很差。作者可以也应该把它写成“A”

事实上,这可能是你的bug的根源,因为看起来你的神秘词是小写的'-'a'是32,大于所用数组的边界

这让我们回到我的主要观点。因为,很明显,在你的代码混搭中,你没有理解你复制的代码的隐含不变量。。。并打破了它们。引发异常的有问题语句旨在处理仅大写的单词。。。但你改变了这一点

变化

if (used[(int)mysteryWord.charAt(cl)-65])
    guessed.append(mysteryWord.charAt(cl));
else
    guessed.append(".");
}

if (used[(int)mysteryWord.charAt(cl)-97])
    guessed.append(mysteryWord.charAt(cl));
else
    guessed.append(".");
}
转换为ASCII时,第55行的代码为en 使用大于所用数组大小的值进行加密。

更改

if (used[(int)mysteryWord.charAt(cl)-65])
    guessed.append(mysteryWord.charAt(cl));
else
    guessed.append(".");
}

if (used[(int)mysteryWord.charAt(cl)-97])
    guessed.append(mysteryWord.charAt(cl));
else
    guessed.append(".");
}


当转换为ASCII时,第55行的代码的值大于所用数组的大小。

65是“a”的ASCII,但您的字都是小写的。因此,您不应该使用intmysteryWord.charAtcl-65,而应该使用intmysteryWord.charAtcl-'a'

65是表示'a'的ASCII,但您的单词都是小写的。因此,您不应该使用intmysteryWord.charAtcl-65,而应该使用intmysteryWord.charAtcl-'a'

抛出哪些特定异常?你有没有可能在控制台中包含堆栈跟踪?哦,很好-我看到了可怕的错误,认为有人意外地被你的程序绞死了。在苏联,刽子手程序绞死了你:-当然!我可以告诉你所有的例外情况。但是字符数太多,无法包含在这里。你想让我给你看什么?我正在调试它。。或者,我应该说。。我正在尝试找出如何使用调试程序。感谢所有的帮助。我会继续登记的。感谢您正在抛出哪些特定异常?你有没有可能在控制台中包含堆栈跟踪?哦,很好-我看到了可怕的错误,认为有人意外地被你的程序绞死了。在苏联,刽子手程序绞死了你:-当然!我可以告诉你所有的例外情况。但是字符数太多,无法包含在这里。你想让我给你看什么?我正在调试它。。或者,我应该说。。我正在尝试找出如何使用调试程序。感谢所有的帮助。我会继续登记的。谢谢,好的,这很有道理。但我还是不明白它为什么会断裂。可能是因为used[]是一个布尔数组,它使用int?啊,好的,这很有意义。但我还是不明白它为什么会断裂。也许是因为used[]是一个布尔数组,并且它使用int?我真的很欣赏这一点。我自己绘制了我的程序,自己创建了GUI。对于每个功能,我都必须在互联网上搜索类似的东西。虽然我复制/粘贴了它,但我确实检查了每一行来修改它,使它适合我的代码&以确保我理解它。我想我没那么热。哈哈!好的,我将抓取ASCII并重写它以使用普通的旧小写字母。我真的很感激你的建议@EnkeiRC5——鉴于此,您在报价中对自己代码的描述过于负面。无论如何,我坚持我关于剪切粘贴编程问题的一般建议。我真的很感激这一点。我自己绘制了我的程序,自己创建了GUI。对于每个功能,我都必须在互联网上搜索类似的东西。虽然我复制/粘贴了它,但我确实检查了每一行来修改它,使它适合我的代码&以确保我理解它。我想我没那么热。哈哈!好的,我将抓取ASCII并重写它以使用普通的旧小写字母。我真的很感激你的建议@EnkeiRC5——鉴于此,您在报价中对自己代码的描述过于负面。无论如何,对于剪切粘贴编程的问题,我坚持我的一般建议。