Commit 7d5e366f authored by 林修诚's avatar 林修诚
Browse files

ok

parents
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
package Components;

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/* 这个你不用来看 */
public abstract class BasicComponent extends JComponent {
    public BasicComponent() {
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                super.mousePressed(e);
                onMouseClicked();
            }
        });
    }

    public abstract void onMouseClicked();
}
+222 −0
Original line number Diff line number Diff line

package Components;

import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.plaf.DimensionUIResource;

import java.awt.*;

import Model.ChessPiece;
import Core.*;

public class ChessBoardPanel extends JPanel {
    private int boardRows = 8;// 行数
    private int boardCols = 8;// 列数
    private static int everyFromLength = 50;
    private ChessPanel[][] chessBoard;// 棋盘
    private int[][] lastChessGrids;
    private int[][] saveGrids;

    public ChessBoardPanel(int boardRows, int boardCols) {
        this.setVisible(true);
        this.setFocusable(true);
        this.setLayout(new GridLayout(this.boardRows, this.boardCols));
        this.setBackground(Color.PINK);// todo: choose a beautiful color
        this.boardRows = boardRows;
        this.boardCols = boardCols;
        chessBoard = new ChessPanel[boardRows][boardCols];
        ChessPanel.setSize(100);
        intitalChessPanel();
    }

    public void intitalChessPanel() {// 初始化每个格子
        this.lastChessGrids = new int[8][8];
        this.saveGrids = new int[8][8];
        for (int i = 0; i != boardRows; ++i) {
            for (int j = 0; j != boardCols; ++j) {
                ChessPanel tempPanel = new ChessPanel(i, j);
                this.add(tempPanel);
                chessBoard[i][j] = tempPanel;
            }
        }
    }

    public void setChess(int row, int col, ChessPiece chess) {// 在指定格子放棋
        chessBoard[row][col].setChessPiece(chess);
    }

    public ChessPiece getChess(int y, int x) {
        return chessBoard[y][x].getChessPiece();
    }

    public boolean isEmpty(int col, int row) {
        if (chessBoard[col][row].getChessPiece() == ChessPiece.EMPTY) {
            return true;
        }
        return false;
    }

    public boolean canClickGrid(int row, int col, ChessPiece currentPlayer) {// 判断该格子是否可以放棋
        int[][] digitBoard = new int[8][8];
        int color;
        if (currentPlayer == ChessPiece.BLACK) {
            color = -1;
        } else {
            color = 1;
        }
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (chessBoard[i][j].getChessPiece() == ChessPiece.BLACK) {
                    digitBoard[i][j] = -1;
                }
                if (chessBoard[i][j].getChessPiece() == ChessPiece.WHITE) {
                    digitBoard[i][j] = 1;
                }
                if (chessBoard[i][j].getChessPiece() == ChessPiece.EMPTY) {
                    digitBoard[i][j] = 0;
                }
            }
        }

        for (int i = 0; i < 8; i++) { // 刷新棋盘之前把上一步拷到undogrids里
            for (int j = 0; j < 8; j++) {
                if (chessBoard[i][j].getChessPiece() == ChessPiece.BLACK) {
                    lastChessGrids[i][j] = -1;
                }
                if (chessBoard[i][j].getChessPiece() == ChessPiece.WHITE) {
                    lastChessGrids[i][j] = 1;
                }
                if (chessBoard[i][j].getChessPiece() == ChessPiece.EMPTY) {
                    lastChessGrids[i][j] = 0;
                }
            }
        }

        DigitBoard d = new DigitBoard(row, col, color, digitBoard);
        d.DoLogic();
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (d.getAns(i, j) == -1) {
                    chessBoard[i][j].setChessPiece(ChessPiece.BLACK);
                }
                if (d.getAns(i, j) == 1) {
                    chessBoard[i][j].setChessPiece(ChessPiece.WHITE);
                }
                if (d.getAns(i, j) == 0) {
                    chessBoard[i][j].setChessPiece(ChessPiece.EMPTY);
                }
            }
        }
        repaint();
        return d.getAns(row, col) == color;
    }

    public boolean isGameOver(ChessPiece currentPlayer) {
        int color;
        if (currentPlayer == ChessPiece.BLACK) {
            color = -1;
        } else {
            color = 1;
        }
        int[][] digitBoard = new int[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (chessBoard[i][j].getChessPiece() == ChessPiece.BLACK) {
                    digitBoard[i][j] = -1;
                }
                if (chessBoard[i][j].getChessPiece() == ChessPiece.WHITE) {
                    digitBoard[i][j] = 1;
                }
                if (chessBoard[i][j].getChessPiece() == null) {
                    digitBoard[i][j] = 0;
                }
            }
        }

        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                while (digitBoard[i][j] != 0) {
                    DigitBoard db = new DigitBoard(i, j, color, digitBoard);
                    db.DoLogic();
                    if (db.outBoard != digitBoard) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    public void undoStep() { // 读取撤销棋盘
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (lastChessGrids[i][j] == -1) {
                    chessBoard[i][j].setChessPiece(ChessPiece.BLACK);
                }
                if (lastChessGrids[i][j] == 1) {
                    chessBoard[i][j].setChessPiece(ChessPiece.WHITE);
                }
                if (lastChessGrids[i][j] == 0) {
                    chessBoard[i][j].setChessPiece(ChessPiece.EMPTY);
                }
            }
        }
        repaint();
    }

    public void saveGame() { // 存档 存一个txt 由210和最后一步玩家(玩家在gamecore写入)组成 简陋但有效
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (chessBoard[i][j].getChessPiece() == ChessPiece.BLACK) {
                    saveGrids[i][j] = 2;
                }
                if (chessBoard[i][j].getChessPiece() == ChessPiece.WHITE) {
                    saveGrids[i][j] = 1;
                }
                if (chessBoard[i][j].getChessPiece() == ChessPiece.EMPTY) {
                    saveGrids[i][j] = 0;
                }
            }
        }
    }

    public void readGame(String readGame) { // 读取 数字代表棋子颜色
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                String substring = readGame.substring(i * 8 + j, i * 8 + j + 1);
                if (substring.equals("2")) {
                    chessBoard[i][j].setChessPiece(ChessPiece.BLACK);
                }
                if (substring.equals("1")) {
                    chessBoard[i][j].setChessPiece(ChessPiece.WHITE);
                }
                if (substring.equals("0")) {
                    chessBoard[i][j].setChessPiece(ChessPiece.EMPTY);
                }
            }
        }
        repaint();
    }

    @Override
    public String toString() { // 存档用
        StringBuilder saveString = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                saveString.append(saveGrids[i][j]);
            }
        }
        return String.valueOf(saveString);
    }

    @Override
    public Dimension getPreferredSize() {
        return chessBoard[0][0].getPreferredSize();
    }

    public void autoZoom(int width, int height) {// zoom
        this.setSize(chessBoard[0][0].getPreferredSize());
    }
}
 No newline at end of file
