Java超进阶版五子棋

时间:2024-10-17 17:29:06

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. 编译和运行

  1. 编译:确保你在 gobang 文件夹的父目录中,然后使用以下命令编译所有类:

    javac -d bin src/gobang/*.java
  2. 运行:运行主类 GobangGUI

    java -cp bin gobang.GobangGUI

4. 解释

  • Board 类:管理棋盘的状态,包括初始化、检查移动是否有效、执行移动、检查胜负等。
  • Player 类:表示玩家,包含玩家的名字和符号。
  • Game 类:管理游戏的逻辑,包括切换玩家、检查棋盘是否已满等。
  • GobangGUI 类:使用 Swing 创建图形用户界面,显示棋盘和处理用户的点击事件。

5. 运行效果

当你运行 GobangGUI 类时,会弹出一个窗口,显示一个 15x15 的棋盘。玩家可以通过点击按钮来下棋,当有玩家获胜或棋盘已满时,会弹出相应的提示信息。