feat(重构): 重构棋盘和棋子的逻辑
- 重构了 ChessBoard 和 ChessPiece 类的逻辑 - 添加了新版本的 ChineseChess 库 - 删除了旧版本的 VirtualBoard 和 VirtualPiece 类 - 更新了相关的场景和脚本
This commit is contained in:
117
Scripts/Src/ChineseChess/CCPlayer.cs
Normal file
117
Scripts/Src/ChineseChess/CCPlayer.cs
Normal file
@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Vector2I = Vector.Vector2I;
|
||||
|
||||
namespace ChineseChess;
|
||||
public class Player {
|
||||
private readonly CCBoard board;
|
||||
private readonly SelectedPiece selectedNode;
|
||||
|
||||
public EventHandler<IBoard.MoveEventArgs> 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;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user