refactor(重构): 重构了事件驱动的代码体系,使用全新命名和版本,以及测试套件的初试
- 移除了.csproj文件 - 更新了.gitignore,添加了.editorconfig - 重构了IBoard和IPiece接口,引入了新的事件处理机制 - 优化了CCBoard、CCPiece等类的实现,使用新的事件驱动模型 - 删除了冗余代码,提高了代码的可读性和可维护性
This commit is contained in:
@ -1,32 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Vector2I = Vector.Vector2I;
|
||||
|
||||
using static IBoard;
|
||||
public abstract class AbstractBoard : IBoard {
|
||||
private readonly int rows;
|
||||
private readonly int cols;
|
||||
protected readonly IPiece?[,] pieces;
|
||||
protected readonly List<MoveRecord> moveRecords = new();
|
||||
protected readonly int MAX_RECORDS;
|
||||
public abstract class AbstractBoard(int rows, int cols, int maxRecords = int.MaxValue,
|
||||
IBoardOn? on = null) : IBoard {
|
||||
private readonly int rows = rows;
|
||||
private readonly int cols = cols;
|
||||
protected readonly IPiece?[,] pieces = new IPiece[rows, cols];
|
||||
protected readonly List<MoveRecord> moveRecords = [];
|
||||
protected readonly int MAX_RECORDS = maxRecords;
|
||||
|
||||
public int Rows => rows;
|
||||
public int Cols => cols;
|
||||
protected IBoardOn? on = on;
|
||||
|
||||
public event EventHandler<SetPieceEventArgs>? OnSetPiece;
|
||||
public event EventHandler<IPiece>? OnInsert;
|
||||
public event EventHandler<IPiece>? OnRemove;
|
||||
public event EventHandler<MoveEventArgs>? OnMove;
|
||||
|
||||
public event EventHandler<MoveRecord>? OnAddRecord;
|
||||
public event EventHandler<MoveRecord>? OnUndoRecord;
|
||||
|
||||
public AbstractBoard(int rows, int cols, int maxRecords = int.MaxValue) {
|
||||
this.rows = rows;
|
||||
this.cols = cols;
|
||||
pieces = new IPiece[rows, cols];
|
||||
MAX_RECORDS = maxRecords;
|
||||
}
|
||||
public virtual IBoardOn? On { get => on; set => on = value; }
|
||||
|
||||
public virtual bool IsPosOutOfRange(Vector2I arrayPos) {
|
||||
return arrayPos.X < 0 || arrayPos.X >= Rows || arrayPos.Y < 0 || arrayPos.Y >= Cols;
|
||||
@ -42,19 +30,20 @@ public abstract class AbstractBoard : IBoard {
|
||||
|
||||
IPiece? oldPiece = pieces[pos.X, pos.Y];
|
||||
pieces[pos.X, pos.Y] = piece;
|
||||
if (piece != null) piece.Pos = pos;
|
||||
if (piece is not null) piece.Pos = pos;
|
||||
// if (oldPiece != null) oldPiece.Pos = Vector2I.Zero;
|
||||
|
||||
OnSetPiece?.Invoke(this, new SetPieceEventArgs { OldPiece = oldPiece, NewPiece = piece, Pos = pos });
|
||||
on?.OnSetPieceInteral(this, new IBoardOn.SetPieceEventArgs
|
||||
(oldPiece, piece, pos));
|
||||
return oldPiece;
|
||||
}
|
||||
|
||||
public virtual bool InsertPiece(IPiece piece, Vector2I pos) {
|
||||
if (GetPiece(pos) != null && piece == null) {
|
||||
if (GetPiece(pos) is not null && piece == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OnInsert?.Invoke(this, piece);
|
||||
on?.OnInsert(this, piece);
|
||||
SetPiece(piece, pos);
|
||||
return true;
|
||||
}
|
||||
@ -65,11 +54,11 @@ public abstract class AbstractBoard : IBoard {
|
||||
}
|
||||
|
||||
IPiece? piece = GetPiece(from);
|
||||
if (GetPiece(to) != null || piece == null) {
|
||||
if (GetPiece(to) is not null || piece is null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OnMove?.Invoke(this, new MoveEventArgs { From = from, To = to, Piece = piece });
|
||||
on?.OnMove(this, new IBoardOn.MoveEventArgs(piece, from, to));
|
||||
SetPiece(null, from);
|
||||
SetPiece(piece, to);
|
||||
return true;
|
||||
@ -77,8 +66,9 @@ public abstract class AbstractBoard : IBoard {
|
||||
|
||||
public virtual IPiece? RemovePiece(Vector2I pos) {
|
||||
IPiece? piece = GetPiece(pos);
|
||||
if (piece == null) return null;
|
||||
OnRemove?.Invoke(this, piece);
|
||||
if (piece is null) return null;
|
||||
|
||||
on?.OnRemove(this, piece);
|
||||
return SetPiece(null, pos);
|
||||
}
|
||||
|
||||
@ -103,7 +93,7 @@ public abstract class AbstractBoard : IBoard {
|
||||
}
|
||||
MoveRecord record = new(From, To, FromPos, ToPos);
|
||||
|
||||
OnAddRecord?.Invoke(this, record);
|
||||
on?.OnAddRecord(this, record);
|
||||
moveRecords.Add(record);
|
||||
}
|
||||
|
||||
@ -113,29 +103,15 @@ public abstract class AbstractBoard : IBoard {
|
||||
moveRecords.RemoveAt(moveRecords.Count - 1);
|
||||
|
||||
// 恢复新位置的棋子,order is very inmportant
|
||||
if (record.From != null) {
|
||||
if (record.From is not null) {
|
||||
MovePiece(record.ToPos, record.FromPos);
|
||||
}
|
||||
|
||||
// 恢复旧位置的棋子
|
||||
if (record.To != null) {
|
||||
if (record.To is not null) {
|
||||
InsertPiece(record.To, record.ToPos);
|
||||
}
|
||||
|
||||
OnUndoRecord?.Invoke(this, record);
|
||||
}
|
||||
|
||||
public class MoveRecord {
|
||||
public IPiece? From { get; }
|
||||
public IPiece? To { get; }
|
||||
public Vector2I FromPos { get; }
|
||||
public Vector2I ToPos { get; }
|
||||
|
||||
public MoveRecord(IPiece? From, IPiece? To, Vector2I FromPos, Vector2I ToPos) {
|
||||
this.From = From;
|
||||
this.To = To;
|
||||
this.ToPos = ToPos;
|
||||
this.FromPos = FromPos;
|
||||
}
|
||||
on?.OnUndoRecord(this, record);
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Vector2I = Vector.Vector2I;
|
||||
|
||||
public abstract class AbstractPiece : IPiece {
|
||||
private Vector2I pos; // 注意这个坐标的非像素坐标而是棋盘坐标
|
||||
using static IPiece;
|
||||
public abstract class AbstractPiece(string name = "", Vector2I? pos = null,
|
||||
IPieceOn? on = null) : IPiece {
|
||||
private Vector2I pos = pos ?? new(); // 注意这个坐标的非像素坐标而是棋盘坐标
|
||||
private bool isSelected = false;
|
||||
protected string name;
|
||||
private Dictionary<string, object> data = new();
|
||||
protected string name = name;
|
||||
private Dictionary<string, object> data = [];
|
||||
protected IPieceOn? on = on;
|
||||
|
||||
public Vector2I Pos {
|
||||
public virtual IPieceOn? On { get => on; set => on = value; }
|
||||
|
||||
public virtual Vector2I Pos {
|
||||
get => pos;
|
||||
set {
|
||||
if (pos != value) {
|
||||
var oldPos = pos;
|
||||
pos = value;
|
||||
OnPos?.Invoke(this, oldPos);
|
||||
on?.OnPos(this, oldPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSelected {
|
||||
public virtual bool IsSelected {
|
||||
get => isSelected;
|
||||
set {
|
||||
if (isSelected != value) {
|
||||
var oldIsSelected = isSelected;
|
||||
isSelected = value;
|
||||
OnSelected?.Invoke(this, oldIsSelected);
|
||||
on?.OnSelected(this, oldIsSelected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Name {
|
||||
public virtual string Name {
|
||||
get => name;
|
||||
set {
|
||||
if (name != value) {
|
||||
var oldName = name;
|
||||
name = value;
|
||||
OnName?.Invoke(this, oldName);
|
||||
on?.OnName(this, oldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, object> Data {
|
||||
public virtual Dictionary<string, object> Data {
|
||||
get => data;
|
||||
set => data = value;
|
||||
}
|
||||
|
||||
public event EventHandler<Vector2I>? OnPos;
|
||||
public event EventHandler<Vector2I>? OnMove;
|
||||
public event EventHandler<bool>? OnSelected;
|
||||
public event EventHandler<string>? OnName;
|
||||
|
||||
public virtual bool Move(Vector2I pos) {
|
||||
if (!CanMove(pos)) {
|
||||
return false;
|
||||
}
|
||||
Pos = pos;
|
||||
OnMove?.Invoke(this, pos);
|
||||
on?.OnMove(this, pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -65,9 +64,4 @@ public abstract class AbstractPiece : IPiece {
|
||||
public override string ToString() {
|
||||
return $"{Name} at {pos}";
|
||||
}
|
||||
|
||||
public AbstractPiece(string name = "", Vector2I? pos = null) {
|
||||
this.name = name;
|
||||
this.pos = pos ?? new();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -1,32 +1,33 @@
|
||||
using System;
|
||||
using Godot;
|
||||
using Vector2I = Vector.Vector2I;
|
||||
|
||||
|
||||
public interface IBoard {
|
||||
public interface IBoardOn {
|
||||
void OnInsert(object self, IPiece piece) {}
|
||||
void OnRemove(object self, IPiece piece) {}
|
||||
void OnMove(object self, MoveEventArgs args) {}
|
||||
|
||||
void OnAddRecord(object self, MoveRecord record) {}
|
||||
void OnUndoRecord(object self, MoveRecord record) {}
|
||||
void OnSetPieceInteral(object self, SetPieceEventArgs args) {}
|
||||
record SetPieceEventArgs(IPiece? OldPiece, IPiece? NewPiece, Vector2I Pos);
|
||||
record MoveEventArgs(IPiece? Piece, Vector2I From, Vector2I To);
|
||||
}
|
||||
|
||||
public IBoardOn? On { get; protected set; }
|
||||
public int Rows { get; }
|
||||
public int Cols { get; }
|
||||
|
||||
public class SetPieceEventArgs : EventArgs {
|
||||
public IPiece? OldPiece { get; set; }
|
||||
public IPiece? NewPiece { get; set; }
|
||||
public Vector2I Pos { get; set; } = new();
|
||||
}
|
||||
|
||||
public class MoveEventArgs : EventArgs {
|
||||
public IPiece? Piece { get; set; }
|
||||
public Vector2I From { get; set; } = new();
|
||||
public Vector2I To { get; set; } = new();
|
||||
}
|
||||
|
||||
event EventHandler<IPiece> OnInsert;
|
||||
event EventHandler<IPiece> OnRemove;
|
||||
event EventHandler<MoveEventArgs> OnMove;
|
||||
event EventHandler<SetPieceEventArgs> OnSetPiece;
|
||||
|
||||
bool IsPosOutOfRange(Vector2I pos);
|
||||
IPiece? GetPiece(Vector2I pos);
|
||||
IPiece? SetPiece(IPiece piece, Vector2I pos);
|
||||
IPiece? SetPiece(IPiece? piece, Vector2I pos);
|
||||
bool InsertPiece(IPiece piece, Vector2I pos);
|
||||
bool MovePiece(Vector2I from, Vector2I to);
|
||||
IPiece? RemovePiece(Vector2I pos);
|
||||
void Clear();
|
||||
void Clear(bool clearRecords);
|
||||
void AddRecord(IPiece? From, IPiece? To, Vector2I FromPos, Vector2I ToPos);
|
||||
void UndoRecord();
|
||||
record MoveRecord(IPiece? From, IPiece? To, Vector2I FromPos, Vector2I ToPos);
|
||||
}
|
||||
|
@ -2,17 +2,21 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Vector2I = Vector.Vector2I;
|
||||
|
||||
|
||||
public interface IPiece {
|
||||
public interface IPieceOn {
|
||||
void OnPos(object self, Vector2I oldPos) {}
|
||||
void OnMove(object self, Vector2I oldPos) {}
|
||||
void OnSelected(object self, bool oldIsSelected) {}
|
||||
void OnName(object self, string oldName) {}
|
||||
}
|
||||
|
||||
IPieceOn? On { get; protected set; }
|
||||
Vector2I Pos { get; set; }
|
||||
string Name { get; set; }
|
||||
bool IsSelected { get; set; }
|
||||
Dictionary<string, object> Data { get; set; }
|
||||
|
||||
event EventHandler<Vector2I> OnPos;
|
||||
event EventHandler<Vector2I> OnMove;
|
||||
event EventHandler<bool> OnSelected;
|
||||
event EventHandler<string> OnName;
|
||||
|
||||
bool CanMove(Vector2I to);
|
||||
bool Move(Vector2I pos);
|
||||
}
|
||||
|
Reference in New Issue
Block a user