0

首先,我想说感谢您的帮助。我对 Java 编程比较陌生。我构建了一个简单的井字游戏,但遇到了一些麻烦。

每隔一段时间,“X”或“O”就会连续播放两次。我有一个布尔变量,当每个玩家轮流时,它应该从 true 切换为 false 以将“X”更改为“O”,但由于某种原因,它不会随机切换。

我认为这可能是 Eclipse 或其他问题,因为我不明白它为什么会这样做。

下面是游戏的代码:

public class gameMain {

    Boolean player = true;
    JPanel gameBoard;
    JButton[] b = new JButton[10];
    Font font = new Font("Arial", Font.BOLD, 99);
    ListenForButtons lfb = new ListenForButtons();

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new gameMain();
            }
        });
    }

    public gameMain() {
        JFrame j = new JFrame("TicTacToe");
        j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        j.setLocationRelativeTo(null);
        j.setSize(400, 400);

        gameBoard = new JPanel();
        gameBoard.setLayout(new GridLayout(3, 3));

        b[1] = new JButton("");
        b[1].addActionListener(lfb);
        b[1].setContentAreaFilled(false);
        b[1].setFont(font);
        b[1].setBorder(BorderFactory.createMatteBorder(0, 0, 2, 2, Color.BLACK));
        b[2] = new JButton("");
        b[2].addActionListener(lfb);
        b[2].setContentAreaFilled(false);
        b[2].setFont(font);
        b[2].setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, Color.BLACK));
        b[3] = new JButton("");
        b[3].addActionListener(lfb);
        b[3].setContentAreaFilled(false);
        b[3].setFont(font);
        b[3].setBorder(BorderFactory.createMatteBorder(0, 2, 2, 0, Color.BLACK));
        b[4] = new JButton("");
        b[4].addActionListener(lfb);
        b[4].setContentAreaFilled(false);
        b[4].setFont(font);
        b[4].setBorder(BorderFactory.createMatteBorder(0, 0, 0, 2, Color.BLACK));
        b[5] = new JButton("");
        b[5].addActionListener(lfb);
        b[5].setContentAreaFilled(false);
        b[5].setFont(font);
        b[5].setBorder(BorderFactory.createMatteBorder(0, 0, 0, 0, Color.BLACK));
        b[6] = new JButton("");
        b[6].addActionListener(lfb);
        b[6].setContentAreaFilled(false);
        b[6].setFont(font);
        b[6].setBorder(BorderFactory.createMatteBorder(0, 2, 0, 0, Color.BLACK));
        b[7] = new JButton("");
        b[7].addActionListener(lfb);
        b[7].setContentAreaFilled(false);
        b[7].setFont(font);
        b[7].setBorder(BorderFactory.createMatteBorder(2, 0, 0, 2, Color.BLACK));
        b[8] = new JButton("");
        b[8].addActionListener(lfb);
        b[8].setContentAreaFilled(false);
        b[8].setFont(font);
        b[8].setBorder(BorderFactory.createMatteBorder(2, 0, 0, 0, Color.BLACK));
        b[9] = new JButton("");
        b[9].addActionListener(lfb);
        b[9].setContentAreaFilled(false);
        b[9].setFont(font);
        b[9].setBorder(BorderFactory.createMatteBorder(2, 2, 0, 0, Color.BLACK));

        gameBoard.add(b[1]);
        gameBoard.add(b[2]);
        gameBoard.add(b[3]);
        gameBoard.add(b[4]);
        gameBoard.add(b[5]);
        gameBoard.add(b[6]);
        gameBoard.add(b[7]);
        gameBoard.add(b[8]);
        gameBoard.add(b[9]);

        j.add(gameBoard);
        j.setVisible(true);
    }

    public class ListenForButtons implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            if (e.getSource() == b[1]) {
                setSquare(b[1]);
            }
            if (e.getSource() == b[2]) {
                setSquare(b[2]);
            }
            if (e.getSource() == b[3]) {
                setSquare(b[3]);
            }
            if (e.getSource() == b[4]) {
                setSquare(b[4]);
            }
            if (e.getSource() == b[5]) {
                setSquare(b[5]);
            }
            if (e.getSource() == b[6]) {
                setSquare(b[6]);
            }
            if (e.getSource() == b[7]) {
                setSquare(b[7]);
            }
            if (e.getSource() == b[8]) {
                setSquare(b[8]);
            }
            if (e.getSource() == b[9]) {
                setSquare(b[9]);
            }
            checkForWin();
        }
    }

    public void setSquare(JButton button) {
        if (player) {
            button.setText("X");
            player = false;
            button.removeActionListener(lfb);
        } else {
            button.setText("O");
            player = true;
            button.removeActionListener(lfb);
        }
    }

    public void checkForWin() {
        if ((b[1].getText().equals("X") && b[2].getText().equals("X") && b[3].getText().equals("X"))
                || (b[4].getText().equals("X") && b[5].getText().equals("X") && b[6].getText().equals("X"))
                || (b[7].getText().equals("X") && b[8].getText().equals("X") && b[9].getText().equals("X"))
                || (b[1].getText().equals("X") && b[4].getText().equals("X") && b[7].getText().equals("X"))
                || (b[2].getText().equals("X") && b[5].getText().equals("X") && b[8].getText().equals("X"))
                || (b[3].getText().equals("X") && b[6].getText().equals("X") && b[9].getText().equals("X"))
                || (b[1].getText().equals("X") && b[5].getText().equals("X") && b[9].getText().equals("X"))
                || (b[3].getText().equals("X") && b[5].getText().equals("X") && b[7].getText().equals("X"))) {
            JOptionPane.showMessageDialog(null, "X WINS THE GAME!", "", JOptionPane.INFORMATION_MESSAGE);
            resetBoard();
        } else if ((b[1].getText().equals("O") && b[2].getText().equals("O") && b[3].getText().equals("O"))
                || (b[4].getText().equals("O") && b[5].getText().equals("O") && b[6].getText().equals("O"))
                || (b[7].getText().equals("O") && b[8].getText().equals("O") && b[9].getText().equals("O"))
                || (b[1].getText().equals("O") && b[4].getText().equals("O") && b[7].getText().equals("O"))
                || (b[2].getText().equals("O") && b[5].getText().equals("O") && b[8].getText().equals("O"))
                || (b[3].getText().equals("O") && b[6].getText().equals("O") && b[9].getText().equals("O"))
                || (b[1].getText().equals("O") && b[5].getText().equals("O") && b[9].getText().equals("O"))
                || (b[3].getText().equals("O") && b[5].getText().equals("O") && b[7].getText().equals("O"))) {

            JOptionPane.showMessageDialog(null, "O WINS THE GAME!", "", JOptionPane.INFORMATION_MESSAGE);
            resetBoard();
        } else if (!b[1].getText().equals("") && !b[2].getText().equals("") && !b[3].getText().equals("")
                && !b[4].getText().equals("") && !b[5].getText().equals("") && !b[6].getText().equals("")
                && !b[7].getText().equals("") && !b[8].getText().equals("") && !b[9].getText().equals("")) {
            JOptionPane.showMessageDialog(null, "Cats Game!", "", JOptionPane.INFORMATION_MESSAGE);
            resetBoard();
        }
    }

    public void resetBoard() {
        for (int i = 1; i <= b.length - 1; i++) {
            b[i].setText("");
        }
        for (int i = 1; i <= b.length - 1; i++) {
            b[i].addActionListener(lfb);
        }
        player = true;
    }
 }
4

1 回答 1

2

ResetBoard()被调用并且不是每个按钮都被按下时,你最终ActionListeners会为那些未使用的按钮分配多个。

这是一个示例resetBoard()方法:

    public void resetBoard() {
        // Fixed the loop index. Was: (int i = 1; i <= b.length - 1; i++)
        for (int i = 0; i < b.length; i++) {
            b[i].setText("");
            // Adding a listener only if there isn't one already
            if (b[i].getActionListeners().length < 1) 
                b[i].addActionListener(lfb);
        }
        player = true;
    }

正如@MadProgrammer 建议的那样,我还重构了setSquare()方法:

    public void setSquare(JButton button) {
        if (player) {
            button.setText("X");
        } else {
            button.setText("O");
        }
        button.removeActionListener(lfb);
        player = !player;
    }
于 2013-04-09T22:42:28.227 回答