+107 −0
Original line number Diff line number Diff line
package Components;

import javax.swing.ImageIcon;
import javax.swing.plaf.DimensionUIResource;

import Core.GameCore;
import GameUI.ChessGameUI;

import java.awt.*;
import Model.ChessPiece;

public class ChessPanel extends BasicComponent {
    private int row;
    private int col;
    private static int size = 8;
    private ChessPiece playersChess;
    ImageIcon emptyImg = new ImageIcon("Resources/empty.png");
    ImageIcon whiteImg = new ImageIcon("Resources/white1.png");
    ImageIcon blackImg = new ImageIcon("Resources/black1.png");
    ImageIcon image;

    ChessPanel(int row, int col) {
        setVisible(true);
        this.row = row;
        this.col = col;
        // setPreferredSize(new Dimension(40, 40));
        image = emptyImg;
        playersChess = ChessPiece.EMPTY;

    }

    public static void setSize(int size) {
        ChessPanel.size = size;
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension space = getParent().getParent().getSize();
        int length = 8 * (Math.min(space.width / 8, space.height / 8));
        // System.out.println(space.width + "\t" + space.height + "\t" + length);
        return new Dimension(length, length);
    }

    @Override
    public void onMouseClicked() {// todo 鼠标点击时的动作
        System.out.printf("%s clicked (%d, %d)\n",
                ChessGameUI.thisGameCore.getCurrentPlayer(), row, col);
        // todo: complete mouse click method
        if (ChessGameUI.thisGameCore.canClick(row, col)) {// todo
            ChessGameUI.thisGameCore.countScore();
            this.playersChess = ChessGameUI.thisGameCore.getCurrentPlayer();
            ChessGameUI.thisGameCore.swapPlayer();
            paintChess(playersChess);
        }
        ChessGameUI.undoCnt = 0;
        ChessGameUI.thisGameCore.checkGameOver();
    }

    @Override
    protected void paintComponent(Graphics g) {// 画棋子
        super.paintComponent(g);

        int width = this.getWidth();
        int height = this.getHeight();
        int drawWidth = Math.min(width, height);
        int drawHeight = drawWidth;

        Image imageTrans = image.getImage(); // transform it
        int size = drawWidth;
        Image newimg = imageTrans.getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH); // scale it the smooth way
        ImageIcon imgZoomed = new ImageIcon(newimg); // transform it back

