public virtual MoveType ApplyMove(Move move, bool alreadyValidated)
{
ChessUtilities.ThrowIfNull(move, "move");
if (!alreadyValidated && !IsValidMove(move))
return MoveType.Invalid;
MoveType type = MoveType.Move;
Piece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
Piece capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank);
Piece newPiece = movingPiece;
bool isCapture = capturedPiece != null;
CastlingType castle = CastlingType.None;
if (movingPiece is Pawn)
{
_halfMoveClock = 0;
PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition);
if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition) == null)
{ // en passant
isCapture = true;
SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, null);
}
if (move.NewPosition.Rank == (move.Player == Player.White ? 8 : 1))
{
newPiece = MapPgnCharToPiece(move.Promotion.Value, move.Player);
type |= MoveType.Promotion;
}
}
else if (movingPiece is King)
{
if (movingPiece.Owner == Player.White)
CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false;
else
CanBlackCastleKingSide = CanBlackCastleQueenSide = false;
if (new PositionDistance(move.OriginalPosition, move.NewPosition).DistanceX == 2 && CastlingCanBeLegal)
{
castle = ApplyCastle(move);
type |= MoveType.Castling;
}
}
else if (movingPiece is Rook)
{
if (move.Player == Player.White)
{
if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 1)
CanWhiteCastleQueenSide = false;
else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 1)
CanWhiteCastleKingSide = false;
}
else
{
if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 8)
CanBlackCastleQueenSide = false;
else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 8)
CanBlackCastleKingSide = false;
}
}
if (isCapture)
{
type |= MoveType.Capture;
_halfMoveClock = 0;
if (move.NewPosition.File == File.A && move.NewPosition.Rank == 1)
CanWhiteCastleQueenSide = false;
else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 1)
CanWhiteCastleKingSide = false;
else if (move.NewPosition.File == File.A && move.NewPosition.Rank == 8)
CanBlackCastleQueenSide = false;
else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 8)
CanBlackCastleKingSide = false;
}
if (!isCapture && !(movingPiece is Pawn))
{
_halfMoveClock++;
if (_halfMoveClock >= 100)
{
fiftyMoves = true;
}
else
{
fiftyMoves = false;
}
}
if (move.Player == Player.Black)
{
_fullMoveNumber++;
}
SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece);
SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null);
WhoseTurn = ChessUtilities.GetOpponentOf(move.Player);
_moves.Add(new DetailedMove(move, movingPiece, isCapture, castle));
return type;
}