在java上用GUI界面做Tic Tac Toe游戏,在包含新方法后面临运行时错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21806608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:46:27  来源:igfitidea点击:

Doing Tic Tac Toe game with GUI interface on java, facing runtime error after including new method

javaruntimeinfinite-sequence

提问by user3290306

So I am making a tic tac toe game with user friendly GUI interface. I have almost completed the game but there seems to be a problem with my checkWin function. Up to this point, everything was working just fine until I added the checkWin function and the parameters associated it with it. Before I implemented the checkWin function, you would press a button, it would be marked X and then there would be an automated computer move that would place an O randomly on the board where there isn't an X. Code is posted below. When I run the code, and you press a button, the applet just freezes and you can't even exit out of it without end task, ctrl-alt-del... Again, everything worked fine up until the checkWin function and now I'm facing a run-time error.

所以我正在制作一个具有用户友好 GUI 界面的井字游戏。我几乎完成了游戏,但我的 checkWin 功能似乎有问题。到目前为止,一切正常,直到我添加了 checkWin 函数和与其关联的参数。在我实现 checkWin 功能之前,你会按下一个按钮,它会被标记为 X,然后会有一个自动计算机移动,它会在没有 X 的板上随机放置一个 O。代码贴在下面。当我运行代码时,你按下一个按钮,小程序就会冻结,你甚至不能在没有结束任务的情况下退出它,ctrl-alt-del...同样,在 checkWin 函数之前一切正常,现在我正面临运行时错误。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class TicGUI extends JFrame 
    {

  JFrame frame = new JFrame("TicTacToe");                    //Global frame and grid button variables 
  JButton[][] buttons = new JButton[3][3];
  JButton start = new JButton("Start");              //Create start/reset buttons for game
  JButton reset = new JButton("Reset");
  JOptionPane turn;
  int moveCounter = 9;
  boolean gameWon = false;


 public TicGUI()                                        //Tic tac default constructor which adds and dimensions Jframe
   {
     super();
     frame.setSize(350, 450);
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE);        //Setting dimension of Jframe and setting parameters
     frame.setVisible(true);
     frame.setResizable(false);

   }

  private void checkWin(int row, int col)
    {
      if(buttons[row][0].getText()==buttons[row][1].getText()&& buttons[row][1].getText()==buttons[row][2].getText())
        {
          gameWon = true;
          System.out.println(buttons[row][0].getText()+ " wins!!!");         
        }
    else  if(buttons[0][col].getText()==buttons[1][col].getText()&& buttons[1][col].getText()==buttons[2][col].getText())
       {
          gameWon = true;
          System.out.println(buttons[row][0].getText()+ " wins!!!");
       }
    }
  private void compTurn(int count)
   { 
    int randomMove=count;
    Random num = new Random();
    randomMove = num.nextInt(randomMove)+1;

     while(gameWon ==false)
      {
       for(int i = 0; i < 3; i++)                      //Create grid of buttons for tic tac toe game
        {
         for(int j = 0; j < 3; j++) 
          {                 
           if(buttons[i][j].isEnabled()==true)
            {
               randomMove--;

             if(randomMove==0 )
              {
                buttons[i][j].setText("O");
                buttons[i][j].setEnabled(false);
                moveCounter--;
                checkWin(i, j);
              }
             } 

            }
          }
        }
      }