        imgZoomed.paintIcon(this, g, 0, 0);
        // System.out.println(width);
    }

    private void paintChess(ChessPiece playersChess) {// 画棋子
        switch (playersChess) {
            case BLACK -> image = blackImg;
            case WHITE -> image = whiteImg;
            case EMPTY -> image = emptyImg;
            default -> throw new IllegalArgumentException("Unexpected value: " + playersChess);
        }
        repaint();
    }

    public void configSize(int grindPanelSize) {// 初始化长宽
    }

    public ChessPiece getChessPiece() {// 获取当前位置的棋子
        return playersChess;
    }

    public void setChessPiece(ChessPiece player) {// 放棋
        this.playersChess = player;
        paintChess(this.playersChess);
    }

    /* 获取当前棋子的行列(好像没啥用) */
    public int getRow() {
        return row;
    }

    public int getCol() {
        return col;
    }
}
+172 −0
Original line number Diff line number Diff line
package Core;

public class DigitBoard {
    int[][] inBoard = new int[8][8];
    public int[][] outBoard = new int[8][8];
    int[][] operate = new int[1][2];
    int color = 0;

    public DigitBoard(int row, int col, int color, int[][] digitBoard) {
        this.inBoard = digitBoard;
        this.color = color;
        this.operate[0][0] = row;
        this.operate[0][1] = col;
    }

    public void DoLogic() {
        for (int i = 0, flag = 0; i != 1; this.color *= -1, flag = 0, ++i) {
            boolean[][][] direction = CheckAvailable(this.inBoard, this.operate[i], this.color);
            for (int j = 0; j != 8; ++j) {
                if (direction[this.operate[i][0]][this.operate[i][1]][j]) {
                    ++flag;
                    this.inBoard = OperateMat(this.inBoard, this.operate[i], direction, this.color);
                }
            }
            if (flag == 0)
                break;
        }
        for (int i = 0; i < 8; i++) {
            System.arraycopy(this.inBoard[i], 0, this.outBoard[i], 0, 8);
        }
    }

    public int getAns(int y, int x) {
        return this.outBoard[y][x];
    }

    public static boolean CheckEmptyPoint(int[][] mat, int[] pos, int color) {
        return mat[pos[0]][pos[1]] == 0;
    }

    public static boolean CheckRivalColorLine(int[][] mat, int row, int col, int pointColor, int rowFlag, int colFlag) {
        for (; row + rowFlag > -1 && row + rowFlag < 8 && col + colFlag > -1
                && col + colFlag < 8; rowFlag = FlagChange(rowFlag), colFlag = FlagChange(colFlag)) {
            if (mat[row + rowFlag][col + colFlag] == 0)
                return false;
            if (mat[row + rowFlag][col + colFlag] == pointColor)
                return false;
            if (mat[row + rowFlag][col + colFlag] == -pointColor)
                return true;
        }
        return false;
    }

    public static boolean CheckSelfColorLine(int[][] mat, int row, int col, int pointColor, int rowFlag, int colFlag) {
        for (int count = 0; row + rowFlag > -1 && row + rowFlag < 8 && col + colFlag > -1
                && col + colFlag < 8; rowFlag = FlagChange(rowFlag), colFlag = FlagChange(colFlag), ++count) {
            if (mat[row + rowFlag][col + colFlag] == 0)
                return false;
            if (mat[row + rowFlag][col + colFlag] == pointColor) {
                return count != 0;
            }
        }
        return false;
    }

    public static int[][] ChangeRivalColor(int[][] mat, int[] pos, int rowFlag, int colFlag, int selfcolor) {
        int[][] result = mat;
        for (; pos[0] + rowFlag > -1 && pos[0] + rowFlag < 8 && pos[1] + colFlag > -1
                && pos[1] + colFlag < 8; rowFlag = FlagChange(rowFlag), colFlag = FlagChange(colFlag)) {
            if (mat[pos[0] + rowFlag][pos[1] + colFlag] == selfcolor)
                break;
            if (mat[pos[0] + rowFlag][pos[1] + colFlag] == -selfcolor) {
                result[pos[0] + rowFlag][pos[1] + colFlag] = selfcolor;
            }
        }
        return result;
    }

    public static int FlagChange(int flag) {
        if (flag == 0)
            ;
        else if (flag < 0)
            --flag;
        else
            ++flag;
        return flag;
    }

