using System; using System.Collections; using Vector2I = Vector.Vector2I; namespace ChineseChess; public class Player { private readonly CCBoard board; private readonly SelectedPiece selectedNode; public EventHandler OnMove; public bool CanMove { get; set; } = true; public enum PlayerType { Human, AI } public Player(CCBoard board, PlayerType type = PlayerType.Human) { this.board = board; this.selectedNode = new SelectedPiece(board); } public void HandleBoardPosClick(Vector2I clickPos) { if (board.IsPosOutOfRange(clickPos)) return; // Console.WriteLine($"VirtualBoard {clickPos} clicked"); IPiece clickChess = board.GetPiece(clickPos); if (!selectedNode.HasSelected()) { // Select piece if (clickChess == null) { // selectedNode.Clear(); return; } selectedNode.SetPos(clickPos); } else if (clickChess == selectedNode.GetPiece()) { // Unselect piece selectedNode.Clear(); } else { // Move piece // GD.Print("default MoveFunc Move: ", selectedNode.GetPos(), "->", clickPos); if (CanMove) MoveAndRecord(clickPos, selectedNode.GetPos()); } } public void MoveAndRecord(Vector2I toPos, Vector2I fromPos) { // GD.Print($"{fromPos} move to {toPos}"); IPiece toChess = board.GetPiece(toPos); IPiece fromChess = board.GetPiece(fromPos); if (fromChess != null) fromChess.IsSelected = false; selectedNode.Clear(); if (!fromChess.CanMove(toPos)) { return; } // MUST BE THERE !!! 防止删除节点后在启动回调导致错误 OnMove?.Invoke(this, new IBoard.MoveEventArgs { From = fromPos, To = toPos }); if (toChess != null) { board.RemovePiece(toPos); } board.MovePiece(fromPos, toPos); selectedNode.Clear(); } public void SelectedClear() { selectedNode.Clear(); } public void SetAllowedPieces(ArrayList allowedPieces) { selectedNode.allowedPieces = allowedPieces; } private class SelectedPiece { // Called when the node enters the scene tree for the first time. private Vector2I selectedNodePos = Vector2I.MaxValue; private IPiece piece; private readonly CCBoard board; public ArrayList allowedPieces = null; public SelectedPiece(CCBoard board) { this.board = board; } public void Clear() { if (selectedNodePos != Vector2I.MaxValue) { selectedNodePos = Vector2I.MaxValue; piece.IsSelected = false; } // Console.WriteLine("SelectedPiece.Clear {0}", piece); } public void SetPos(Vector2I pos) { piece = board.GetPiece(pos); if (allowedPieces != null && allowedPieces.Contains(piece) == false) { return; } selectedNodePos = pos; piece.IsSelected = true; Console.WriteLine("SelectedPiece.SetPos {0}", piece); } public IPiece GetPiece() { return piece; } public Vector2I GetPos() { return selectedNodePos; } public bool HasSelected() { return selectedNodePos != Vector2I.MaxValue; } } }