private void initialize()             //Initialize tic tac toe game board
   {
      JPanel mainPanel = new JPanel(new BorderLayout());         //create main panel container to put layer others on top
      JPanel menu = new JPanel(new BorderLayout());
      JPanel game = new JPanel(new GridLayout(3,3));                     //Create two more panels with layouts for buttons

      frame.add(mainPanel);                                         //add main container panel to frame

      mainPanel.setPreferredSize(new Dimension(325,425));
      menu.setPreferredSize(new Dimension(300,50));                     //Setting dimensions of panels
      game.setPreferredSize(new Dimension(300,300));

      mainPanel.add(menu, BorderLayout.NORTH);                   //Add two panels to the main container panel             
      mainPanel.add(game, BorderLayout.SOUTH);

      menu.add(start, BorderLayout.WEST);                //Add both start/reset buttons to menu container panel
      menu.add(reset, BorderLayout.EAST);

      start.addActionListener(new myActionListener());
      reset.addActionListener(new myActionListener());

   for(int i = 0; i < 3; i++)                      //Create grid of buttons for tic tac toe game
     {
      for(int j = 0; j < 3; j++) 
        {

         buttons[i][j] = new JButton();                //Instantiating buttons 
         buttons[i][j].setText("");
         buttons[i][j].setVisible(true);

         game.add(buttons[i][j]); 
         buttons[i][j].addActionListener(new myActionListener());        //Adding response event to buttons
        }
     }

  }

 private class myActionListener implements ActionListener
   {      //Implementing action listener for buttons
     public void actionPerformed(ActionEvent a) 
      {
       //Display X's or O's on the buttons  
       if(a.getSource() == buttons[0][0])                  //Checking which button is pressed
         {
           buttons[0][0].setText("X");
           buttons[0][0].setEnabled(false);
           moveCounter--;
           compTurn(moveCounter);
           checkWin(0,0);
         } 
       else if(a.getSource() == buttons[0][1])
         {
           buttons[0][1].setText("X");
           buttons[0][1].setEnabled(false);
           moveCounter--;
           compTurn(moveCounter);
           checkWin(0,1);
         } 
       else if(a.getSource() == buttons[1][0])
        {
          buttons[1][0].setText("X");  
          buttons[1][0].setEnabled(false);
          moveCounter--;
          compTurn(moveCounter);
          checkWin(1,0);
        } 
       else if(a.getSource() == buttons[1][1])
        {
          buttons[1][1].setText("X");
          buttons[1][1].setEnabled(false);
          moveCounter--;
          compTurn(moveCounter);
          checkWin(1,1);
        }
       else if(a.getSource() == buttons[1][2])
        {
          buttons[1][2].setText("X");
          buttons[1][2].setEnabled(false);
          moveCounter--;
          compTurn(moveCounter); 
          checkWin(1,2);
        } 
       else if(a.getSource() == buttons[2][2])
        {
         buttons[2][2].setText("X");
         buttons[2][2].setEnabled(false);
         moveCounter--;
         compTurn(moveCounter);
         checkWin(2,2);
        } 
       else if(a.getSource() == buttons[0][2])
        {
         buttons[0][2].setText("X");
         buttons[0][2].setEnabled(false);
         moveCounter--;
         compTurn(moveCounter);
         checkWin(0,2);
        }
       else if(a.getSource() == buttons[2][1])
        {
         buttons[2][1].setText("X");
         buttons[2][1].setEnabled(false);
         moveCounter--;
         compTurn(moveCounter);
         checkWin(2,1);
        }
       else if(a.getSource() == buttons[2][0])
        {
         buttons[2][0].setText("X");
         buttons[2][0].setEnabled(false);
         moveCounter--;
         compTurn(moveCounter);
         checkWin(2,0);
        }
       else if(a.getSource() == start)
         {
           turn = new JOptionPane("Do you want to go first?\n",JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
           start.setEnabled(false);
         }
       else if(a.getSource() == reset)
         {
            for(int i = 0; i < 3; i++)
             { 
               for(int j = 0; j < 3; j++)
                {
                   buttons[i][j].setText(""); 
                   buttons[i][j].setEnabled(true);
                   gameWon = false;
                }
             }
           }
       }
     }

 public static void main(String[] args)
    {
      TicGUI game = new TicGUI();         //main method and instantiating tic tac object and calling initialize function
      game.initialize();
    }
 }

回答by ltalhouarne

You need to use the following:

您需要使用以下内容:

buttons[row][0].getText().equals(buttons[row][1].getText())

instead of:

代替:

buttons[row][0].getText()==buttons[row][1].getText()

That also applies to all the other string comparisons in your checkWin method.

这也适用于 checkWin 方法中的所有其他字符串比较。

回答by MadProgrammer

The loop in you checkWon can't end while the game is I complete, but you can complete the game because the while loop is blocking it

checkWon 中的循环无法在游戏完成时结束,但您可以完成游戏,因为 while 循环阻止了它

回答by Jess Fan

