用Java的GUI界面设计一个五子棋游戏,在界面上可以选择人机对战或人人对战以及统计对战一局所需时间、对战次数、对战胜率、悔棋、退出游戏等功能,界面具有一定的美观的完整代码
时间: 2023-07-10 17:31:31 浏览: 151
这是一个用Java实现具有图形界面的五子棋游戏,能实现人机对战和人人对战,课程设计。.zip
下面是一个用Java Swing实现的五子棋游戏的完整代码。它包括人机对战和人人对战两种模式,还包括统计对战信息、悔棋和退出游戏等功能。界面比较简单,但是可以根据需要进行美化。
```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Gobang extends JFrame implements ActionListener, MouseListener {
private static final long serialVersionUID = 1L;
private static final int ROWS = 15, COLS = 15, SIZE = 30;
private static final int BLACK = 1, WHITE = -1, EMPTY = 0;
private int[][] board = new int[ROWS][COLS];
private int currentPlayer = BLACK;
private boolean gameOver = false, humanVsHuman = true, humanFirst = true;
private JLabel statusLabel;
private JButton humanVsHumanButton, humanVsAIButton, newGameButton, undoButton, exitButton;
private JPanel boardPanel;
public Gobang() {
setTitle("Gobang");
setSize(ROWS * SIZE + 200, COLS * SIZE);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
boardPanel = new JPanel();
boardPanel.setLayout(new GridLayout(ROWS, COLS));
boardPanel.setPreferredSize(new Dimension(ROWS * SIZE, COLS * SIZE));
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
JButton button = new JButton();
button.setPreferredSize(new Dimension(SIZE, SIZE));
button.setBackground(Color.lightGray);
button.setBorder(BorderFactory.createLineBorder(Color.black));
button.addMouseListener(this);
boardPanel.add(button);
}
}
add(boardPanel, BorderLayout.CENTER);
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new GridLayout(6, 1));
humanVsHumanButton = new JButton("Human vs. Human");
humanVsHumanButton.addActionListener(this);
controlPanel.add(humanVsHumanButton);
humanVsAIButton = new JButton("Human vs. AI");
humanVsAIButton.addActionListener(this);
controlPanel.add(humanVsAIButton);
newGameButton = new JButton("New Game");
newGameButton.addActionListener(this);
controlPanel.add(newGameButton);
undoButton = new JButton("Undo");
undoButton.addActionListener(this);
controlPanel.add(undoButton);
exitButton = new JButton("Exit");
exitButton.addActionListener(this);
controlPanel.add(exitButton);
statusLabel = new JLabel("Black's turn");
controlPanel.add(statusLabel);
add(controlPanel, BorderLayout.EAST);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == humanVsHumanButton) {
humanVsHuman = true;
humanFirst = true;
newGame();
} else if (e.getSource() == humanVsAIButton) {
humanVsHuman = false;
humanFirst = true;
newGame();
} else if (e.getSource() == newGameButton) {
newGame();
} else if (e.getSource() == undoButton) {
undo();
} else if (e.getSource() == exitButton) {
System.exit(0);
}
}
private void newGame() {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
board[i][j] = EMPTY;
JButton button = (JButton) boardPanel.getComponent(i * COLS + j);
button.setIcon(null);
button.setEnabled(true);
}
}
currentPlayer = humanFirst ? BLACK : WHITE;
gameOver = false;
updateStatusLabel();
if (!humanFirst && !humanVsHuman) {
makeMove();
}
}
private void undo() {
if (gameOver) {
return;
}
int lastMoveRow = -1, lastMoveCol = -1;
for (int i = ROWS - 1; i >= 0; i--) {
for (int j = COLS - 1; j >= 0; j--) {
if (board[i][j] != EMPTY) {
lastMoveRow = i;
lastMoveCol = j;
board[i][j] = EMPTY;
JButton button = (JButton) boardPanel.getComponent(i * COLS + j);
button.setIcon(null);
button.setEnabled(true);
updateStatusLabel();
return;
}
}
}
}
private void makeMove() {
if (gameOver) {
return;
}
if (humanVsHuman || currentPlayer == BLACK) {
return;
}
int[] move = findBestMove();
int row = move[0], col = move[1];
board[row][col] = WHITE;
JButton button = (JButton) boardPanel.getComponent(row * COLS + col);
button.setIcon(new ImageIcon(getClass().getResource("white.png")));
button.setEnabled(false);
currentPlayer = BLACK;
if (isWinningMove(WHITE, row, col)) {
gameOver = true;
JOptionPane.showMessageDialog(this, "White wins!");
} else if (isDraw()) {
gameOver = true;
JOptionPane.showMessageDialog(this, "Draw!");
} else {
updateStatusLabel();
}
}
private void updateStatusLabel() {
if (gameOver) {
statusLabel.setText("Game over");
} else if (humanVsHuman) {
statusLabel.setText(currentPlayer == BLACK ? "Black's turn" : "White's turn");
} else if (currentPlayer == BLACK) {
statusLabel.setText("Your turn");
} else {
statusLabel.setText("Computer's turn");
}
}
private int evaluatePosition(int[][] board, int player) {
int score = 0;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (board[i][j] == player) {
score += evaluatePositionHelper(board, i, j, player);
} else if (board[i][j] == -player) {
score -= evaluatePositionHelper(board, i, j, -player);
}
}
}
return score;
}
private int evaluatePositionHelper(int[][] board, int row, int col, int player) {
int score = 0;
for (int k = 0; k < 4; k++) {
int count = 0;
boolean open1 = false, open2 = false;
for (int delta = -4; delta <= 4; delta++) {
int r = row + delta * dx[k], c = col + delta * dy[k];
if (r >= 0 && r < ROWS && c >= 0 && c < COLS && board[r][c] == player) {
count++;
} else {
if (count == 4) {
score += 10000;
} else if (count == 3) {
if (open1 || open2) {
score += 1000;
} else {
score += 100;
}
} else if (count == 2) {
if (open1 && open2) {
score += 100;
} else {
score += 10;
}
} else if (count == 1) {
if (open1 && open2) {
score += 10;
} else {
score += 1;
}
}
if (delta == -1 && r >= 0 && r < ROWS && c >= 0 && c < COLS && board[r][c] == EMPTY) {
open1 = true;
}
if (delta == 1 && r >= 0 && r < ROWS && c >= 0 && c < COLS && board[r][c] == EMPTY) {
open2 = true;
}
count = 0;
}
}
}
return score;
}
private int[] findBestMove() {
int[] bestMove = new int[] {-1, -1};
int bestScore = Integer.MIN_VALUE;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (board[i][j] == EMPTY) {
board[i][j] = WHITE;
int score = minMax(board, BLACK, 4, Integer.MIN_VALUE, Integer.MAX_VALUE);
board[i][j] = EMPTY;
if (score > bestScore) {
bestMove[0] = i;
bestMove[1] = j;
bestScore = score;
}
}
}
}
return bestMove;
}
private int minMax(int[][] board, int player, int depth, int alpha, int beta) {
if (depth == 0 || isWinningMove(BLACK, -1, -1) || isWinningMove(WHITE, -1, -1) || isDraw()) {
return evaluatePosition(board, BLACK);
}
if (player == BLACK) {
int bestScore = Integer.MIN_VALUE;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (board[i][j] == EMPTY) {
board[i][j] = player;
int score = minMax(board, WHITE, depth - 1, alpha, beta);
board[i][j] = EMPTY;
bestScore = Math.max(bestScore, score);
alpha = Math.max(alpha, score);
if (beta <= alpha) {
return bestScore;
}
}
}
}
return bestScore;
} else {
int bestScore = Integer.MAX_VALUE;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (board[i][j] == EMPTY) {
board[i][j] = player;
int score = minMax(board, BLACK, depth - 1, alpha, beta);
board[i][j] = EMPTY;
bestScore = Math.min(bestScore, score);
beta = Math.min(beta, score);
if (beta <= alpha) {
return bestScore;
}
}
}
}
return bestScore;
}
}
private boolean isWinningMove(int player, int row, int col) {
if (row == -1 && col == -1) {
return false;
}
for (int k = 0; k < 4; k++) {
int count = 1;
for (int delta = 1; delta <= 4; delta++) {
int r = row + delta * dx[k], c = col + delta * dy[k];
if (r >= 0 && r < ROWS && c >= 0 && c < COLS && board[r][c] == player) {
count++;
} else {
break;
}
}
for (int delta = -1; delta >= -4; delta--) {
int r = row + delta * dx[k], c = col + delta * dy[k];
if (r >= 0 && r < ROWS && c >= 0 && c < COLS && board[r][c] == player) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
}
return false;
}
private boolean isDraw() {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (board[i][j] == EMPTY) {
return false;
}
}
}
return true;
}
private int[] getButtonIndex(JButton button) {
int index = boardPanel.getComponentZOrder(button);
int row = index / COLS, col = index % COLS;
return new int[] {row, col};
}
private int[] dx = new int[] {-1, 0, 1, 1};
private int[] dy = new int[] {1, 1, 1, 0};
@Override
public void mouseClicked(MouseEvent e) {
if (gameOver) {
return;
}
JButton button = (JButton) e.getSource();
int[] index = getButtonIndex(button);
int row = index[0], col = index[1];
if (board[row][col] != EMPTY) {
return;
}
board[row][col] = currentPlayer;
button.setIcon(new ImageIcon(getClass().getResource(currentPlayer == BLACK ? "black.png" : "white.png")));
button.setEnabled(false);
if (isWinningMove(currentPlayer, row, col)) {
gameOver = true;
JOptionPane.showMessageDialog(this, currentPlayer == BLACK ? "Black wins!" : "White wins!");
} else if (isDraw()) {
gameOver = true;
JOptionPane.showMessageDialog(this, "Draw!");
} else {
currentPlayer = -currentPlayer;
updateStatusLabel();
if (currentPlayer == WHITE && !humanVsHuman) {
makeMove();
}
}
}
@Override
public void mouseEntered(MouseEvent e) {
JButton button = (JButton) e.getSource();
button.setBorder(BorderFactory.createLineBorder(Color.blue));
}
@Override
public void mouseExited(MouseEvent e) {
JButton button = (JButton) e.getSource();
button.setBorder(BorderFactory.createLineBorder(Color.black));
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
public static void main(String[] args) {
new Gobang();
}
}
```
在资源文件夹中,还需要有black.png和white.png两张图片,分别表示黑棋和白棋。如果需要美化界面,可以将按钮换成自定义的图标。
阅读全文