81 lines
2.8 KiB
C#
81 lines
2.8 KiB
C#
|
|
namespace Shogi.Domain.Other;
|
|
|
|
/// <summary>
|
|
/// </summary>
|
|
/// <typeparam name="TPiece"></typeparam>
|
|
/// <param name="boardState">A 2D array of pieces, representing your board. Indexed as [x, y].</param>
|
|
public class BoardRules<TPiece>(TPiece?[,] boardState) where TPiece : IRulesLifecycle<TPiece>
|
|
{
|
|
private readonly Vector2 MaxIndex = new(boardState.GetLength(0) - 1, boardState.GetLength(1) - 1);
|
|
|
|
/// <summary>
|
|
/// Validates a move, invoking the <see cref="IRulesLifecycle{TPiece}.OnMoveValidation(MoveValidationContext{TPiece})"/> callback which you should implement.
|
|
/// A move is considered valid if it could be made legally, ignoring check or check-mate rules.
|
|
/// Check and check-mate verifying happens in a different lifecycle callback.
|
|
/// </summary>
|
|
/// <param name="from">The position of the piece being moved.</param>
|
|
/// <param name="to">The desired destination of the piece being moved.</param>
|
|
/// <param name="isPromotion">TODO</param>
|
|
/// <returns></returns>
|
|
public RulesLifecycleResult ValidateMove(Vector2 from, Vector2 to, bool isPromotion)
|
|
{
|
|
if (IsWithinBounds(from) && IsWithinBounds(to))
|
|
{
|
|
var piece = boardState[(int)from.X, (int)from.Y];
|
|
if (piece == null)
|
|
{
|
|
return new RulesLifecycleResult(IsError: true, $"There is no piece at position {from}.");
|
|
}
|
|
|
|
return piece.OnMoveValidation(new MoveValidationContext<TPiece>(from, to, isPromotion, boardState));
|
|
}
|
|
|
|
return new RulesLifecycleResult(IsError: true, "test message");
|
|
}
|
|
|
|
|
|
//foreach (var piece in boardState)
|
|
//{
|
|
// if (piece != null)
|
|
// {
|
|
// var result = piece.OnMoveValidation(new MoveValidationContext<TPiece>(from, to, isPromotion, boardState));
|
|
// if (result.IsError)
|
|
// {
|
|
// return result;
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
//public int ValidateMove(Vector2 start, Vector2 end)
|
|
//{
|
|
// if (board.GetLength(0) != boardSize.X || board.GetLength(1) != boardSize.Y)
|
|
// {
|
|
// throw new ArgumentException($"2D array dimensions must match boardSize given during {nameof(CreateNewRules)} method.", nameof(board));
|
|
// }
|
|
// if (start - start != Vector2.Zero)
|
|
// {
|
|
// throw new ArgumentException("Negative values not allowed.", nameof(start));
|
|
// }
|
|
// if (end - end != Vector2.Zero)
|
|
// {
|
|
// throw new ArgumentException("Negative values not allowed.", nameof(end));
|
|
// }
|
|
// if (start.X >= boardSize.X || start.Y >= boardSize.Y)
|
|
// {
|
|
// throw new ArgumentException("Start position must be within the given boardSize.", nameof(start));
|
|
// }
|
|
// if (end.X >= boardSize.X || end.Y >= boardSize.Y)
|
|
// {
|
|
// throw new ArgumentException("End position must be within the given boardSize.", nameof(end));
|
|
// }
|
|
|
|
// return 0;
|
|
//}
|
|
|
|
private bool IsWithinBounds(Vector2 position)
|
|
{
|
|
var isPositive = position - position == Vector2.Zero;
|
|
return isPositive && position.X <= MaxIndex.X && position.Y <= MaxIndex.Y;
|
|
}
|
|
} |