refactor(重构): 重构了事件驱动的代码体系,使用全新命名和版本,以及测试套件的初试
- 移除了.csproj文件 - 更新了.gitignore,添加了.editorconfig - 重构了IBoard和IPiece接口,引入了新的事件处理机制 - 优化了CCBoard、CCPiece等类的实现,使用新的事件驱动模型 - 删除了冗余代码,提高了代码的可读性和可维护性
This commit is contained in:
@ -1,24 +1,29 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using static ChineseChess.ChessCore;
|
||||
using Vector2I = Vector.Vector2I;
|
||||
|
||||
namespace ChineseChess;
|
||||
public class CCBoard : AbstractBoard
|
||||
{
|
||||
public event EventHandler<int>? OnStepsChanged;
|
||||
public interface ICCBoardOn : IBoard.IBoardOn {
|
||||
void OnSteps(object self, int oldSteps) {}
|
||||
}
|
||||
|
||||
public class CCBoard(ICCBoardOn? on = null) : AbstractBoard(9, 10, on: on) {
|
||||
private int steps = 0;
|
||||
protected new ICCBoardOn? on = on;
|
||||
// public virtual IPieceOn? On { get => on; set => on = value; }
|
||||
public new ICCBoardOn? On { get => on; set {
|
||||
on = value; base.on = value;} }
|
||||
|
||||
public int Steps {
|
||||
get => steps;
|
||||
protected set {
|
||||
if (steps != value) {
|
||||
var oldSteps = steps;
|
||||
steps = value;
|
||||
OnStepsChanged?.Invoke(this, steps);
|
||||
on?.OnSteps(this, oldSteps);
|
||||
}
|
||||
}
|
||||
}
|
||||
public CCBoard() : base(9, 10) {
|
||||
}
|
||||
|
||||
public override void AddRecord(IPiece? From, IPiece? To, Vector2I FromPos, Vector2I ToPos) {
|
||||
base.AddRecord(From, To, FromPos, ToPos);
|
||||
@ -32,65 +37,49 @@ public class CCBoard : AbstractBoard
|
||||
|
||||
public (ArrayList, ArrayList) InitGame() {
|
||||
Steps = 0;
|
||||
// ArrayList blackPart = InitOnePartPieces(TurnsSideType.Black, new[] {
|
||||
// new CCChariot(TurnsSideType.Black, "black chariot 0", 0, 0),
|
||||
// ("车", 0, 0), ("马", 1, 0), ("象", 2, 0),
|
||||
// ("士", 3, 0), ("将", 4, 0), ("士", 5, 0),
|
||||
// ("象", 6, 0), ("马", 7, 0), ("车", 8, 0),
|
||||
// ("炮", 1, 2), ("炮", 7, 2),
|
||||
// ("卒", 0, 3), ("卒", 2, 3), ("卒", 4, 3), ("卒", 6, 3), ("卒", 8, 3)
|
||||
// });
|
||||
ArrayList blackPart = InitOnePartPieces(TurnsSideType.Black, [
|
||||
new CCChariot (this, TurnsSideType.Black, new Vector2I( 4, 0)),
|
||||
new CCHorse (this, TurnsSideType.Black, new Vector2I( 3, 0)),
|
||||
new CCElephant(this, TurnsSideType.Black, new Vector2I( 2, 0)),
|
||||
new CCAdvisor (this, TurnsSideType.Black, new Vector2I( 1, 0)),
|
||||
new CCGeneral (this, TurnsSideType.Black, new Vector2I( 0, 0)),
|
||||
new CCAdvisor (this, TurnsSideType.Black, new Vector2I(-1, 0)),
|
||||
new CCElephant(this, TurnsSideType.Black, new Vector2I(-2, 0)),
|
||||
new CCHorse (this, TurnsSideType.Black, new Vector2I(-3, 0)),
|
||||
new CCChariot (this, TurnsSideType.Black, new Vector2I(-4, 0)),
|
||||
new CCCannon (this, TurnsSideType.Black, new Vector2I( 3, 2)),
|
||||
new CCCannon (this, TurnsSideType.Black, new Vector2I(-3, 2)),
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I(-4, 3)),
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I(-2, 3)),
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I( 0, 3)),
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I( 2, 3)),
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I( 4, 3)),
|
||||
]);
|
||||
|
||||
// ArrayList redPart = InitOnePartPieces(TurnsSideType.Red, new[] {
|
||||
// ("车", 0, -0), ("马", 1, -0), ("象", 2, -0),
|
||||
// ("士", 3, -0), ("将", 4, -0), ("士", 5, -0),
|
||||
// ("象", 6, -0), ("马", 7, -0), ("车", 8, -0),
|
||||
// ("炮", 1, -2), ("炮", 7, -2),
|
||||
// ("卒", 0, -3), ("卒", 2, -3), ("卒", 4, -3), ("卒", 6, -3), ("卒", 8, -3)
|
||||
// });
|
||||
ArrayList blackPart = InitOnePartPieces(TurnsSideType.Black, new CCPiece[] {
|
||||
new CCChariot (this, TurnsSideType.Black, new Vector2I( 4, 0)), // 4,0
|
||||
new CCHorse (this, TurnsSideType.Black, new Vector2I( 3, 0)), // 3,0
|
||||
new CCElephant(this, TurnsSideType.Black, new Vector2I( 2, 0)), // 2,0
|
||||
new CCAdvisor (this, TurnsSideType.Black, new Vector2I( 1, 0)), // 1,0
|
||||
new CCGeneral (this, TurnsSideType.Black, new Vector2I( 0, 0)), // 0,0
|
||||
new CCAdvisor (this, TurnsSideType.Black, new Vector2I(-1, 0)), // -1,0
|
||||
new CCElephant(this, TurnsSideType.Black, new Vector2I(-2, 0)), // -2,0
|
||||
new CCHorse (this, TurnsSideType.Black, new Vector2I(-3, 0)), // -3,0
|
||||
new CCChariot (this, TurnsSideType.Black, new Vector2I(-4, 0)), // -4,0
|
||||
new CCCannon (this, TurnsSideType.Black, new Vector2I( 3, 2)), // 3,2
|
||||
new CCCannon (this, TurnsSideType.Black, new Vector2I(-3, 2)), // -3,2
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I(-4, 3)), // -4,3
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I(-2, 3)), // -2,3
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I( 0, 3)), // 0,3
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I( 2, 3)), // -4,3
|
||||
new CCPawn (this, TurnsSideType.Black, new Vector2I( 4, 3)) // 4,3
|
||||
});
|
||||
|
||||
ArrayList redPart = InitOnePartPieces(TurnsSideType.Red, new CCPiece[] {
|
||||
new CCChariot (this, TurnsSideType.Red, new Vector2I( 4, 0)), // 4,0
|
||||
new CCHorse (this, TurnsSideType.Red, new Vector2I( 3, 0)), // 3,0
|
||||
new CCElephant(this, TurnsSideType.Red, new Vector2I( 2, 0)), // 2,0
|
||||
new CCAdvisor (this, TurnsSideType.Red, new Vector2I( 1, 0)), // 1,0
|
||||
new CCGeneral (this, TurnsSideType.Red, new Vector2I( 0, 0)), // 0,0
|
||||
new CCAdvisor (this, TurnsSideType.Red, new Vector2I(-1, 0)), // -1,0
|
||||
new CCElephant(this, TurnsSideType.Red, new Vector2I(-2, 0)), // -2,0
|
||||
new CCHorse (this, TurnsSideType.Red, new Vector2I(-3, 0)), // -3,0
|
||||
new CCChariot (this, TurnsSideType.Red, new Vector2I(-4, 0)), // -4,0
|
||||
new CCCannon (this, TurnsSideType.Red, new Vector2I( 3, 2)), // 3,2
|
||||
new CCCannon (this, TurnsSideType.Red, new Vector2I(-3, 2)), // -3,2
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I(-4, 3)), // -4,3
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I(-2, 3)), // -2,3
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I( 0, 3)), // 0,3
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I( 2, 3)), // 2,3
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I( 4, 3)) // 4,3
|
||||
});
|
||||
ArrayList redPart = InitOnePartPieces(TurnsSideType.Red, [
|
||||
new CCChariot (this, TurnsSideType.Red, new Vector2I( 4, 0)),
|
||||
new CCHorse (this, TurnsSideType.Red, new Vector2I( 3, 0)),
|
||||
new CCElephant(this, TurnsSideType.Red, new Vector2I( 2, 0)),
|
||||
new CCAdvisor (this, TurnsSideType.Red, new Vector2I( 1, 0)),
|
||||
new CCGeneral (this, TurnsSideType.Red, new Vector2I( 0, 0)),
|
||||
new CCAdvisor (this, TurnsSideType.Red, new Vector2I(-1, 0)),
|
||||
new CCElephant(this, TurnsSideType.Red, new Vector2I(-2, 0)),
|
||||
new CCHorse (this, TurnsSideType.Red, new Vector2I(-3, 0)),
|
||||
new CCChariot (this, TurnsSideType.Red, new Vector2I(-4, 0)),
|
||||
new CCCannon (this, TurnsSideType.Red, new Vector2I( 3, 2)),
|
||||
new CCCannon (this, TurnsSideType.Red, new Vector2I(-3, 2)),
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I(-4, 3)),
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I(-2, 3)),
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I( 0, 3)),
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I( 2, 3)),
|
||||
new CCPawn (this, TurnsSideType.Red, new Vector2I( 4, 3)),
|
||||
]);
|
||||
|
||||
return (blackPart, redPart);
|
||||
}
|
||||
|
||||
private ArrayList InitOnePartPieces(TurnsSideType side, CCPiece[] pieces) {
|
||||
ArrayList list = new();
|
||||
ArrayList list = [];
|
||||
foreach (var piece in pieces) {
|
||||
list.Add(piece);
|
||||
InsertPiece(piece, piece.Pos);
|
||||
|
@ -1,6 +1,8 @@
|
||||
using Vector2 = Vector.Vector2I;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using static IBoard.IBoardOn;
|
||||
|
||||
namespace ChineseChess;
|
||||
|
||||
public class ChessCore {
|
||||
@ -23,17 +25,18 @@ public class ChessCore {
|
||||
|
||||
private TurnsSideType sideType = TurnsSideType.Red;
|
||||
private readonly TurnsSideType selfSide;
|
||||
public readonly CCBoard board = new();
|
||||
public readonly CCBoard board;
|
||||
private readonly Player playerSelf;
|
||||
private readonly Player playerOpponent;
|
||||
// public EventHandler<IBoard.MoveEventArgs> OnMove;
|
||||
public ChessCore(Mode mode, TurnsSideType selfSide) {
|
||||
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, IBoard.MoveEventArgs record) {
|
||||
void func(object? _self, MoveEventArgs record) {
|
||||
// 防止 Undo 时 Selected Clear 出现 Null Pointer Exception
|
||||
playerSelf.SelectedClear();
|
||||
playerOpponent.SelectedClear();
|
||||
|
@ -1,6 +1,5 @@
|
||||
namespace ChineseChess;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Vector;
|
||||
@ -20,11 +19,14 @@ public class CCPiece : AbstractPiece {
|
||||
string name = "", Vector2I? pos = null) : base(name) {
|
||||
this.board = board ?? new();
|
||||
TurnsSide = turnsSide;
|
||||
OnPos += (sender, args) => {
|
||||
localPos = Global2Local(Pos);
|
||||
};
|
||||
Pos = pos is not null ? Local2Global(pos) : Vector2I.Zero;
|
||||
localPos = Global2Local(Pos);
|
||||
}
|
||||
|
||||
public override Vector2I Pos {
|
||||
get => base.Pos; set {
|
||||
base.Pos = value;
|
||||
localPos = Global2Local(Pos);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanMove(Vector2I to) {
|
||||
@ -44,18 +46,18 @@ public class CCPiece : AbstractPiece {
|
||||
}
|
||||
|
||||
public virtual List<Vector2I> CanMoveAllPosSelf() {
|
||||
return new List<Vector2I>();
|
||||
return [];
|
||||
}
|
||||
|
||||
public IEnumerable<Vector2I> CanMoveAllPosLocal() {
|
||||
var self = CanMoveAllPosSelf().Select(item => item + localPos);// 转换局部坐标
|
||||
var self = CanMoveAllPosSelf().Select(item => item + localPos);
|
||||
var ret = self.Where(item => {
|
||||
CCPiece? piece = GetCCPieceLocal(item);
|
||||
bool ret = piece is null || piece.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));
|
||||
@ -64,7 +66,7 @@ public class CCPiece : AbstractPiece {
|
||||
|
||||
public IEnumerable<Vector2I> CanMoveAllPos() {
|
||||
var ret = CanMoveAllPosLocal()
|
||||
.Select(item => Local2Global(item)); // 转换为全局坐标
|
||||
.Select(item => Local2Global(item));
|
||||
// Console.WriteLine("CanMoveAllPos: {0}", string.Join(",", ret));
|
||||
return ret;
|
||||
}
|
||||
|
@ -3,11 +3,12 @@ using System.Collections;
|
||||
using Vector2I = Vector.Vector2I;
|
||||
|
||||
namespace ChineseChess;
|
||||
using static IBoard.IBoardOn;
|
||||
public class Player {
|
||||
private readonly CCBoard board;
|
||||
private readonly SelectedPiece selectedNode;
|
||||
|
||||
public EventHandler<IBoard.MoveEventArgs>? OnMove;
|
||||
public EventHandler<MoveEventArgs>? OnMove;
|
||||
public bool CanMove { get; set; } = true;
|
||||
|
||||
public enum PlayerType {
|
||||
@ -15,8 +16,7 @@ public class Player {
|
||||
AI
|
||||
}
|
||||
|
||||
public Player(CCBoard board, PlayerType type = PlayerType.Human)
|
||||
{
|
||||
public Player(CCBoard board, PlayerType type = PlayerType.Human) {
|
||||
this.board = board;
|
||||
this.selectedNode = new SelectedPiece(board);
|
||||
}
|
||||
@ -56,9 +56,9 @@ public class Player {
|
||||
}
|
||||
|
||||
// MUST BE THERE !!! 防止删除节点后在启动回调导致错误
|
||||
OnMove?.Invoke(this, new IBoard.MoveEventArgs
|
||||
{ From = fromPos, To = toPos, Piece = fromChess });;
|
||||
|
||||
OnMove?.Invoke(this, new MoveEventArgs
|
||||
(fromChess, fromPos, toPos));
|
||||
|
||||
if (toChess != null) {
|
||||
board.RemovePiece(toPos);
|
||||
}
|
||||
|
Reference in New Issue
Block a user