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