namespace ChineseChess; using System; using System.Collections.Generic; using System.Linq; using Vector; using static ChineseChess.ChessCore; public class CCPiece : AbstractPiece { public string CNName { get; protected set; } public TurnsSideType TurnsSide { get; } protected CCBoard board; protected Vector2I localPos = new(); static readonly Trans2DI transRedGlobal2Local = new(new Vector2I(1, 0), new Vector2I(0, -1), new Vector2I(-4, 9)); static readonly Trans2DI transBlackGlobal2Local = new(new Vector2I(-1, 0), new Vector2I(0, 1), new Vector2I(4, 0)); public CCPiece(CCBoard board = null, TurnsSideType turnsSide = TurnsSideType.Red, string name = "", Vector2I pos = null) : base(name) { this.board = board; TurnsSide = turnsSide; OnPos += (sender, args) => { localPos = Global2Local(Pos); }; Pos = pos != null ? Local2Global(pos) : Vector2I.Zero; } public override bool CanMove(Vector2I to) { return CanMoveAllPos().Any(item => item == to); } protected Vector2I Local2Global(in Vector2I pos) { return TurnsSide == TurnsSideType.Red ? (pos * transRedGlobal2Local) : (pos * transBlackGlobal2Local); } protected Vector2I Global2Local(in Vector2I pos) { return TurnsSide == TurnsSideType.Red ? (transRedGlobal2Local * pos) : (transBlackGlobal2Local * pos); } protected CCPiece GetCCPieceLocal(in Vector2I pos) { return (CCPiece)board.GetPiece(Local2Global(pos)); } public virtual List CanMoveAllPosSelf() { return new List(); } public IEnumerable CanMoveAllPosLocal() { var self = CanMoveAllPosSelf().Select(item => item + localPos);// 转换局部坐标 var ret = self.Where(item => { bool ret = GetCCPieceLocal(item) == null || GetCCPieceLocal(item).TurnsSide != TurnsSide; // Console.WriteLine($"{item} can move: {ret}"); return ret; }); // 过滤无效位置 // Console.WriteLine("localPos: {0}", localPos); // Console.WriteLine("CanMoveAllPosSelf: {0}", string.Join(",", self)); // Console.WriteLine("CanMoveAllPosLocal: {0}", string.Join(",", ret)); return ret; } public IEnumerable CanMoveAllPos() { var ret = CanMoveAllPosLocal() .Select(item => Local2Global(item)); // 转换为全局坐标 // Console.WriteLine("CanMoveAllPos: {0}", string.Join(",", ret)); return ret; } protected bool IsPosOutOfRangeLocal(Vector2I pos) { return board.IsPosOutOfRange(Local2Global(pos)); } protected CCPiece GetRecursivePieceLocal(Vector2I origin, Vector2I pos) { Vector2I with = origin + pos; while (!IsPosOutOfRangeLocal(with) && GetCCPieceLocal(with) == null) { with += pos; } return GetCCPieceLocal(with); } }