1. 创建项目结构
首先,创建一个项目文件夹,例如 gobang
,并在其中创建以下文件:
gobang/
src/
gobang/
Board.java
Player.java
Game.java
GobangGUI.java
2. 编写代码
2.1 Board 类
package gobang;
public class Board {
public static final int SIZE = 15; // 棋盘大小
private char[][] board;
public Board() {
board = new char[SIZE][SIZE];
clearBoard();
}
public void clearBoard() {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
board[i][j] = '-';
}
}
}
public boolean isMoveValid(int row, int col) {
return row >= 0 && row < SIZE && col >= 0 && col < SIZE && board[row][col] == '-';
}
public void makeMove(int row, int col, char player) {
if (isMoveValid(row, col)) {
board[row][col] = player;
} else {
throw new IllegalArgumentException("Invalid move");
}
}
public boolean checkWin(char player) {
// 检查水平方向
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j <= SIZE - 5; j++) {
if (board[i][j] == player && board[i][j + 1] == player &&
board[i][j + 2] == player && board[i][j + 3] == player &&
board[i][j + 4] == player) {
return true;
}
}
}
// 检查垂直方向
for (int i = 0; i <= SIZE - 5; i++) {
for (int j = 0; j < SIZE; j++) {
if (board[i][j] == player && board[i + 1][j] == player &&
board[i + 2][j] == player && board[i + 3][j] == player &&
board[i + 4][j] == player) {
return true;
}
}
}
// 检查对角线方向(左上到右下)
for (int i = 0; i <= SIZE - 5; i++) {
for (int j = 0; j <= SIZE - 5; j++) {
if (board[i][j] == player && board[i + 1][j + 1] == player &&
board[i + 2][j + 2] == player && board[i + 3][j + 3] == player &&
board[i + 4][j + 4] == player) {
return true;
}
}
}
// 检查对角线方向(右上到左下)
for (int i = 0; i <= SIZE - 5; i++) {
for (int j = 4; j < SIZE; j++) {
if (board[i][j] == player && board[i + 1][j - 1] == player &&
board[i + 2][j - 2] == player && board[i + 3][j - 3] == player &&
board[i + 4][j - 4] == player) {
return true;
}
}
}
return false;
}
public char[][] getBoard() {
return board;
}
}
2.2 Player 类
package gobang;
public class Player {
private String name;
private char symbol;
public Player(String name, char symbol) {
this.name = name;
this.symbol = symbol;
}
public String getName() {
return name;
}
public char getSymbol() {
return symbol;
}
}
2.3 Game 类
package gobang;
public class Game {
private Board board;
private Player player1;
private Player player2;
private Player currentPlayer;
public Game(Player player1, Player player2) {
this.board = new Board();
this.player1 = player1;
this.player2 = player2;
this.currentPlayer = player1;
}
public void makeMove(int row, int col) {
if (board.isMoveValid(row, col)) {
board.makeMove(row, col, currentPlayer.getSymbol());
if (board.checkWin(currentPlayer.getSymbol())) {
System.out.println(currentPlayer.getName() + " wins!");
} else {
switchPlayer();
}
} else {
System.out.println("Invalid move. Try again.");
}
}
public boolean isBoardFull() {
for (int i = 0; i < Board.SIZE; i++) {
for (int j = 0; j < Board.SIZE; j++) {
if (board.board[i][j] == '-') {
return false;
}
}
}
return true;
}
private void switchPlayer() {
if (currentPlayer == player1) {
currentPlayer = player2;
} else {
currentPlayer = player1;
}
}
public Player getCurrentPlayer() {
return currentPlayer;
}
public Board getBoard() {
return board;
}
}
2.4 GobangGUI 类
package gobang;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GobangGUI extends JFrame {
private Game game;
private JButton[][] buttons;
public GobangGUI() {
Player player1 = new Player("Player 1", 'X');
Player player2 = new Player("Player 2", 'O');
game = new Game(player1, player2);
setTitle("Gobang Game");
setSize(600, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JPanel panel = new JPanel(new GridLayout(Board.SIZE, Board.SIZE));
buttons = new JButton[Board.SIZE][Board.SIZE];
for (int i = 0; i < Board.SIZE; i++) {
for (int j = 0; j < Board.SIZE; j++) {
buttons[i][j] = new JButton("");
buttons[i][j].addActionListener(new ButtonListener(i, j));
panel.add(buttons[i][j]);
}
}
add(panel);
setVisible(true);
}
private class ButtonListener implements ActionListener {
private int row;
private int col;
public ButtonListener(int row, int col) {
this.row = row;
this.col = col;
}
@Override
public void actionPerformed(ActionEvent e) {
game.makeMove(row, col);
updateBoard();
if (game.getBoard().checkWin(game.getCurrentPlayer().getSymbol())) {
JOptionPane.showMessageDialog(GobangGUI.this, game.getCurrentPlayer().getName() + " wins!", "Game Over", JOptionPane.INFORMATION_MESSAGE);
resetGame();
} else if (game.isBoardFull()) {
JOptionPane.showMessageDialog(GobangGUI.this, "It's a draw!", "Game Over", JOptionPane.INFORMATION_MESSAGE);
resetGame();
}
}
}
private void updateBoard() {
char[][] board = game.getBoard().getBoard();
for (int i = 0; i < Board.SIZE; i++) {
for (int j = 0; j < Board.SIZE; j++) {
buttons[i][j].setText(board[i][j] == '-' ? "" : String.valueOf(board[i][j]));
}
}
}
private void resetGame() {
game.getBoard().clearBoard();
updateBoard();
}
public static void main(String[] args) {
new GobangGUI();
}
}
3. 编译和运行
-
编译:确保你在
gobang
文件夹的父目录中,然后使用以下命令编译所有类:javac -d bin src/gobang/*.java
-
运行:运行主类
GobangGUI
:java -cp bin gobang.GobangGUI
4. 解释
- Board 类:管理棋盘的状态,包括初始化、检查移动是否有效、执行移动、检查胜负等。
- Player 类:表示玩家,包含玩家的名字和符号。
- Game 类:管理游戏的逻辑,包括切换玩家、检查棋盘是否已满等。
- GobangGUI 类:使用 Swing 创建图形用户界面,显示棋盘和处理用户的点击事件。
5. 运行效果
当你运行 GobangGUI
类时,会弹出一个窗口,显示一个 15x15 的棋盘。玩家可以通过点击按钮来下棋,当有玩家获胜或棋盘已满时,会弹出相应的提示信息。