2012-05-07 46 views
1

我是Java的初学者,并被要求为Java最终项目拼凑一个应用程序。我想做hang子手(当时看起来很简单)。这对我来说极其困难。这是我的代码到目前为止。 (这真的是大约10个开源hang子手游戏一起被抛出的可憎)。见我的问题底部。爪哇hang子手程序错过了可怕的错误

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构建得很好。这只是所有的数学和触发器搞砸了。 (图形用户界面我建立全部由我自己!:))

异常

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) 
+0

什么具体例外被抛出?你有可能从控制台中包含堆栈跟踪吗? – derekerdmann

+7

噢,不错 - 我看到“可怕的错误”,并认为有人不小心被你的程序吊死。 –

+0

“在苏联俄罗斯,Hang子手程序挂你”:-) –

回答

1

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

+0

好吧,这是非常有道理的。但我似乎仍然无法理解它为何破裂。也许是因为used []是一个布尔数组,它使用一个int? – EnkeiRC5

6

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

你写:

(它的真正的约10开源刽子手游戏放在一起可憎的)

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

  • 您在现有代码中继承了“收获”功能和样式的问题。
  • 您添加了一堆新的功能和风格问题,这些问题是由不同的代码库和您的构想之间的不匹配造成的。

代码重用可以一件好事,但你必须遵守纪律和选择性:

  • 设计自己的代码......下面,你被教导的设计原则。
  • 在图书馆级别重复使用,使用精心设计的库。
  • 请勿通过复制粘贴重复使用。
  • 不要重复看起来像狗的早餐的代码(或库)。 (如果作者对他/她的代码风格和API设计sl,不驯,这对其他质量问题是一个不好的迹象。)

(*您看到像65嵌入代码晦涩号码实际上是代码的低质量的标志,作者可能和应该写,作为'A')。

事实上,这可能是你的bug的根源,因为它看起来像你的“神秘”的单词是小写的。 'a' - 'A'32,并且大于used阵列的范围。

这使我们回到我的主要观点。因为,显然,在你的代码混搭中,你无法理解你复制的代码的隐含不变式......并将其破坏。抛出异常的问题语句被设计为只能处理大写字母......但您已经改变了这一点。

+0

+1这里肯定是最明智的答案。 –

+0

我真的很感激。我自己制定了我的程序,并自己创建了GUI。对于每个“功能”,我不得不在互联网上搜索类似的东西。虽然我做了复制/粘贴,但我通过每一行来修改它,以便它符合我的代码并确保我能理解它。我想我没那么热。哈哈!好的,我将抓取ASCII并重写它以使用普通的旧小写字母。我真的很感谢你的建议! – EnkeiRC5

+0

@ EnkeiRC5 - 鉴于此,您对自己的代码(在您的报价中)的描述过于消极。无论如何,我支持我关于剪贴式编程问题的一般建议。 –

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时,以比使用数组的大小大的值结束了。

+0

非常感谢! :) – EnkeiRC5

1

65是'A'的ASCII码,但您的文字全部是小写。所以,而不是(int)mysteryWord.charAt(cl)-65,你应该做(int)mysteryWord.charAt(cl)-'a'