象棋規則 = 棋子類型 + 目標座標 + 棋盤狀態 的組合判斷。每種棋子獨立封裝合法移動邏輯。
public enum PieceType { 將帥, 士仕, 相象, 馬傌, 車俥, 炮砲, 卒兵 }
public enum Camp { 紅, 黑 }
public class Piece {
public PieceType Type;
public Camp Camp;
public int X, Y; // 0-8, 0-9
}
public class Board {
private Piece[,] grid = new Piece[9, 10]; // x:0-8, y:0-9
public bool IsValidMove(Piece piece, int targetX, int targetY) {
// 1. 邊界檢查
if (targetX < 0 || targetX > 8 || targetY < 0 || targetY > 9) return false;
// 2. 同色檢查
Piece target = grid[targetX, targetY];
if (target != null && target.Camp == piece.Camp) return false;
// 3. 具體規則
return CheckRule(piece, targetX, targetY, target);
}
private bool CheckRule(Piece piece, int tx, int ty, Piece target) {
int dx = tx - piece.X;
int dy = ty - piece.Y;
int adx = Math.Abs(dx), ady = Math.Abs(dy);
switch (piece.Type) {
case PieceType.車俥:
return (dx == 0 || dy == 0) && IsPathClear(piece.X, piece.Y, tx, ty);
case PieceType.馬傌:
return (adx == 1 && ady == 2) || (adx == 2 && ady == 1)
&& !IsLegBlocked(piece.X, piece.Y, tx, ty);
case PieceType.炮砲:
if (dx == 0 || dy == 0) {
int between = CountPiecesBetween(piece.X, piece.Y, tx, ty);
return (target == null && between == 0) || (target != null && between == 1);
}
return false;
// ... 士仕(九宮斜走)、相象(田字腿不塞腿)、將帥(九宮直走/飛將)、卒兵(過河橫走)
}
return false;
}
// 輔助:路徑檢查、馬腿檢查、炮台計數
private bool IsPathClear(int x1, int y1, int x2, int y2) { /* 直線掃描 */ }
private bool IsLegBlocked(int x1, int y1, int x2, int y2) { /* 馬腿座標判斷 */ }
private int CountPiecesBetween(int x1, int y1, int x2, int y2) { /* 掃描計數 */ }
}
| 棋子 | 移動規則 | 特殊檢查 |
|---|---|---|
| 車 | 直線任意格 | 路徑無阻擋 |
| 馬 | 日字形 (1,2) | 馬腿不被阻擋 (中間相鄰點無子) |
| 炮 | 直線任意格 | 不吃子時路徑無子;吃子時路徑恰好 1 子作炮台 |
| 相/象 | 田字形 (2,2) | 相眼不被阻擋 (中心點無子);不過河 |
| 士/仕 | 九宮斜線 1 格 | 不出九宮 |
| 將/帥 | 九宮直線 1 格 | 不出九宮;飛將規則 (同檔無子直接將軍) |
| 卒/兵 | 前進 1 格;過河後可左右 | 不可後退 |
Board 作為單例或掛在 GameManager 上。Piece 數據,點擊事件調用 Board.IsValidMove 高亮合法目標格。DOTween 或協程插值,動畫結束後更新 grid 數組。Stack 記錄 (piece, fromX, fromY, capturedPiece)。將規則封裝在 Board.CheckRule 中,配合輔助掃描方法,即可清晰實現中國象棋全規則判斷。