Java GUI冻结井字游戏

时间:2018-06-28 19:43:24

标签: java

我用Java编写了井字游戏。 我似乎遇到的问题是,(人类)播放器1和(计算机)播放器2之间存在联系时,GUI冻结了。我在“ Buttonlistener”类和“ Methods”中都创建了tieCheck来抓领带。

我的程序的工作方式是,当按下按钮时,它将值传递给方法类中的数组。在此阵列中,1 =玩家1,2 =玩家2。

人类选手总是先走,所以当人类选手走了4次时,我在用tieCheck(turncount)进行最后一回合之前检查平局。然后,此方法利用方法类中的tieCheck()将最后一位放置1,然后检查获胜者。如果找不到赢家,则返回true。那么ButtonListener类中的tieCheck()将禁用所有按钮,并说“这是一条领带”。 但是,这些都不起作用。该程序仍将允许我做最后一步,并导致冻结的窗口,必须使用任务管理器关闭。请帮忙!

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MediumPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private JButton playAgain;
    private JButton[] buttons = new JButton[9];

    private JLabel label, turn;

    public MediumPanel() {

        ButtonListener listener = new ButtonListener();

        Font f1 = new Font("Arial", Font.BOLD , 100);
        Font f2 = new Font("Arial", Font.PLAIN, 50);

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

        for (int i = 0; i <= 8; i++) {
            buttons[i] = new JButton("");
            buttons[i].addActionListener(listener);
            buttons[i].setBackground(Color.white);
            buttons[i].setFont(f1);
            ButtonPanel.add(buttons[i]);
        }

        playAgain = new JButton();

        label = new JLabel();
        label.setFont(f2);

        turn = new JLabel("");
        turn.setFont(f1);

        playAgain.addActionListener(listener);
        playAgain.setText("Click to Play Again");
        playAgain.setFont(f2);

        setBackground(Color.green);
        setLayout(new BorderLayout());
        setPreferredSize(new Dimension(500, 500));

        add(playAgain, BorderLayout.SOUTH);
        add(label, BorderLayout.NORTH);
        add(ButtonPanel);
    }

    private class ButtonListener implements ActionListener {

        Methods method = new Methods();

        public void reset() {

            label.setText("");

            for (int i = 0; i <= 8; i++) {

                buttons[i].setEnabled(true);
                buttons[i].setText("");
            }

            method.reset();
        }

        // inserts
        public void insertG(int num) {

            for (int i = 0; i <= 8; i++) {

                if (num == i) {
                    buttons[i].setText("O");
                    buttons[i].setEnabled(false);
                }
            }
        }

        public void disable() {

            for(int i=0; i<=8; i++) {

                buttons[i].setEnabled(false);

            }

        }

        // Checks array using tieCheck from Methods class for a tie
        public void tieCheck(int turncount) {

            if (turncount == 4 && method.tieCheck() == true) {

                disable();
                label.setText("It's a tie!");
            }
        }

        // Checks for buttons being pressed
        public void actionPerformed(ActionEvent event) {

            int turncount = 0;


            //Resets array board, GUI buttons, and label when clicked
            if (event.getSource() == playAgain) {
                reset();
            }



            // Button 0
            if (event.getSource() == buttons[0]) {



                buttons[0].setText("X");
                buttons[0].setEnabled(false);
                turncount++;
                tieCheck(turncount);

                method.insertArray(0, 1);

                if (method.winCheck(1) == 1) {

                    label.setText("You Won!");
                    disable();



                } else {

                    insertG(method.smartMove(1, 2));

                    if (method.winCheck(2) == 1) {

                        label.setText("You Lost!");
                        disable();
                    }


                }

            }
            // Button 1
            if (event.getSource() == buttons[1]) {

                buttons[1].setText("X");
                buttons[1].setEnabled(false);
                turncount++;
                tieCheck(turncount);

                method.insertArray(1, 1);

                if (method.winCheck(1) == 1) {

                    label.setText("You Won!");
                    disable();

                } else {

                    insertG(method.smartMove(1, 2));

                    if (method.winCheck(2) == 1) {

                        label.setText("You Lost!");
                        disable();

                    }


                }

            }
            // Button 2
            if (event.getSource() == buttons[2]) {

                buttons[2].setText("X");
                buttons[2].setEnabled(false);
                turncount++;
                tieCheck(turncount);

                method.insertArray(2, 1);

                if (method.winCheck(1) == 1) {

                    label.setText("You Won!");
                    disable();

                } else {

                    insertG(method.smartMove(1, 2));

                    if (method.winCheck(2) == 1) {

                        label.setText("You Lost!");
                        disable();

                    }


                }

            }
            // Button 3
            if (event.getSource() == buttons[3]) {



                buttons[3].setText("X");
                buttons[3].setEnabled(false);
                turncount++;
                tieCheck(turncount);

                method.insertArray(3, 1);

                if (method.winCheck(1) == 1) {

                    label.setText("You Won!");
                    disable();

                } else {

                    insertG(method.smartMove(1, 2));

                    if (method.winCheck(2) == 1) {

                        label.setText("You Lost!");
                        disable();

                    }


                }

            }
            // Button 4
            if (event.getSource() == buttons[4]) {



                buttons[4].setText("X");
                buttons[4].setEnabled(false);
                turncount++;
                tieCheck(turncount);

                method.insertArray(4, 1);

                if (method.winCheck(1) == 1) {

                    label.setText("You Won!");
                    disable();

                } else {

                    insertG(method.smartMove(1, 2));

                    if (method.winCheck(2) == 1) {

                        label.setText("You Lost!");
                        disable();

                    }


                }

            }
            // Button 5
            if (event.getSource() == buttons[5]) {


                buttons[5].setText("X");
                buttons[5].setEnabled(false);
                turncount++;
                tieCheck(turncount);

                method.insertArray(5, 1);

                if (method.winCheck(1) == 1) {

                    label.setText("You Won!");
                    disable();

                } else {

                    insertG(method.smartMove(1, 2));

                    if (method.winCheck(2) == 1) {

                        label.setText("You Lost!");
                        disable();

                    }


                }

            }
            //Button 6
            if (event.getSource() == buttons[6]) {

                buttons[6].setText("X");
                buttons[6].setEnabled(false);
                turncount++;
                tieCheck(turncount);

                method.insertArray(6, 1);

                if (method.winCheck(1) == 1) {

                    label.setText("You Won!");
                    disable();

                } else {

                    insertG(method.smartMove(1, 2));

                    if (method.winCheck(2) == 1) {

                        label.setText("You Lost!");
                        disable();

                    }

                }

            }
            // Button 7
            if (event.getSource() == buttons[7]) {

                buttons[7].setText("X");
                buttons[7].setEnabled(false);
                turncount++;
                tieCheck(turncount);

                method.insertArray(7, 1);

                if (method.winCheck(1) == 1) {

                    label.setText("You Won!");
                    disable();

                } else {

                    insertG(method.smartMove(1, 2));

                    if (method.winCheck(2) == 1) {

                        label.setText("You Lost!");
                        disable();

                    }


                }

            }
            //Button 8
            if (event.getSource() == buttons[8]) {

                buttons[8].setText("X");
                buttons[8].setEnabled(false);
                turncount++;
                tieCheck(turncount);

                method.insertArray(8, 1);

                if (method.winCheck(1) == 1) {

                    label.setText("You Won!");
                    disable();

                } else {

                    insertG(method.smartMove(1, 2));

                    if (method.winCheck(2) == 1) {

                        label.setText("You Lost!");
                        disable();

                    }


                }

            }

        }
    }
}



