当前位置: 首页 > 知识库问答 >
问题:

JavaGUI冻结井字游戏

滑骞尧
2023-03-14

我用Java写了Tic-Tac-Toe。我似乎遇到的问题是,当(人类)播放器1和(计算机)播放器2之间出现平局时,GUI会冻结。我已经在“Buttonlistener”类和“Methods”中创建了一个tieCheck,以获得一个平局。

我的程序的工作方式是,当按下一个按钮时,它会将一个值传递给methods类中的数组。在这个数组中,1=玩家1,2=玩家2。

人类玩家总是先走,所以当人类玩家走了4次时,我会在最后一圈之前用tieCheck检查是否打成平手;然后这个方法使用方法类中的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个答案

裴卓君
2023-03-14

正如彼得1982年在回答中所说,你应该把turncount作为一个类变量,而不是一个方法变量,这样它就不会在每次调用actionPerformed方法时被重置。

为了防止游戏冻结,可以创建一个布尔类变量来跟踪游戏是否结束,例如gameOver。然后在tieCheck方法中更新gameOver,例如:

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

      // ...
}

确保在reset方法中重置turncounttieCheck

另外,作为一个额外的注意事项,当我查看您的代码时,我注意到在您的randomMove方法中,您有以下内容:rnum=rand。nextInt(8) 。目前,这将不允许计算机在第9个按钮上进行随机移动,因为rand。nextInt(8)将通过7返回0的值。这是因为8是独占的。所以只要把9作为如下参数:rand。下一步(9)通过8获取0。我知道这很琐碎,但我只想指出一点。

陆文斌
2023-03-14

每次单击时,您都会设置turncount=0

    // 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变量从本地更改为全局。

然后在方法随机移动中,您有一个无休止的循环:

    // 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);

    }
 类似资料:
  • 嗨,我正在编写一个井字游戏。我已经在代码中的注释中详细说明了我需要什么。我现在遇到的问题是制作一个getMobile方法。我想我需要在按下行和列后的if/else语句中调用getMobile方法? 我不确定如何从获取行/列编号并将其放入我的板上以获取用户输入的内容。 以下是我的代码:

  • 我目前正在编写一个创建井字游戏的程序。目前的应用程序有两个人互相对战,轮流输入行号和列号。这个程序的主要问题是我无法让它显示一个人赢或输或两个玩家平局的结果。如果有人对我如何解决这个问题有任何建议,那就太好了。再次感谢您的时间。

  • 问题内容: 我已经用Java编写了一个井字游戏,而我目前确定游戏结束的方法说明了游戏结束的以下可能情况: The board is full, and no winner has yet been declared: Game is a draw. Cross has won. Circle has won. 不幸的是,这样做的目的是从表中读取一组预定义的方案。考虑到一个棋盘上只有9个空格,这并不

  • 我正在制作一个名为SOS的游戏。这是一款3x3的棋盘游戏,与Tic Tac Toe的概念相同,但在这款游戏中,玩家无法选择是以X还是O的身份进行游戏,游戏中唯一的规则是形成“SOS”。 我们的项目应该在所有职位被填补后终止,每个组成的“SOS”将被添加到组成“SOS”的玩家中。 我的问题是关于得分。在第一行输入SOS后,即,我尝试在第二行第一列输入“O”,玩家2将递增。它不应该递增,因为它不满足我

  • 所以我为我的课做了一个抽动练习作业。我已经成功地创建了一个简单的Tic Tac Toe程序,但不知何故,检查绘制的方法有时并不正确。如果所有东西都填满了,但没有赢家,那就是平局。但如果除第0行第1列外,其他所有内容都已填满,则即使该框仍为空白,它仍将显示“Draw”。如果你不明白我的意思,就试着把所有的东西都填满,但不是赢,即使最后一个框没有填满,它也会说“平局”。我在代码中做错了什么????驱动

  • 我在Java中创建了一个小TicTacToe游戏,我想编写更有效的代码,我会制作一个for循环来创建9个按钮。 我现在面临的问题是如何测试按下哪个按钮以确定胜利者。我已经注释掉了我的旧测试代码,因为它不再工作。