using Vector2 = Vector.Vector2I; using System; using System.Collections; using static IBoard.IBoardOn; namespace ChineseChess; public class ChessCore { public enum Mode { SingleMode, MultiMode, DebugMode, }; public enum TurnsSideType { Red, Black, }; public enum PlayerSideType { Self, Opponent, Any, }; private TurnsSideType sideType = TurnsSideType.Red; private readonly TurnsSideType selfSide; public readonly CCBoard board; private readonly Player playerSelf; private readonly Player playerOpponent; // public EventHandler OnMove; public ChessCore(Mode mode, TurnsSideType selfSide, ICCBoardOn? boardOn = null) { this.selfSide = selfSide; board = new(boardOn); playerSelf = new(board, Player.PlayerType.Human); playerOpponent = new(board, Player.PlayerType.Human); void func(object? _self, MoveEventArgs record) { // 防止 Undo 时 Selected Clear 出现 Null Pointer Exception playerSelf.SelectedClear(); playerOpponent.SelectedClear(); // TODO FIXME it can be simple if (record.From is null || record.To is null) { return; } IPiece? from = record.From is not null ? board.GetPiece(record.From) : null; IPiece? to = record.To is not null ? board.GetPiece(record.To) : null; board.AddRecord(from, to, record.From ?? new(), record.To ?? new()); } playerSelf.OnMove += func; playerOpponent.OnMove += func; switch (mode) { case Mode.SingleMode: break; case Mode.MultiMode: break; default: case Mode.DebugMode: throw new NotImplementedException(); } } public void Init() { (ArrayList blackPart, ArrayList redPart) = board.InitGame(); if (selfSide == TurnsSideType.Red) { playerSelf.SetAllowedPieces(redPart); playerOpponent.SetAllowedPieces(blackPart); } else { playerSelf.SetAllowedPieces(blackPart); playerOpponent.SetAllowedPieces(redPart); } } public void OnPosClicked(Vector2 pos, PlayerSideType clickedSide = PlayerSideType.Any) { if (GetTurnsType() == selfSide) { playerSelf.CanMove = true; playerOpponent.CanMove = false; } else { playerSelf.CanMove = false; playerOpponent.CanMove = true; } switch (clickedSide) { case PlayerSideType.Any: playerSelf.HandleBoardPosClick(pos); playerOpponent.HandleBoardPosClick(pos); break; case PlayerSideType.Self: playerSelf.HandleBoardPosClick(pos); break; case PlayerSideType.Opponent: playerOpponent.HandleBoardPosClick(pos); break; } } public TurnsSideType GetTurnsType() { sideType = board.Steps % 2 == 0 ? TurnsSideType.Red : TurnsSideType.Black; return sideType; } public void Undo() { playerSelf.SelectedClear(); playerOpponent.SelectedClear(); board.UndoRecord(); } public void ReInit() { playerSelf.SelectedClear(); playerOpponent.SelectedClear(); board.Clear(true); Init(); } }