Java hangman程序出现了可怕的错误

时间:2012-05-07 02:08:07

标签: java swing

我是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); }
  }
}       
}

目前这不起作用。我运行它,并出现大量的线程执行错误。 (它汇编得很漂亮)。它带我的第一行是

if (used[(int)mysteryWord.charAt(cl)-65])

我不确定这条线的问题是什么。此外,原作者使用了数字65.我调整了我的代码并使用了我自己的变量,以便我理解它是如何工作的。但65号和它来自哪里,我无法弄清楚我的生活。有什么想法吗?

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

异常

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 34
    at Hangman$myDrawPanel.paintComponent(Hangman.java:55)
    at javax.swing.JComponent.paint(JComponent.java:1054)
    at javax.swing.JComponent.paintChildren(JComponent.java:887)
    at javax.swing.JComponent.paint(JComponent.java:1063)
    at javax.swing.JComponent.paintChildren(JComponent.java:887)
    at javax.swing.JComponent.paint(JComponent.java:1063)
    at javax.swing.JComponent.paintChildren(JComponent.java:887)
    at javax.swing.JComponent.paint(JComponent.java:1063)
    at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
    at javax.swing.JComponent.paintChildren(JComponent.java:887)

4 个答案:

答案 0 :(得分:6)

这主要不是你问题的直接答案,但它与学习编写软件的大问题有关......这是你的总体目标。 (底部有一个真正的答案。)

你写道:

  

(这真是令人厌恶的大约10个开源刽子手游戏)

将一堆现有的程序(质量可疑*)与它们混合在一起并不是创建软件的好方法。

  • 您继承了“已收获”的现有代码中的功能和样式问题。
  • 您添加了一系列由不同代码库之间的不匹配导致的新功能和样式问题......以及您的构想。

代码重用可以是一件好事,但你需要有纪律和有选择性:

  • 设计您自己的代码......遵循您所教授的设计原则。
  • 使用精心设计的库在库级别重复使用。
  • 不要通过复制粘贴重复使用。
  • 不要重复使用看起来像狗早餐的代码(或库)。 (如果作者对他/她的代码风格和API设计很草率,这对其他质量问题来说是个坏兆头。)

(*您看到代码中嵌入了65个隐藏的数字这一事实表明代码质量很差。作者可以而且应该将其写为'A'。)

事实上,这可能是你的bug的根源,因为看起来你的“神秘”字是小写的。 'a' - 'A'32,且大于used数组的范围。

这让我们回到了我的主要观点。因为,显然,在您的代码混搭中,您无法理解您复制的代码的隐含不变量......并打破了它们。抛出异常的有问题的语句被设计为使用仅大写的单词...但是你已经改变了。

答案 1 :(得分:1)

65是字母'A'的ASCII字符代码。有问题的行是从ASCII序数值转换为0-25范围内的值,这允许used数组存储是否已检查字母表中的每个字母。

答案 2 :(得分:1)

65是'A'的ASCII,但你的单词都是小写的。因此,您应该(int)mysteryWord.charAt(cl)-65

而不是(int)mysteryWord.charAt(cl)-'a'

答案 3 :(得分:0)

变化

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(".");
}

第55行的代码,当转换为ASCII时,最终会得到一个大于所用数组大小​​的值。