The issue seems to be that the AI ("compTurn()") Is running an indefinite loop, and never gives the player an actual turn. It instead constantly tries to do its turn. To combat this, add a regulating variable (I added "int whoseTurn" in the example fix below).

问题似乎是 AI(“compTurn()”)正在无限循环运行,并且从不给玩家真正的转弯。相反,它不断尝试轮到自己。为了解决这个问题,添加一个调节变量(我在下面的示例修复中添加了“int whosTurn”)。

That only combats the runtime error, though. Another issue is that on MacOS devices (I tested it on MacOS X) the buttons are drawn before the backbuffer, and so the result is a blank backbuffer and a unplayable game. The solution to this is to draw the buttons after drawing the backbuffer, or just copy + paste the code of the buttons after the drawing backbuffer code.

不过,这只能解决运行时错误。另一个问题是,在 MacOS 设备上(我在 MacOS X 上测试过)按钮是在后台缓冲区之前绘制的,因此结果是一个空白的后台缓冲区和一个无法玩的游戏。解决这个问题的方法是在绘制后台缓冲区后绘制按钮,或者在绘制后台缓冲区代码之后复制并粘贴按钮的代码。

There is yet another issue, whereas the "Start button is completely useless, and does not affect the game in any way. I removed that in the example code below.

还有一个问题,而“开始按钮完全没用,并且不会以任何方式影响游戏。我在下面的示例代码中删除了它。

The final issue is that your "checkWin" mehtod is simple, but oftentimes wrong. I have replaced it with a longer, more accurate win checking system.

最后一个问题是您的“checkWin”方法很简单,但通常是错误的。我用更长、更准确的获胜检查系统替换了它。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.JOptionPane;

