我用爪哇写过Tic-Tac-Toe。我似乎遇到的问题是,当(人类)玩家1和(计算机)玩家2之间存在平局时,图形用户界面冻结。我已经在"Buttonlistener“类和”方法“中创建了一个tieCheck来捕捉领带。
我的程序的工作方式是,当按钮被按下时,它将一个值传递给methods类中的数组。在这个数组中,1=玩家1,2 =玩家2。
人类棋手总是先走,所以当人类棋手走了4次时,我会在最后一个回合进行之前用tieCheck(Turncount)检查平局;这个方法然后利用methods类中的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);
}
发布于 2018-06-29 04:03:59
在每次点击时,您都会设置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
变量从本地更改为全局。
然后在方法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);
}
发布于 2018-06-29 07:15:39
正如Peter1982在他的回答中所说的,您应该使turncount
成为类变量而不是方法变量,这样它就不会在每次调用actionPerformed
方法时被重置。
为了防止游戏冻结,您可以创建一个跟踪游戏是否结束的boolean
类变量,比如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
方法中重置turncount
和tieCheck
。
此外,作为额外的说明,当我查看您的代码时,我注意到您的randomMove
方法中包含以下内容:rnum = rand.nextInt(8);
。目前,这不允许计算机在第9个按钮上进行随机移动,因为rand.nextInt(8)
将通过7
返回值0
。这是因为8
是独占的。因此,只需像这样将9
作为参数:rand.nextInt(9)
以通过8
获取0
。我知道这是微不足道的,但我只是想指出它。
https://stackoverflow.com/questions/51090257
复制相似问题