chinese_chess/Scripts/Utilities/VirtualBoard.cs
2024-11-03 21:15:33 +08:00

101 lines
2.7 KiB
C#

using System;
// using System.Numerics;
// using System.Transactions;
using Godot;
public class VirtualBoard {
private readonly int Rows;
private readonly int Cols;
private readonly VirtualPiece[,] pieces;
public class SetPiecePosEventArgs : EventArgs
{
public VirtualPiece OldPiece { get; set; }
public VirtualPiece NewPiece { get; set; }
}
public class MoveEventArgs : EventArgs
{
public Vector2 From { get; set; }
public Vector2 To { get; set; }
}
public event EventHandler<SetPiecePosEventArgs> OnSetPiecePos;
public event EventHandler<VirtualPiece> OnInsert;
public event EventHandler<VirtualPiece> OnRemove;
public event EventHandler<MoveEventArgs> OnMove;
public VirtualBoard(int rows, int cols) {
this.Rows = rows;
this.Cols = cols;
pieces = new VirtualPiece[rows, cols];
}
public bool ArrPosOutOfRange(Vector2 arrayPos) {
return arrayPos.X < 0 || arrayPos.X >= Rows || arrayPos.Y < 0 || arrayPos.Y >= Cols;
}
public VirtualPiece GetPiece(Vector2 arrayPos) {
if (ArrPosOutOfRange(arrayPos)) return null;
return pieces[(int)arrayPos.X, (int)arrayPos.Y];
}
public VirtualPiece SetPiecePos(VirtualPiece piece, Vector2 arrayPos) {
if (ArrPosOutOfRange(arrayPos)) return null;
VirtualPiece oldPiece = pieces[(int)arrayPos.X, (int)arrayPos.Y];
pieces[(int)arrayPos.X, (int)arrayPos.Y] = piece;
OnSetPiecePos?.Invoke(this, new SetPiecePosEventArgs { OldPiece = oldPiece, NewPiece = piece });
piece?.Move(arrayPos);
return oldPiece;
}
public bool InsertPiece(VirtualPiece piece, Vector2 arrayPos) {
if (GetPiece(arrayPos) != null) {
return false;
}
OnInsert?.Invoke(this, piece);
SetPiecePos(piece, arrayPos);
return true;
}
public bool MovePiece(Vector2 from, Vector2 to) {
if (ArrPosOutOfRange(to) || ArrPosOutOfRange(from)) {
return false;
}
if (GetPiece(to) != null) {
return false;
}
OnMove?.Invoke(this, new MoveEventArgs { From = from, To = to });
SetPiecePos(SetPiecePos(null, from), to);
return true;
}
public bool RemovePiece(Vector2 pos) {
VirtualPiece piece = GetPiece(pos);
if (piece == null) {
return false;
}
OnRemove?.Invoke(this, piece);
return SetPiecePos(null, pos) != null;
}
public void Clear() {
for (int i = 0; i < Rows; i++) {
for (int j = 0; j < Cols; j++) {
RemovePiece(new Vector2(i, j));
}
}
}
}