class TicGUI extends JFrame 
{

JButton[][] buttons = new JButton[3][3];
JFrame frame = new JFrame("TicTacToe");                    //Global frame and grid button variables
JButton reset = new JButton("Reset");             //Create reset button for game
JOptionPane turn;
int moveCounter = 9;
boolean gameWon = false;
int WhoseTurn = 1;

public TicGUI()                                        //Tic tac default constructor which adds and dimensions Jframe
{
 super();
 frame.setSize(350, 355);
 frame.setDefaultCloseOperation(EXIT_ON_CLOSE);        //Setting dimension of Jframe and setting parameters
 frame.setVisible(true);
 frame.setResizable(false);
 JButton[][] buttons = new JButton[3][3];
 JFrame frame = new JFrame("TicTacToe");                    //Global frame and grid button variables 
 JButton reset = new JButton("Reset");             //Create reset button for game
 JOptionPane turn;

}

private void checkWin(int row, int col)
{
    try {
    if (buttons[0][2].getText()==buttons[1][2].getText()&& buttons[1][2].getText()==buttons[2][2].getText()&& buttons[2][2].getText()==buttons[0][2].getText()&& buttons[1][2].getText()!="")
   {
      gameWon = true;
      WhoseTurn = 0;
      System.out.println(buttons[1][2].getText()+ " wins!!!");
      JOptionPane.showMessageDialog(frame, buttons[1][2].getText()+ " wins!!!");
   }
    if (buttons[0][1].getText()==buttons[1][1].getText()&& buttons[1][1].getText()==buttons[2][1].getText()&& buttons[2][1].getText()==buttons[0][1].getText()&& buttons[1][1].getText()!="")
   {
      gameWon = true;
      WhoseTurn = 0;
      System.out.println(buttons[1][1].getText()+ " wins!!!");
      JOptionPane.showMessageDialog(frame, buttons[1][1].getText()+ " wins!!!");
   }
    if (buttons[0][0].getText()==buttons[1][0].getText()&& buttons[1][0].getText()==buttons[2][0].getText()&& buttons[2][0].getText()==buttons[0][0].getText()&& buttons[1][0].getText()!="")
   {
      gameWon = true;
      WhoseTurn = 0;
      System.out.println(buttons[1][0].getText()+ " wins!!!");
      JOptionPane.showMessageDialog(frame, buttons[1][0].getText()+ " wins!!!");
   }
    if (buttons[2][0].getText()==buttons[2][1].getText()&& buttons[2][1].getText()==buttons[2][2].getText()&& buttons[2][2].getText()==buttons[2][0].getText()&& buttons[2][1].getText()!="")
   {
      gameWon = true;
      WhoseTurn = 0;
      System.out.println(buttons[2][1].getText()+ " wins!!!");
      JOptionPane.showMessageDialog(frame, buttons[2][1].getText()+ " wins!!!");
   }
    if (buttons[1][0].getText()==buttons[1][1].getText()&& buttons[1][1].getText()==buttons[1][2].getText()&& buttons[1][2].getText()==buttons[1][0].getText()&& buttons[1][1].getText()!="")
   {
      gameWon = true;
      WhoseTurn = 0;
      System.out.println(buttons[1][1].getText()+ " wins!!!");
      JOptionPane.showMessageDialog(frame, buttons[1][1].getText()+ " wins!!!");
   }
    if (buttons[0][0].getText()==buttons[0][1].getText()&& buttons[0][1].getText()==buttons[0][2].getText()&& buttons[0][2].getText()==buttons[0][0].getText()&& buttons[0][1].getText()!="")
   {
      gameWon = true;
      WhoseTurn = 0;
      System.out.println(buttons[0][1].getText()+ " wins!!!");
      JOptionPane.showMessageDialog(frame, buttons[0][1].getText()+ " wins!!!");
   }
   if (buttons[0][0].getText()==buttons[1][1].getText()&& buttons[1][1].getText()==buttons[2][2].getText()&& buttons[2][2].getText()==buttons[0][0].getText()&& buttons[1][1].getText()!="")
   {
      gameWon = true;
      WhoseTurn = 0;
      System.out.println(buttons[1][1].getText()+ " wins!!!");
      JOptionPane.showMessageDialog(frame, buttons[1][1].getText()+ " wins!!!");
   }
   if (buttons[0][2].getText()==buttons[1][1].getText()&& buttons[1][1].getText()==buttons[2][0].getText()&& buttons[2][0].getText()==buttons[0][2].getText()&& buttons[1][1].getText()!="")
   {
      gameWon = true;
      WhoseTurn = 0;
      System.out.println(buttons[1][1].getText()+ " wins!!!");
      JOptionPane.showMessageDialog(frame, buttons[1][1].getText()+ " wins!!!");
   }
    }catch(Exception e) {
        gameWon = true;
      WhoseTurn = 0;
      System.out.println("Stalemate");
      JOptionPane.showMessageDialog(frame, "Stalemate");
    }
}

private void compTurn(int count)
{ 
int randomMove=count;
Random num = new Random();
randomMove = num.nextInt(randomMove)+1;

 while(gameWon ==false & WhoseTurn ==2)
  {
   for(int i = 0; i < 3; i++)                      //Create grid of buttons for tic tac toe game
    {
     for(int j = 0; j < 3; j++) 
      {                 
       if(buttons[i][j].isEnabled()==true)
        {
           randomMove--;

         if(randomMove==0 )
          {
            buttons[i][j].setText("O");
            buttons[i][j].setEnabled(false);
            moveCounter--;
            checkWin(i, j);
            WhoseTurn = 1;
          }
         } 

        }
      }
    }
  }

private void initialize()             //Initialize tic tac toe game board
{
  JPanel mainPanel = new JPanel(new BorderLayout());         //create main panel container to put layer others on top
  JPanel menu = new JPanel(new BorderLayout());
  JPanel game = new JPanel(new GridLayout(3,3));                     //Create two more panels with layouts for buttons

  frame.add(mainPanel);                                         //add main container panel to frame

  mainPanel.setPreferredSize(new Dimension(325,425));
  menu.setPreferredSize(new Dimension(300,50));                     //Setting dimensions of panels
  game.setPreferredSize(new Dimension(300,300));

  mainPanel.add(menu, BorderLayout.NORTH);                   //Add two panels to the main container panel             
  mainPanel.add(game, BorderLayout.SOUTH);

  //Add both start/reset buttons to menu container panel
  menu.add(reset, BorderLayout.NORTH);

  reset.addActionListener(new myActionListener());

for(int i = 0; i < 3; i++)                      //Create grid of buttons for tic tac toe game
 {
  for(int j = 0; j < 3; j++) 
    {

     buttons[i][j] = new JButton();                //Instantiating buttons 
     buttons[i][j].setText("");
     buttons[i][j].setVisible(true);

     game.add(buttons[i][j]); 
     buttons[i][j].addActionListener(new myActionListener());        //Adding response event to buttons
    }
 }

}

private class myActionListener implements ActionListener
{      //Implementing action listener for buttons
 public void actionPerformed(ActionEvent a) 
  {
   //Display X's or O's on the buttons
   if(gameWon == false)
   {
   if(a.getSource() == buttons[0][0])                  //Checking which button is pressed
     {
       buttons[0][0].setText("X");
       buttons[0][0].setEnabled(false);
       WhoseTurn = 2;
       moveCounter--;
       compTurn(moveCounter);
       checkWin(0,0);
     } 
   else if(a.getSource() == buttons[0][1])
     {
       buttons[0][1].setText("X");
       buttons[0][1].setEnabled(false);
       WhoseTurn = 2;
       moveCounter--;
       compTurn(moveCounter);
       checkWin(0,1);
     } 
   else if(a.getSource() == buttons[1][0])
    {
      buttons[1][0].setText("X");  
      buttons[1][0].setEnabled(false);
      WhoseTurn = 2;
      moveCounter--;
      compTurn(moveCounter);
      checkWin(1,0);
    } 
   else if(a.getSource() == buttons[1][1])
    {
      buttons[1][1].setText("X");
      buttons[1][1].setEnabled(false);
      WhoseTurn = 2;
      moveCounter--;
      compTurn(moveCounter);
      checkWin(1,1);
    }
   else if(a.getSource() == buttons[1][2])
    {
      buttons[1][2].setText("X");
      buttons[1][2].setEnabled(false);
      WhoseTurn = 2;
      moveCounter--;
      compTurn(moveCounter); 
      checkWin(1,2);
    } 
   else if(a.getSource() == buttons[2][2])
    {
     buttons[2][2].setText("X");
     buttons[2][2].setEnabled(false);
     WhoseTurn = 2;
     moveCounter--;
     compTurn(moveCounter);
     checkWin(2,2);
    } 
   else if(a.getSource() == buttons[0][2])
    {
     buttons[0][2].setText("X");
     buttons[0][2].setEnabled(false);
     WhoseTurn = 2;
     moveCounter--;
     compTurn(moveCounter);
     checkWin(0,2);
    }
   else if(a.getSource() == buttons[2][1])
    {
     buttons[2][1].setText("X");
     buttons[2][1].setEnabled(false);
     WhoseTurn = 2;
     moveCounter--;
     compTurn(moveCounter);
     checkWin(2,1);
    }
   else if(a.getSource() == buttons[2][0])
    {
     buttons[2][0].setText("X");
     buttons[2][0].setEnabled(false);
     WhoseTurn = 2;
     moveCounter--;
     compTurn(moveCounter);
     checkWin(2,0);
    }
   }
   if(a.getSource() == reset)
     {
        for(int i = 0; i < 3; i++)
         { 
           for(int j = 0; j < 3; j++)
            {
                gameWon = false;
               buttons[i][j].setText(""); 
               buttons[i][j].setEnabled(true);
               moveCounter = 9;
               WhoseTurn = 1;

            }
         }
       }
  }
 }

public static void main(String[] args)
{
  TicGUI game = new TicGUI();         //main method and instantiating tic tac object and calling initialize function
  game.initialize();
 }
}

If you continue to have problems, just ask!

如果您仍然遇到问题,请询问!

  • Jess Fan
  • 杰斯范

JEF1056 [Musical artist, .Net programmer, Student]

JEF1056 [音乐艺术家、.Net 程序员、学生]

https://itunes.apple.com/us/artist/jef1056/id1139804160https://play.google.com/store/music/artist/JEF1056?id=Aovo6cz54vkx2ekexyl7eom6nwy

https://itunes.apple.com/us/artist/jef1056/id1139804160 https://play.google.com/store/music/artist/JEF1056?id=Aovo6cz54vkx2ekexyl7eom6nwy