import java.util.*;

public class Methods {

    Random rand = new Random();
    Scanner scan = new Scanner(System.in);

    // represents Tick-Tack-Toe Play Field
    int[] board = new int[9];

    // resets board array
    public void reset() {

        for (int i = 0; i < 9; i++) {
            board[i] = 0;
        }

    }

    // inserts player on a specific spot
    public void insertArray(int spot, int player) {
        board[spot] = player;
    }

    // for hard mode  
    public void expertMove(int player1, int player2) {

    }

    // for medium 
    public int smartMove(int player1, int player2) {

        boolean turntaken = false;

        for (int i = 0; i < 9; i++) {

            if (board[i] == 0) {

                board[i] = player2;

                if (winCheck(player2) == 1) {

                    return i;

                } else {
                    board[i] = 0;
                }

            }

        }

        for (int i = 0; i < 9; i++) {

            if (board[i] == 0) {

                board[i] = player1;

                if (winCheck(player1) != 1) {

                    board[i] = 0;

                } else {

                    board[i] = player2;
                    return i;
                }
            }
        }
        // If the opposite player is not about to win, then Computer goes randomly

        if (turntaken == false) {
            return randomMove(player2);
        }

        return 0;
    }

    // For easy mode and also utilized in smartMove() for medium mode
    public int randomMove(int player) {

        int rnum = 0;

        rnum = rand.nextInt(8);
        while (emptyCheck(rnum) != true) {

            rnum = rand.nextInt(8);

        }

        board[rnum] = player;

        return rnum;
    }

