1

私は 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

4 に答える 4

6

これはほとんどあなたの質問に対する直接的な答えではありませんが、ソフトウェアの書き方を学ぶというより大きな問題に関連しています...それがあなたの全体的な目標です。(そして、一番下に本当の答えがあります。)

あなたが書く:

(これは、約 10 のオープンソースの絞首刑執行人ゲームを一緒に投げたものです)

既存のプログラム (質が疑わしい *) をたくさん集めてマッシュアップすることは、ソフトウェアを作成する良い方法ではありません。

  • 「収集」した既存のコードの機能とスタイルの問題を継承します。
  • さまざまなコードベースとあなたの概念との間の不一致によって引き起こされる新しい機能とスタイルの問題をたくさん追加します。

コードの再利用良いことですが、規律と選択が必要です。

  • 教えられた設計原則に従って、独自のコードを設計してください。
  • よく設計されたライブラリを使用して、ライブラリ レベルで再利用します。
  • コピペによる再利用はご遠慮ください。
  • 犬の朝食のように見えるコード (またはライブラリ) を再利用しないでください。(作成者が自分のコード スタイルと API 設計でだらしない場合、それは他の品質の問題の悪い兆候です。)

(* コードに 65 のようなあいまいな数字が埋め込まれているという事実は、コードの品質が低いことを示しています。作成者はそれを'A'.

実際、これがバグの原因である可能性があります。「謎の」単語が小文字になっているように見えるからです。 'a' - 'A'であり、それは配列32の境界よりも大きいです。used

そして、これで私の要点に戻ります。どうやら、コードのマッシングでは、コピーしたコードの暗黙の不変条件を理解できず、それらを壊してしまったようです。例外をスローしている問題のあるステートメントは、大文字のみの単語で動作するように設計されています...しかし、それを変更しました。

于 2012-05-07T02:49:47.793 に答える
1

65は「A」のASCIIですが、単語はすべて小文字です。したがって、の代わりに(int)mysteryWord.charAt(cl)-65(int)mysteryWord.charAt(cl)-'a'

于 2012-05-07T03:02:57.523 に答える
1

65 は文字「A」の ASCII 文字コードです。問題の行は、ASCII の序数の値から 0 ~ 25 の範囲の何かに変換しています。これusedにより、アルファベットの各文字がチェックされているかどうかを配列に格納できます。

于 2012-05-07T02:11:33.687 に答える
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に変換すると、使用されている配列のサイズよりも大きい値になります。

于 2012-05-07T03:00:22.517 に答える