I have my code almost entirely working and just ran into a couple of small problems. For one, I want the user to receive a popup when they try to select a button already marked with an X or an O, telling them the move is invalid and to pick another. Secondly, I'm trying to add a quit button to the bottom of the game, but it always makes the quit button part of the game grid? The solution is probably simple and I'm just not seeing it, but I've tried it a couple different times and can't seem to get it out of that grid. Thanks for all help.
我的代码几乎完全正常工作,只是遇到了几个小问题。首先,我希望用户在尝试选择已标有X或O的按钮时接收弹出窗口,告诉他们移动无效并选择另一个。其次,我试图在游戏的底部添加一个退出按钮,但它总是使退出按钮成为游戏网格的一部分?解决方案可能很简单,我只是没有看到它,但我已经尝试了几次不同的时间,似乎无法将其从网格中解脱出来。谢谢你的帮助。
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
class TicTacToeFrame extends JFrame implements ActionListener {
private int[][] winningMoves = new int[][]{
{1, 2, 3}, {4, 5, 6}, {7, 8, 9},
{1, 4, 7}, {2, 5, 8}, {3, 6, 9},
{1, 5, 9}, {3, 5, 7}
};
private JFrame frame = new JFrame("Tic Tac Toe");
private JButton buttons[] = new JButton[10];
private JButton quitButton = new JButton("Quit");
private int moveCount = 0;
private String letter = "";
private boolean win = false;
ActionListener quitListener = new quitListener();
public TicTacToeFrame() {
JPanel bottom = new JPanel();
bottom.setBorder(BorderFactory.createLineBorder(Color.black));
frame.setPreferredSize(new Dimension(400, 400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(3, 3));
frame.pack();
frame.setLocationRelativeTo(null);
quitButton.addActionListener(quitListener);
bottom.add(quitButton, BorderLayout.SOUTH);
for (int i = 1; i <= 9; i++) {
buttons[i] = new JButton();
frame.add(buttons[i]);
buttons[i].addActionListener(this);
}
frame.setVisible(true);
}
public void actionPerformed(ActionEvent a) {
for (int i = 1; i <= 9; i++) {
if (a.getSource() == buttons[i]) {
buttons[i].setText("X");
buttons[i].setEnabled(false);
}
}
moveCount++;
computer();
}
public void computer() {
moveCount++;
if (buttons[1].getText().equals("O") && buttons[2].getText().equals("O") && buttons[3].getText().equals("")) {
buttons[3].setText("O");
buttons[3].setEnabled(false);
} else if (buttons[4].getText().equals("O") && buttons[5].getText().equals("O") && buttons[6].getText().equals("")) {
buttons[6].setText("O");
buttons[6].setEnabled(false);
} else if (buttons[7].getText().equals("O") && buttons[8].getText().equals("O") && buttons[9].getText().equals("")) {
buttons[9].setText("O");
buttons[9].setEnabled(false);
} else if (buttons[2].getText().equals("O") && buttons[3].getText().equals("O") && buttons[1].getText().equals("")) {
buttons[1].setText("O");
buttons[1].setEnabled(false);
} else if (buttons[5].getText().equals("O") && buttons[6].getText().equals("O") && buttons[4].getText().equals("")) {
buttons[4].setText("O");
buttons[4].setEnabled(false);
} else if (buttons[8].getText().equals("O") && buttons[9].getText().equals("O") && buttons[7].getText().equals("")) {
buttons[7].setText("O");
buttons[7].setEnabled(false);
} else if (buttons[1].getText().equals("O") && buttons[3].getText().equals("O") && buttons[2].getText().equals("")) {
buttons[2].setText("O");
buttons[2].setEnabled(false);
} else if (buttons[4].getText().equals("O") && buttons[6].getText().equals("O") && buttons[5].getText().equals("")) {
buttons[5].setText("O");
buttons[5].setEnabled(false);
} else if (buttons[7].getText().equals("O") && buttons[9].getText().equals("O") && buttons[8].getText().equals("")) {
buttons[8].setText("O");
buttons[8].setEnabled(false);
} else if (buttons[1].getText().equals("O") && buttons[4].getText().equals("O") && buttons[7].getText().equals("")) {
buttons[7].setText("O");
buttons[7].setEnabled(false);
} else if (buttons[2].getText().equals("O") && buttons[5].getText().equals("O") && buttons[8].getText().equals("")) {
buttons[4].setText("O");
buttons[4].setEnabled(false);
} else if (buttons[3].getText().equals("O") && buttons[6].getText().equals("O") && buttons[9].getText().equals("")) {
buttons[9].setText("O");
buttons[9].setEnabled(false);
} else if (buttons[4].getText().equals("O") && buttons[7].getText().equals("O") && buttons[1].getText().equals("")) {
buttons[1].setText("O");
buttons[1].setEnabled(false);
} else if (buttons[5].getText().equals("O") && buttons[8].getText().equals("O") && buttons[2].getText().equals("")) {
buttons[2].setText("O");
buttons[2].setEnabled(false);
} else if (buttons[6].getText().equals("O") && buttons[9].getText().equals("O") && buttons[3].getText().equals("")) {
buttons[3].setText("O");
buttons[3].setEnabled(false);
} else if (buttons[1].getText().equals("O") && buttons[7].getText().equals("O") && buttons[4].getText().equals("")) {
buttons[4].setText("O");
buttons[4].setEnabled(false);
} else if (buttons[2].getText().equals("O") && buttons[8].getText().equals("O") && buttons[5].getText().equals("")) {
buttons[5].setText("O");
buttons[5].setEnabled(false);
} else if (buttons[3].getText().equals("O") && buttons[9].getText().equals("O") && buttons[6].getText().equals("")) {
buttons[6].setText("O");
buttons[6].setEnabled(false);
} else if (buttons[1].getText().equals("O") && buttons[5].getText().equals("O") && buttons[9].getText().equals("")) {
buttons[9].setText("O");
buttons[9].setEnabled(false);
} else if (buttons[5].getText().equals("O") && buttons[9].getText().equals("O") && buttons[1].getText().equals("")) {
buttons[1].setText("O");
buttons[1].setEnabled(false);
} else if (buttons[1].getText().equals("O") && buttons[9].getText().equals("O") && buttons[5].getText().equals("")) {
buttons[5].setText("O");
buttons[5].setEnabled(false);
} else if (buttons[3].getText().equals("O") && buttons[5].getText().equals("O") && buttons[7].getText().equals("")) {
buttons[7].setText("O");
buttons[7].setEnabled(false);
} else if (buttons[7].getText().equals("O") && buttons[5].getText().equals("O") && buttons[3].getText().equals("")) {
buttons[3].setText("O");
buttons[3].setEnabled(false);
} else if (buttons[7].getText().equals("O") && buttons[3].getText().equals("O") && buttons[5].getText().equals("")) {
buttons[5].setText("O");
buttons[5].setEnabled(false);
} else if (buttons[1].getText().equals("X") && buttons[2].getText().equals("X") && buttons[3].getText().equals("")) {
buttons[3].setText("O");
buttons[3].setEnabled(false);
} else if (buttons[4].getText().equals("X") && buttons[5].getText().equals("X") && buttons[6].getText().equals("")) {
buttons[6].setText("O");
buttons[6].setEnabled(false);
} else if (buttons[7].getText().equals("X") && buttons[8].getText().equals("X") && buttons[9].getText().equals("")) {
buttons[9].setText("O");
buttons[9].setEnabled(false);
} else if (buttons[2].getText().equals("X") && buttons[3].getText().equals("X") && buttons[1].getText().equals("")) {
buttons[1].setText("O");
buttons[1].setEnabled(false);
} else if (buttons[5].getText().equals("X") && buttons[6].getText().equals("X") && buttons[4].getText().equals("")) {
buttons[4].setText("O");
buttons[4].setEnabled(false);
} else if (buttons[8].getText().equals("X") && buttons[9].getText().equals("X") && buttons[7].getText().equals("")) {
buttons[7].setText("O");
buttons[7].setEnabled(false);
} else if (buttons[1].getText().equals("X") && buttons[3].getText().equals("X") && buttons[2].getText().equals("")) {
buttons[2].setText("O");
buttons[2].setEnabled(false);
} else if (buttons[4].getText().equals("X") && buttons[6].getText().equals("X") && buttons[5].getText().equals("")) {
buttons[5].setText("O");
buttons[5].setEnabled(false);
} else if (buttons[7].getText().equals("X") && buttons[9].getText().equals("X") && buttons[8].getText().equals("")) {
buttons[8].setText("O");
buttons[8].setEnabled(false);
} else if (buttons[1].getText().equals("X") && buttons[4].getText().equals("X") && buttons[7].getText().equals("")) {
buttons[7].setText("O");
buttons[7].setEnabled(false);
} else if (buttons[2].getText().equals("X") && buttons[5].getText().equals("X") && buttons[8].getText().equals("")) {
buttons[8].setText("O");
buttons[8].setEnabled(false);
} else if (buttons[3].getText().equals("X") && buttons[6].getText().equals("X") && buttons[9].getText().equals("")) {
buttons[9].setText("O");
buttons[9].setEnabled(false);
} else if (buttons[4].getText().equals("X") && buttons[7].getText().equals("X") && buttons[1].getText().equals("")) {
buttons[1].setText("O");
buttons[1].setEnabled(false);
} else if (buttons[5].getText().equals("X") && buttons[8].getText().equals("X") && buttons[2].getText().equals("")) {
buttons[2].setText("O");
buttons[2].setEnabled(false);
} else if (buttons[6].getText().equals("X") && buttons[9].getText().equals("X") && buttons[3].getText().equals("")) {
buttons[3].setText("O");
buttons[3].setEnabled(false);
} else if (buttons[1].getText().equals("X") && buttons[7].getText().equals("X") && buttons[4].getText().equals("")) {
buttons[4].setText("O");
buttons[4].setEnabled(false);
} else if (buttons[2].getText().equals("X") && buttons[8].getText().equals("X") && buttons[5].getText().equals("")) {
buttons[5].setText("O");
buttons[5].setEnabled(false);
} else if (buttons[3].getText().equals("X") && buttons[9].getText().equals("X") && buttons[6].getText().equals("")) {
buttons[6].setText("O");
buttons[6].setEnabled(false);
} else if (buttons[1].getText().equals("X") && buttons[5].getText().equals("X") && buttons[9].getText().equals("")) {
buttons[9].setText("O");
buttons[9].setEnabled(false);
} else if (buttons[5].getText().equals("X") && buttons[9].getText().equals("X") && buttons[1].getText().equals("")) {
buttons[1].setText("O");
buttons[1].setEnabled(false);
} else if (buttons[1].getText().equals("X") && buttons[9].getText().equals("X") && buttons[5].getText().equals("")) {
buttons[5].setText("O");
buttons[5].setEnabled(false);
} else if (buttons[3].getText().equals("X") && buttons[5].getText().equals("X") && buttons[7].getText().equals("")) {
buttons[7].setText("O");
buttons[7].setEnabled(false);
} else if (buttons[7].getText().equals("X") && buttons[5].getText().equals("X") && buttons[3].getText().equals("")) {
buttons[3].setText("O");
buttons[3].setEnabled(false);
} else if (buttons[7].getText().equals("X") && buttons[3].getText().equals("X") && buttons[5].getText().equals("")) {
buttons[5].setText("O");
buttons[5].setEnabled(false);
} else if (buttons[1].getText().equals("X") && buttons[5].getText().equals("O") && buttons[9].getText().equals("X")) {
buttons[6].setText("O");
buttons[6].setEnabled(false);
} else if (buttons[3].getText().equals("X") && buttons[5].getText().equals("O") && buttons[7].getText().equals("X")) {
buttons[4].setText("O");
buttons[4].setEnabled(false);
} else if (buttons[5].getText().equals("")) {
buttons[5].setText("O");
buttons[5].setEnabled(false);
} else if (buttons[1].getText().equals("")) {
buttons[1].setText("O");
buttons[1].setEnabled(false);
} else {
if (moveCount >= 9) {
checkWinner();
} else {
random();
}
}
checkWinner();
}
public void random() {
Random x = new Random();
int y = 1 + x.nextInt(9);
if (buttons[y].getText().equals("O") || buttons[y].getText().equals("X")) {
random();
} else {
buttons[y].setText("O");
buttons[y].setEnabled(false);
}
}
class quitListener implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
System.exit(0);
}
}
public void checkWinner() {
for (int i = 0; i <= 7; i++) {
if (buttons[winningMoves[i][0]].getText().equals(buttons[winningMoves[i][1]].getText())
&& buttons[winningMoves[i][1]].getText().equals(buttons[winningMoves[i][2]].getText())
&& !buttons[winningMoves[i][0]].getText().equals("")) {
win = true;
}
}
if (moveCount % 2 == 0) {
letter = "O";
} else {
letter = "X";
}
if (win == true) {
int select = JOptionPane.showConfirmDialog(null, letter + " wins! Would you like to play again?");
if(select == JOptionPane.YES_OPTION)
{
for (int i = 1; i <= 9; i++)
{
buttons[i].setText("");
buttons[i].setEnabled(true);
moveCount = 0;
win = false;
}
}
else
{
if(select == JOptionPane.NO_OPTION)
{
System.exit(0);
}
}
}
else if (moveCount >= 9 && win == false)
{
int select = JOptionPane.showConfirmDialog(null, "It's a tie! Would you like to play again?");
if(select == JOptionPane.YES_OPTION)
{
for (int i = 1; i <= 9; i++)
{
buttons[i].setText("");
buttons[i].setEnabled(true);
moveCount = 0;
win = false;
}
}
else
{
if(select == JOptionPane.NO_OPTION)
{
System.exit(0);
}
}
}
}
}
Runner:
import javax.swing.JFrame;
public class TicTacToeRunner
{
public static void main(String[] args)
{
JFrame frame = new TicTacToeFrame();
frame.setVisible(true);
}
}
1 个解决方案
#1
3
- In your JButton's ActionListener, you can get the button that has been pressed via the ActionEvent's
getSource()
method. Simply callgetText()
on that JButton and if it holds the offending text, show an error JOptionPane. Or just use yourbuttons[i]
variable within the loop, since it points to the offending JButton. - If you go this route, be sure that the exit button has its own separate ActionListener. Otherwise you may run into trouble. An inner anonymous class would work well here.
- You've set the layout of the entire GUI, the JFrame, to be GridLayout, and this boxes you into a grid whether you like it or not. Don't do this. Leave the JFrame's contentPane to use its default BorderLayout, create a new JPanel for the tic tac toe grid, give it a GridLayout, add it to the JFrame BorderLayout.CENTER, and then add the bottom JPanel to the JFrame BorderLayout.PAGE_END.
在JButton的ActionListener中,您可以获取通过ActionEvent的getSource()方法按下的按钮。只需在该JButton上调用getText(),如果它包含有问题的文本,则显示错误JOptionPane。或者只是在循环中使用你的按钮[i]变量,因为它指向违规的JButton。
如果你走这条路,请确保退出按钮有自己独立的ActionListener。否则你可能会遇到麻烦。内部匿名类在这里运行良好。
您已将整个GUI的布局(JFrame)设置为GridLayout,无论您喜欢与否,都会将您置于网格中。不要这样做。保留JFrame的contentPane以使用其默认的BorderLayout,为tic tac toe网格创建一个新的JPanel,给它一个GridLayout,将其添加到JFrame BorderLayout.CENTER,然后将底部的JPanel添加到JFrame BorderLayout.PAGE_END。
Side recommendations unrelated to your questions:
与您的问题无关的附带建议:
- Get rid of all that redundancy. Unnecessarily complex code is hard to debug code.
- Separate your program logic (the logic underlying the tic-tac-toe game) from the GUI code. This too will make it easier to debug and enhance your game.
- In the future, strive to ask a single specific question as yours appears to be a multi-parter.
摆脱所有冗余。不必要的复杂代码很难调试代码。
将您的程序逻辑(井字游戏的基础逻辑)与GUI代码分开。这也将使调试和增强游戏变得更容易。
在将来,努力提出一个具体的问题,因为你的问题似乎是多方的。
#1
3
- In your JButton's ActionListener, you can get the button that has been pressed via the ActionEvent's
getSource()
method. Simply callgetText()
on that JButton and if it holds the offending text, show an error JOptionPane. Or just use yourbuttons[i]
variable within the loop, since it points to the offending JButton. - If you go this route, be sure that the exit button has its own separate ActionListener. Otherwise you may run into trouble. An inner anonymous class would work well here.
- You've set the layout of the entire GUI, the JFrame, to be GridLayout, and this boxes you into a grid whether you like it or not. Don't do this. Leave the JFrame's contentPane to use its default BorderLayout, create a new JPanel for the tic tac toe grid, give it a GridLayout, add it to the JFrame BorderLayout.CENTER, and then add the bottom JPanel to the JFrame BorderLayout.PAGE_END.
在JButton的ActionListener中,您可以获取通过ActionEvent的getSource()方法按下的按钮。只需在该JButton上调用getText(),如果它包含有问题的文本,则显示错误JOptionPane。或者只是在循环中使用你的按钮[i]变量,因为它指向违规的JButton。
如果你走这条路,请确保退出按钮有自己独立的ActionListener。否则你可能会遇到麻烦。内部匿名类在这里运行良好。
您已将整个GUI的布局(JFrame)设置为GridLayout,无论您喜欢与否,都会将您置于网格中。不要这样做。保留JFrame的contentPane以使用其默认的BorderLayout,为tic tac toe网格创建一个新的JPanel,给它一个GridLayout,将其添加到JFrame BorderLayout.CENTER,然后将底部的JPanel添加到JFrame BorderLayout.PAGE_END。
Side recommendations unrelated to your questions:
与您的问题无关的附带建议:
- Get rid of all that redundancy. Unnecessarily complex code is hard to debug code.
- Separate your program logic (the logic underlying the tic-tac-toe game) from the GUI code. This too will make it easier to debug and enhance your game.
- In the future, strive to ask a single specific question as yours appears to be a multi-parter.
摆脱所有冗余。不必要的复杂代码很难调试代码。
将您的程序逻辑(井字游戏的基础逻辑)与GUI代码分开。这也将使调试和增强游戏变得更容易。
在将来,努力提出一个具体的问题,因为你的问题似乎是多方的。