    //Returns 1 if player won the game
    public int winCheck(int player) {

        for (int ii = 0; ii <= 2; ii++) {
            if (board[ii] == player && board[ii + 3] == player && board[ii + 6] == player)
                return 1;
        }
        for (int z = 0; z <= 6; z = z + 3) {
            if (board[z] == player && board[z + 1] == player && board[z + 2] == player)
                return 1;
        }
        if (board[0] == player && board[4] == player && board[8] == player) {
            return 1;
        }
        if (board[2] == player && board[4] == player && board[6] == player) {
            return 1;
        }
        return 0;
    }

    //Returns true if tie
    public boolean tieCheck() {

        for(int i=0;i < 9; i++) {

            if(board[i] == 0) {

                board[i] = 2;

                if(winCheck(1) != 1 && winCheck(2) != 1) {

                    return true;

                }else {
                    board[i] = 0;
                }

            }       
        }
        return false;
    }

    // Checks if empty: True if empty/false if taken by player
    public boolean emptyCheck(int rnum) {

        if (board[rnum] == 0) {
            return true;
        } else {
            return false;
        }

    }

}

import java.awt.Font;

import javax.swing.JFrame;
import javax.swing.JTabbedPane;


public class Driver {


    public static void main(String []args) {

        JTabbedPane difficulty = new JTabbedPane();
        //difficulty.addTab("Easy", new EasyPanel());
        difficulty.addTab("Medium", new MediumPanel());
        //difficulty.addTab("Hard", new HardPanel());

        Font f = new Font("Arial", Font.PLAIN, 20);
        difficulty.setFont(f);




        JFrame frame = new JFrame("Tic-Tac-Toe");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(difficulty);



        frame.pack();
        frame.setVisible(true);



    }

2 个答案:

答案 0 :(得分:3)

每次点击都设置 // Checks for buttons being pressed public void actionPerformed(ActionEvent event) { int turncount = 0;

tieCheck

但在您的方法 // Checks array using tieCheck from Methods class for a tie public void tieCheck(int turncount) { if (turncount == 4 && method.tieCheck() == true) { disable(); label.setText("It's a tie!"); } } 中:

turncount == 4

您检查是否为1,但始终为turncount。您应该将randomMove变量从本地更改为全局。

然后在方法 // For easy mode and also utilized in smartMove() for medium mode public int randomMove(int player) { int rnum = 0; rnum = rand.nextInt(8); while (emptyCheck(rnum) != true) { // <--------- HERE rnum = rand.nextInt(8); } 中,您将遇到一个无限循环:

    public void printTime(String m){
    String pattern = "HH:mm:ss:SSS";
    SimpleDateFormat formato = new SimpleDateFormat(pattern);
    Date date = new Date();
    String dateString = formato.format(date);
    String retorno = dateString+" "+m;
    System.out.println(retorno);
}

答案 1 :(得分:0)

就像Peter1982在回答中所说的那样,应将turncount设为类变量而不是方法变量,以免每次调用actionPerformed方法时都将其重置。

要阻止游戏冻结,您可以创建一个boolean类变量来跟踪游戏是否结束,例如gameOver。然后,您可以使用gameOver方法更新tieCheck,例如:

private class ButtonListener implements ActionListener {

    boolean gameOver = false;

    // ...

     // Checks array using tieCheck from Methods class for a tie
     public void tieCheck(int turncount) {

         if (turncount == 4 && method.tieCheck() == true) {

             gameOver = true; // <---- Update gameOver
             disable();
             label.setText("It's a tie!");
         }
     }

     // Button 0
     if (event.getSource() == buttons[0]) {
         buttons[0].setText("X");
         buttons[0].setEnabled(false);
         turncount++;
         tieCheck(turncount);
         method.insertArray(0, 1);

         if (method.winCheck(1) == 1) {
             label.setText("You Won!");
                    disable();

         } else if (!gameOver) { // <---- Check if the game is over

              insertG(method.smartMove(1, 2));
              if (method.winCheck(2) == 1) {
                  label.setText("You Lost!");
                  disable();
              }
          }
      }

      // ...
}

请确保在您的turncount方法中重置tieCheckreset

另外,要特别注意的是,当我查看您的代码时,我注意到在您的randomMove方法中,您具有以下内容:rnum = rand.nextInt(8);。当前,这不允许计算机在第9个按钮上随意移动,因为rand.nextInt(8)将通过0返回7的值。这是因为8是排他的。因此,只需将9设置为如下参数:rand.nextInt(9)通过0获得8。我知道这很简单,但我只是想指出一点。