private static Move DetermineMove(Board board, UCIChessMove uciMove) { string from = uciMove.From; string to = uciMove.To; var fromPos = Position.Parse(from); var toPos = Position.Parse(to); var fromPiece = board[fromPos]; int fileDiff = Math.Abs((int)fromPiece.Position.File - (int)toPos.File); if (fromPiece.Type == PieceType.King && (fileDiff == 3 || fileDiff == 4)) { King king = (King)fromPiece; Rook rook; if (fileDiff == 4) { rook = (Rook)board[File.A, fromPiece.Position.Rank]; } else { rook = (Rook)board[File.H, fromPiece.Position.Rank]; } return(MoveBuilder.CreateCastleMove(king, rook)); } if (uciMove.PromotionChar != null) { string promotionChar = uciMove.PromotionChar.ToUpper(); var promotionType = (from p in (PieceType[])Enum.GetValues(typeof(PieceType)) where p.ToNotationLetter().ToUpper() == promotionChar.ToUpper() select p).First(); var promotionMoves = MoveBuilder.CreatePromotionMoves((Pawn)fromPiece, toPos, board[toPos] != null); return((from m in promotionMoves where m.Promotion.NewPieceType.Type == promotionType select m).First()); } // Check for en passant var existingPieceRank = fromPiece.Position.Rank; var isCorrectRank = fromPiece.Color == PieceColor.Black ? existingPieceRank == Rank._4 : existingPieceRank == Rank._5; try { int vertDir = fromPiece.Color == PieceColor.White ? -1 : 1; var existingPieceTo = board[toPos]; var capturedPiecePos = toPos.MoveVert(vertDir); var capturedPiece = board[capturedPiecePos]; if (capturedPiece.Color == fromPiece.Color.Opposite() && capturedPiece.MoveHistory.Count == 1) { // This is an en passant return(MoveBuilder.CreateEnPassantMove((Pawn)fromPiece, toPos, capturedPiecePos)); } } catch { } // Only other option is that this is a normal move. return(MoveBuilder.CreateNormalMove(fromPiece, toPos, board[toPos] != null)); }
private List <Move> GetEnPassantMoves(Board board) { var enPassantMoves = new List <Move>(); // Is the pawn in the right rank? if (Color == PieceColor.Black && Position.Rank != Rank._4) { return(new List <Move>()); } if (Color == PieceColor.White && Position.Rank != Rank._5) { return(new List <Move>()); } // Create a few KVP of Key = new position and value = piece to capture position var positions = new List <KeyValuePair <Position, Position> >(); if ((int)Position.File >= (int)File.B) { positions.Add( new KeyValuePair <Position, Position>( Position.MoveVert(IncrementDirection).MoveHoriz(-1), Position.MoveHoriz(-1))); } if ((int)Position.File <= (int)File.G) { positions.Add( new KeyValuePair <Position, Position>( Position.MoveVert(IncrementDirection).MoveHoriz(1), Position.MoveHoriz(1))); } foreach (var kvp in positions) { var newPos = kvp.Key; var capturePos = kvp.Value; // There has to be an enemy piece there var pieceToCapture = board[capturePos]; if (pieceToCapture == null || pieceToCapture.Color == this.Color) { continue; } // The piece must have made a pawn advances 2 move. if (pieceToCapture.MoveHistory == null || pieceToCapture.MoveHistory.Count != 1) { continue; } // The move must be the most recently played move in the game. var pieceToCaptureLastMove = pieceToCapture.MoveHistory.Last(); if (pieceToCaptureLastMove != board.LastMove) { continue; } // We have a candidate for en passant! enPassantMoves.Add(MoveBuilder.CreateEnPassantMove(this, newPos, capturePos)); } return(enPassantMoves); }