public override bool IsValidMove(Move move, ChessGame game)
{
ChessUtilities.ThrowIfNull(move, "move");
ChessUtilities.ThrowIfNull(game, "game");
Position origin = move.OriginalPosition;
Position destination = move.NewPosition;
Piece promotion = null;
if (move.Promotion.HasValue && ValidPromotionPieces.Contains(move.Promotion.Value))
{
promotion = game.MapPgnCharToPiece(char.ToUpper(move.Promotion.Value), move.Player);
}
PositionDistance posDelta = new PositionDistance(origin, destination);
if ((posDelta.DistanceX != 0 || posDelta.DistanceY != 1) && (posDelta.DistanceX != 1 || posDelta.DistanceY != 1)
&& (posDelta.DistanceX != 0 || posDelta.DistanceY != 2))
return false;
if (Owner == Player.White)
{
if (origin.Rank > destination.Rank)
return false;
if (destination.Rank == 8)
{
if (promotion == null)
return false;
if (promotion.Owner != Player.White)
return false;
if (!ValidPromotionPieces.Contains(promotion.GetFenCharacter()))
return false;
}
}
if (Owner == Player.Black)
{
if (origin.Rank < destination.Rank)
return false;
if (destination.Rank == 1)
{
if (promotion == null)
return false;
if (promotion.Owner != Player.Black)
return false;
if (!ValidPromotionPieces.Contains(promotion.GetFenCharacter()))
return false;
}
}
bool checkEnPassant = false;
if (posDelta.DistanceY == 2)
{
if ((origin.Rank != 2 && Owner == Player.White)
|| (origin.Rank != 7 && Owner == Player.Black))
return false;
if (origin.Rank == 2 && game.GetPieceAt(origin.File, 3) != null)
return false;
if (origin.Rank == 7 && game.GetPieceAt(origin.File, 6) != null)
return false;
}
Piece pieceAtDestination = game.GetPieceAt(destination);
if (posDelta.DistanceX == 0 && (posDelta.DistanceY == 1 || posDelta.DistanceY == 2))
{
if (pieceAtDestination != null)
return false;
}
else
{
if (pieceAtDestination == null)
checkEnPassant = true;
else if (pieceAtDestination.Owner == Owner)
return false;
}
if (checkEnPassant)
{
ReadOnlyCollection<DetailedMove> _moves = game.Moves;
if (_moves.Count == 0)
{
return false;
}
if ((origin.Rank != 5 && Owner == Player.White)
|| (origin.Rank != 4 && Owner == Player.Black))
return false;
Move latestMove = _moves[_moves.Count - 1];
if (latestMove.Player != ChessUtilities.GetOpponentOf(Owner))
return false;
if (!(game.GetPieceAt(latestMove.NewPosition) is Pawn))
return false;
if (game.GetPieceAt(latestMove.NewPosition).Owner == Owner)
return false;
if (Owner == Player.White)
{
if (latestMove.OriginalPosition.Rank != 7 || latestMove.NewPosition.Rank != 5)
return false;
}
else // (m.Player == Players.Black)
{
if (latestMove.OriginalPosition.Rank != 2 || latestMove.NewPosition.Rank != 4)
return false;
}
if (destination.File != latestMove.NewPosition.File)
return false;
}
return true;
}