    public static boolean[][][] CheckAvailable(int[][] mat, int[] pos, int color) {
        boolean[][][] direction = new boolean[8][8][8];
        if (CheckEmptyPoint(mat, pos, color)) {
            if (CheckRivalColorLine(mat, pos[0], pos[1], color, 1, 0)
                    && CheckSelfColorLine(mat, pos[0], pos[1], color, 1, 0))
                direction[pos[0]][pos[1]][4] = true;
            if (CheckRivalColorLine(mat, pos[0], pos[1], color, -1, 0)
                    && CheckSelfColorLine(mat, pos[0], pos[1], color, -1, 0))
                direction[pos[0]][pos[1]][0] = true;
            if (CheckRivalColorLine(mat, pos[0], pos[1], color, 0, -1)
                    && CheckSelfColorLine(mat, pos[0], pos[1], color, 0, -1))
                direction[pos[0]][pos[1]][6] = true;
            if (CheckRivalColorLine(mat, pos[0], pos[1], color, 0, 1)
                    && CheckSelfColorLine(mat, pos[0], pos[1], color, 0, 1))
                direction[pos[0]][pos[1]][2] = true;
            if (CheckRivalColorLine(mat, pos[0], pos[1], color, -1, -1)
                    && CheckSelfColorLine(mat, pos[0], pos[1], color, -1, -1))
                direction[pos[0]][pos[1]][7] = true;
            if (CheckRivalColorLine(mat, pos[0], pos[1], color, 1, 1)
                    && CheckSelfColorLine(mat, pos[0], pos[1], color, 1, 1))
                direction[pos[0]][pos[1]][3] = true;
            if (CheckRivalColorLine(mat, pos[0], pos[1], color, -1, 1)
                    && CheckSelfColorLine(mat, pos[0], pos[1], color, -1, 1))
                direction[pos[0]][pos[1]][1] = true;
            if (CheckRivalColorLine(mat, pos[0], pos[1], color, 1, -1)
                    && CheckSelfColorLine(mat, pos[0], pos[1], color, 1, -1))
                direction[pos[0]][pos[1]][5] = true;
        }
        return direction;
    }

    public static int[][] OperateMat(int[][] mat, int[] position, boolean[][][] direction, int color) {
        int[][] result = new int[8][8];
        for (int k = 0; k != 8; ++k) {
            if (direction[position[0]][position[1]][k]) {
                int rowFlag, colFlag;
                switch (k) {
                    case 0:
                        rowFlag = -1;
                        colFlag = 0;
                        result = ChangeRivalColor(mat, position, rowFlag, colFlag, color);
                        break;
                    case 1:
                        rowFlag = -1;
                        colFlag = 1;
                        result = ChangeRivalColor(mat, position, rowFlag, colFlag, color);
                        break;
                    case 2:
                        rowFlag = 0;
                        colFlag = 1;
                        result = ChangeRivalColor(mat, position, rowFlag, colFlag, color);
                        break;
                    case 3:
                        rowFlag = 1;
                        colFlag = 1;
                        result = ChangeRivalColor(mat, position, rowFlag, colFlag, color);
                        break;
                    case 4:
                        rowFlag = 1;
                        colFlag = 0;
                        result = ChangeRivalColor(mat, position, rowFlag, colFlag, color);
                        break;
                    case 5:
                        rowFlag = 1;
                        colFlag = -1;
                        result = ChangeRivalColor(mat, position, rowFlag, colFlag, color);
                        break;
                    case 6:
                        rowFlag = 0;
                        colFlag = -1;
                        result = ChangeRivalColor(mat, position, rowFlag, colFlag, color);
                        break;
                    case 7:
                        rowFlag = -1;
                        colFlag = -1;
                        result = ChangeRivalColor(mat, position, rowFlag, colFlag, color);
                        break;
                }
            }
        }
        result[position[0]][position[1]] = color;
        return result;
    }
}
+178 −0
Original line number Diff line number Diff line
package Core;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.io.FileNotFoundException;

import Components.ChessBoardPanel;
import GameUI.ChessGameUI;
import GameUI.StatusUI;
import GameUI.TopBar;
import Model.CheatStatus;
import Model.ChessPiece;

public class GameCore {
    private ChessBoardPanel gamePanel;// 棋盘
    private int blackScore;// 字面意思
    private int whiteScore;
    private ChessPiece currentPlayer;// 当前该谁下棋
    private String importPath;
    private String exportPath;
    private int panelWidth;
    private int panelHeight;

    public GameCore(int rows, int cols) {
        this.gamePanel = new ChessBoardPanel(rows, cols);
        this.currentPlayer = ChessPiece.BLACK;
        intializeChess();
        blackScore = 2;
        whiteScore = 2;
        ChessGameUI.thisStatus.setScore(blackScore, whiteScore);

    }

