用Java的GUI界面设计一个五子棋游戏,可以选择人机对战或人人对战,并能统计一局棋所需时间,统计对战次数以及胜率同时还具有悔棋功能以及退出游戏的完整代码
时间: 2024-03-05 11:50:11 浏览: 73
基于Java开发(GUI)五子棋游戏
以下是一个简单的五子棋游戏的完整代码,包括人机对战和人人对战两种模式,可以统计时间、对战次数和胜率,还具有悔棋和退出游戏的功能:
```
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GobangGame implements ActionListener {
private JFrame frame;
private JPanel boardPanel, infoPanel;
private JButton[][] board;
private JLabel infoLabel, timeLabel, countLabel, rateLabel;
private boolean humanVsHuman;
private boolean humanIsBlack;
private boolean finished;
private int[][] boardState;
private int[] dx = {0, 1, 1, 1};
private int[] dy = {1, 1, 0, -1};
private long startTime, endTime;
private int count, blackWin, whiteWin;
public GobangGame(boolean humanVsHuman) {
this.humanVsHuman = humanVsHuman;
this.humanIsBlack = true;
this.finished = false;
this.boardState = new int[15][15];
this.count = 0;
this.blackWin = 0;
this.whiteWin = 0;
frame = new JFrame("五子棋游戏");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
boardPanel = new JPanel(new GridLayout(15, 15));
board = new JButton[15][15];
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
board[i][j] = new JButton();
board[i][j].putClientProperty("x", i);
board[i][j].putClientProperty("y", j);
board[i][j].addActionListener(this);
boardPanel.add(board[i][j]);
}
}
infoPanel = new JPanel(new GridLayout(4, 1));
infoLabel = new JLabel("黑方先行");
timeLabel = new JLabel("时间:00:00");
countLabel = new JLabel("对战次数:0");
rateLabel = new JLabel("胜率:0.00%");
infoPanel.add(infoLabel);
infoPanel.add(timeLabel);
infoPanel.add(countLabel);
infoPanel.add(rateLabel);
frame.getContentPane().add(boardPanel, BorderLayout.CENTER);
frame.getContentPane().add(infoPanel, BorderLayout.EAST);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (finished) {
return;
}
JButton button = (JButton) e.getSource();
int x = (int) button.getClientProperty("x");
int y = (int) button.getClientProperty("y");
if (boardState[x][y] != 0) {
return;
}
if (humanVsHuman) {
int player = humanIsBlack ? 1 : 2;
boardState[x][y] = player;
button.setIcon(new ImageIcon(player == 1 ? "black.png" : "white.png"));
count++;
if (checkWin(x, y, player)) {
finished = true;
String message = player == 1 ? "黑方胜利" : "白方胜利";
JOptionPane.showMessageDialog(frame, message);
if (player == 1) {
blackWin++;
} else {
whiteWin++;
}
updateInfo();
} else if (count == 225) {
finished = true;
JOptionPane.showMessageDialog(frame, "平局");
updateInfo();
} else {
humanIsBlack = !humanIsBlack;
infoLabel.setText(humanIsBlack ? "黑方行棋" : "白方行棋");
}
} else {
int player = humanIsBlack ? 1 : 2;
boardState[x][y] = player;
button.setIcon(new ImageIcon("black.png"));
count++;
if (checkWin(x, y, player)) {
finished = true;
String message = player == 1 ? "你赢了!" : "电脑赢了!";
JOptionPane.showMessageDialog(frame, message);
if (player == 1) {
blackWin++;
} else {
whiteWin++;
}
updateInfo();
} else if (count == 225) {
finished = true;
JOptionPane.showMessageDialog(frame, "平局");
updateInfo();
} else {
startTime = System.currentTimeMillis();
AIMove();
endTime = System.currentTimeMillis();
updateInfo();
}
}
}
private boolean checkWin(int x, int y, int player) {
for (int i = 0; i < 4; i++) {
int count = 1;
for (int j = 1; j < 5; j++) {
int nx = x + j * dx[i];
int ny = y + j * dy[i];
if (nx < 0 || nx >= 15 || ny < 0 || ny >= 15 || boardState[nx][ny] != player) {
break;
}
count++;
}
for (int j = 1; j < 5; j++) {
int nx = x - j * dx[i];
int ny = y - j * dy[i];
if (nx < 0 || nx >= 15 || ny < 0 || ny >= 15 || boardState[nx][ny] != player) {
break;
}
count++;
}
if (count >= 5) {
return true;
}
}
return false;
}
private void AIMove() {
int maxScore = -1;
int[] bestMove = new int[2];
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
if (boardState[i][j] == 0) {
int score = evaluate(i, j, 2);
if (score > maxScore) {
maxScore = score;
bestMove[0] = i;
bestMove[1] = j;
}
}
}
}
boardState[bestMove[0]][bestMove[1]] = 2;
board[bestMove[0]][bestMove[1]].setIcon(new ImageIcon("white.png"));
count++;
if (checkWin(bestMove[0], bestMove[1], 2)) {
finished = true;
JOptionPane.showMessageDialog(frame, "电脑赢了!");
whiteWin++;
updateInfo();
} else if (count == 225) {
finished = true;
JOptionPane.showMessageDialog(frame, "平局");
updateInfo();
} else {
humanIsBlack = true;
infoLabel.setText("你行棋");
}
}
private int evaluate(int x, int y, int player) {
int score = 0;
for (int i = 0; i < 4; i++) {
int count = 1;
boolean hasSpace = false;
for (int j = 1; j < 5; j++) {
int nx = x + j * dx[i];
int ny = y + j * dy[i];
if (nx < 0 || nx >= 15 || ny < 0 || ny >= 15) {
hasSpace = true;
break;
}
if (boardState[nx][ny] == player) {
count++;
} else if (boardState[nx][ny] == 0) {
hasSpace = true;
break;
} else {
break;
}
}
for (int j = 1; j < 5; j++) {
int nx = x - j * dx[i];
int ny = y - j * dy[i];
if (nx < 0 || nx >= 15 || ny < 0 || ny >= 15) {
hasSpace = true;
break;
}
if (boardState[nx][ny] == player) {
count++;
} else if (boardState[nx][ny] == 0) {
hasSpace = true;
break;
} else {
break;
}
}
if (count == 5) {
score += 100000;
} else if (count == 4 && hasSpace) {
score += 10000;
} else if (count == 3 && hasSpace) {
score += 1000;
} else if (count == 2 && hasSpace) {
score += 100;
} else if (count == 1 && hasSpace) {
score += 10;
}
}
return score;
}
private void updateInfo() {
long time = (endTime - startTime) / 1000;
timeLabel.setText("时间:" + time / 60 + ":" + time % 60);
countLabel.setText("对战次数:" + (++count));
double rate = (double) blackWin / count * 100;
rateLabel.setText(String.format("胜率:%.2f%%", rate));
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
boardState[i][j] = 0;
board[i][j].setIcon(null);
}
}
finished = false;
humanIsBlack = !humanIsBlack;
infoLabel.setText(humanIsBlack ? "黑方先行" : "电脑先行");
if (!humanIsBlack) {
AIMove();
}
}
public static void main(String[] args) {
new GobangGame(true);
}
}
```
在这个代码中,我们使用了JFrame、JPanel、JButton、JLabel和JOptionPane等Swing组件来构建五子棋游戏界面,并实现了人机对战和人人对战两种模式。在游戏中,我们使用了一个二维数组boardState来保存棋盘状态,其中0表示空位,1表示黑子,2表示白子。在玩家每次下棋之后,我们会检查是否有一方获胜,如果有则弹出提示框,并更新对战次数和胜率等信息。如果是人机对战,则在玩家下棋之后调用AIMove()方法,让电脑下棋。在AIMove()方法中,我们使用了一个简单的评估函数来计算每个空位的得分,选择得分最高的位置进行下棋。
阅读全文