You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于JFrame和JPanel的Java象棋棋子移动规则实现咨询

象棋棋子移动规则实现方案建议

核心设计思路

基于多态特性,在抽象父类ChessPiece中定义用于判断移动合法性的抽象方法,每个棋子子类(Pawn、King等)重写该方法,实现各自的专属移动规则。主逻辑中只需统一调用该方法,即可完成不同棋子的合法性校验。

步骤1:重构ChessPiece类

将ChessPiece改为抽象类,封装基础属性并添加抽象校验方法:

public abstract class ChessPiece {
    protected String color; // 例如"black"或"white"
    protected int x;
    protected int y;

    public ChessPiece(String color, int x, int y) {
        this.color = color;
        this.x = x;
        this.y = y;
    }

    // 抽象方法:判断从(fromX, fromY)到(toX, toY)的移动是否合法
    // board参数用于获取棋盘其他棋子信息,判断阻挡或吃子规则
    public abstract boolean isValidMove(int fromX, int fromY, int toX, int toY, ChessPiece[][] board);

    // getter/setter方法
    public String getColor() { return color; }
    public int getX() { return x; }
    public int getY() { return y; }
    public void setPosition(int x, int y) { this.x = x; this.y = y; }
}

步骤2:Pawn(兵)类的移动规则实现

中国象棋兵规则实现

  • 未过河:仅能向前走1格,不可左右移动,目标位置需为空
  • 过河后:可向前、左、右走1格,目标位置可为空或敌方棋子
public class Pawn extends ChessPiece {
    public Pawn(String color, int x, int y) {
        super(color, x, y);
    }

    @Override
    public boolean isValidMove(int fromX, int fromY, int toX, int toY, ChessPiece[][] board) {
        // 校验目标位置是否在棋盘范围内
        if (toX < 0 || toX >= 9 || toY < 0 || toY >= 10) return false;
        
        ChessPiece targetPiece = board[toY][toX];
        // 目标位置不能是己方棋子
        if (targetPiece != null && targetPiece.getColor().equals(this.color)) return false;

        int xDiff = Math.abs(toX - fromX);
        int yDiff = Math.abs(toY - fromY);

        // 黑兵(初始位于y≥7)逻辑
        if (this.color.equals("black")) {
            if (fromY >= 5) {
                // 未过河:仅向前走1格,x坐标不变,目标为空
                return xDiff == 0 && toY == fromY - 1 && targetPiece == null;
            } else {
                // 过河后:上下左右1格范围内,目标为空或敌方棋子
                return yDiff == 1 && xDiff <= 1 && (targetPiece == null || !targetPiece.getColor().equals(this.color));
            }
        } 
        // 白兵(初始位于y≤2)逻辑
        else if (this.color.equals("white")) {
            if (fromY <= 4) {
                return xDiff == 0 && toY == fromY + 1 && targetPiece == null;
            } else {
                return yDiff == 1 && xDiff <= 1 && (targetPiece == null || !targetPiece.getColor().equals(this.color));
            }
        }

        return false;
    }
}

国际象棋兵规则实现

  • 普通移动:向前走1格,目标位置为空
  • 初始移动:未移动过的兵可向前走2格,路径无阻挡
  • 吃子规则:斜向走1格,目标为敌方棋子
public class Pawn extends ChessPiece {
    public Pawn(String color, int x, int y) {
        super(color, x, y);
    }

    @Override
    public boolean isValidMove(int fromX, int fromY, int toX, int toY, ChessPiece[][] board) {
        if (toX < 0 || toX >= 8 || toY < 0 || toY >= 8) return false;
        ChessPiece target = board[toY][toX];
        int yDirection = this.color.equals("white") ? 1 : -1; // 白兵向上,黑兵向下

        // 普通向前移动
        if (toX == fromX && toY == fromY + yDirection && target == null) {
            return true;
        }

        // 初始2格移动
        if (toX == fromX && toY == fromY + 2 * yDirection) {
            boolean isInitialPos = (this.color.equals("white") && fromY == 1) || (this.color.equals("black") && fromY == 6);
            return isInitialPos && board[fromY + yDirection][fromX] == null && target == null;
        }

        // 斜向吃子
        if (Math.abs(toX - fromX) == 1 && toY == fromY + yDirection) {
            return target != null && !target.getColor().equals(this.color);
        }

        return false;
    }
}

步骤3:King(王)类的移动规则实现

中国象棋王规则实现

  • 仅能在九宫格内移动(黑王:y≥7,3≤x≤5;白王:y≤2,3≤x≤5)
  • 每次仅能走1格(上下左右)
public class King extends ChessPiece {
    public King(String color, int x, int y) {
        super(color, x, y);
    }

    @Override
    public boolean isValidMove(int fromX, int fromY, int toX, int toY, ChessPiece[][] board) {
        // 校验九宫格范围
        if (this.color.equals("black")) {
            if (toY < 7 || toX < 3 || toX > 5) return false;
        } else {
            if (toY > 2 || toX < 3 || toX > 5) return false;
        }

        ChessPiece target = board[toY][toX];
        if (target != null && target.getColor().equals(this.color)) return false;

        // 仅能走1格(上下左右)
        int xDiff = Math.abs(toX - fromX);
        int yDiff = Math.abs(toY - fromY);
        return (xDiff == 1 && yDiff == 0) || (xDiff == 0 && yDiff == 1);
    }
}

国际象棋王规则实现

  • 可向8个方向走1格
  • 目标位置不能是己方棋子
public class King extends ChessPiece {
    public King(String color, int x, int y) {
        super(color, x, y);
    }

    @Override
    public boolean isValidMove(int fromX, int fromY, int toX, int toY, ChessPiece[][] board) {
        if (toX < 0 || toX >= 8 || toY < 0 || toY >= 8) return false;
        ChessPiece target = board[toY][toX];
        if (target != null && target.getColor().equals(this.color)) return false;

        // 8个方向1格范围(排除原地不动)
        int xDiff = Math.abs(toX - fromX);
        int yDiff = Math.abs(toY - fromY);
        return (xDiff <= 1 && yDiff <= 1) && !(xDiff == 0 && yDiff == 0);
    }
}

步骤4:在App.java中整合校验逻辑

在处理用户移动操作时,调用棋子的isValidMove方法判断合法性,合法则执行移动:

// 假设获取到起始位置(startX, startY)和目标位置(targetX, targetY)
ChessPiece selectedPiece = board[startY][startX];
if (selectedPiece != null) {
    if (selectedPiece.isValidMove(startX, startY, targetX, targetY, board)) {
        // 执行移动逻辑
        board[targetY][targetX] = selectedPiece;
        board[startY][startX] = null;
        selectedPiece.setPosition(targetX, targetY);
        // 刷新棋盘UI
        repaint();
    } else {
        // 提示非法移动
        System.out.println("非法移动!");
    }
}

额外注意事项

  • 路径阻挡校验:车、马、象等棋子需额外判断移动路径上是否有其他棋子阻挡(Pawn和King基本无需处理,除国际象棋兵的初始2格)
  • 特殊规则:中国象棋"王不见王"、国际象棋"王车易位"等规则,需在主逻辑或对应棋子类中额外实现
  • 坐标一致性:确保棋盘行/列的坐标定义统一,避免方向逻辑错误

内容的提问来源于stack exchange,提问作者RICCARDO PICCO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 12:30:44