    private void intializeChess() {// 初始化放棋

        gamePanel.setChess(3, 3, ChessPiece.BLACK);
        gamePanel.setChess(4, 4, ChessPiece.BLACK);
        gamePanel.setChess(3, 4, ChessPiece.WHITE);
        gamePanel.setChess(4, 3, ChessPiece.WHITE);
    }

    public void restart() {
        for (int i = 0; i != 8; ++i) {
            for (int j = 0; j != 8; ++j) {
                gamePanel.setChess(i, j, ChessPiece.EMPTY);
            }
        }
        intializeChess();
        currentPlayer = ChessPiece.BLACK;
        ChessGameUI.thisStatus.setCurrentPlayer(currentPlayer);
        countScore();
    }

    public void swapPlayer() {// 交换玩家
        countScore();
        if (this.currentPlayer == ChessPiece.BLACK) {
            this.currentPlayer = ChessPiece.WHITE;
        } else {
            this.currentPlayer = ChessPiece.BLACK;
        }
        ChessGameUI.thisStatus.setCurrentPlayer(currentPlayer);
    }

    public void zoom(int outerWidth, int outHeight) {// 缩放
        panelWidth = outerWidth;
        panelHeight = outHeight;
        gamePanel.autoZoom(panelWidth, panelHeight);
        // todo complete zoom
    }

    public void countScore() {// 计分
        int dw = 0;
        int db = 0;
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (this.gamePanel.getChess(i, j) == ChessPiece.BLACK) {
                    db++;
                }
                if (this.gamePanel.getChess(i, j) == ChessPiece.WHITE) {
                    dw++;
                }
            }
        }
        this.whiteScore = dw;
        this.blackScore = db;
        ChessGameUI.thisStatus.setScore(blackScore, whiteScore);
        ChessGameUI.thisTopBar.setScoreBar(blackScore, whiteScore);
        // todo 在这里更新scorebar的分数
    }

    public void readFileData(String filePath) throws FileNotFoundException {
        // todo: read date from file
        BufferedReader br = new BufferedReader(new FileReader(filePath));
        Scanner in = new Scanner(br);
        String str = in.nextLine();
        in.close();
        this.gamePanel.readGame(str);
        countScore();
        if (str.substring(64).equals("b")) {
            currentPlayer = ChessPiece.BLACK;
        } else {
            currentPlayer = ChessPiece.WHITE;
        }
    }

    public void writeDataToFile(String filePath) throws IOException {
        File file = new File(filePath, "save.txt");
        FileWriter out = new FileWriter(file);
        gamePanel.saveGame();
        out.write(gamePanel.toString());
        if (currentPlayer == ChessPiece.BLACK) {
            out.append("b");
        } else {
            out.append("w");
        }
        out.close();
    }

    public boolean canClick(int row, int col) {// 可以被点击
        if (!gamePanel.isEmpty(row, col)) {
            return false;
        }
        return gamePanel.canClickGrid(row, col, currentPlayer) || ChessGameUI.thisCheatModeStatus == CheatStatus.On;
    }

    public void undo() {// 撤销
        this.gamePanel.undoStep();
        swapPlayer();
        countScore();
    }

    private ChessPiece checkWinner() {// 检测胜者 下面那个满足就执行这个 其实返回值可以改void 然后补上谁赢了的弹窗
        if (this.blackScore > this.whiteScore) {
            return ChessPiece.BLACK;
        }
        if (this.blackScore < this.whiteScore) {
            return ChessPiece.WHITE;
        }
        return ChessPiece.EMPTY;
    }

    public boolean checkGameOver() {// 检测下完没 内部有调用checkWinner 这个每一次点击都会执行
        if (this.gamePanel.isGameOver(currentPlayer)) {
            System.out.println("gg");
            checkWinner();
        } else {
            System.out.println("continue");
        }
        return this.gamePanel.isGameOver(currentPlayer);
    }

    public void setImportpath(String importPath) throws FileNotFoundException {
        this.importPath = importPath;
        System.out.println(this.importPath);
        readFileData(importPath);
    }

    public void setExportPath(String exportPath) throws IOException {
        this.exportPath = exportPath;
        System.out.println(this.exportPath);
        writeDataToFile(exportPath);
    }

    public ChessPiece getCurrentPlayer() {
        return currentPlayer;
    }

    public ChessBoardPanel getGamePanel() {// 应该没啥用
        return gamePanel;
    }
}
 No newline at end of file