private void FindPawnMoves( List <Move> moves, ThreatMatrix threats, Player player, BoardLocation playerPieceLocation, ThreatDirection?playerPieceThreatDirection) { var opposingPlayer = player.OpposingPlayer(); var marchDirection = player == Player.White ? Direction.North : Direction.South; var gradeAttackDirection = player == Player.White ? Direction.NorthEast : Direction.SouthWest; var slopeAttackDirection = player == Player.White ? Direction.NorthWest : Direction.SouthEast; //check to see if we can move up/down //note that any diagonal or horizontal threats will block these moves if ((playerPieceThreatDirection.HasThreats(ThreatDirection.Horizontal | ThreatDirection.Diagonal) == false) && (_board.NeighboringLocationIsEmpty(playerPieceLocation, marchDirection))) { var firstMarchLocation = playerPieceLocation.Neighbor(marchDirection).Value; var row = firstMarchLocation.Row(); if (row == 0 || row == 7)//we can assume this is a pawn promotion { moves.Add(new Move(playerPieceLocation, firstMarchLocation, SpecialMoveType.PawnPromotionKnight)); moves.Add(new Move(playerPieceLocation, firstMarchLocation, SpecialMoveType.PawnPromotionBishop)); moves.Add(new Move(playerPieceLocation, firstMarchLocation, SpecialMoveType.PawnPromotionRook)); moves.Add(new Move(playerPieceLocation, firstMarchLocation, SpecialMoveType.PawnPromotionQueen)); } else { moves.Add(new Move(playerPieceLocation, firstMarchLocation)); } //we can also move up two spaces if the next northern square is empty if ((playerPieceLocation.IsPawnStartingLocation(player)) && (_board.NeighboringLocationIsEmpty(firstMarchLocation, marchDirection))) { moves.Add(new Move(playerPieceLocation, firstMarchLocation.Neighbor(marchDirection).Value)); } } //check to see if we can move along the grade //note that any line or slope threats will block this move if (playerPieceThreatDirection.HasThreats(ThreatDirection.Line | ThreatDirection.Slope) == false) { //if we have an opposing piece in the next square, make hte move if (_board.NeighboringLocationIsOccupiedBy(playerPieceLocation, gradeAttackDirection, opposingPlayer)) { var neighbor = playerPieceLocation.Neighbor(gradeAttackDirection).Value; var row = neighbor.Row(); //capture pawn promotion if (row == 0 || row == 7) { moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor], SpecialMoveType.PawnPromotionKnight)); moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor], SpecialMoveType.PawnPromotionBishop)); moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor], SpecialMoveType.PawnPromotionRook)); moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor], SpecialMoveType.PawnPromotionQueen)); } else//normal capture { moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor])); } } else if (LastMoveAllowsEnPassantFor(playerPieceLocation, gradeAttackDirection)) {//we can do an en passant. var neighbor = playerPieceLocation.Neighbor(gradeAttackDirection).Value; moves.Add(new Move(playerPieceLocation, neighbor, CurrentPlayer == Player.White ? ChessPiece.BlackPawn : ChessPiece.WhitePawn, SpecialMoveType.AuPassant)); } } //check to see if we can move along the slope //note that any line or grade threats will block this move if (playerPieceThreatDirection.HasThreats(ThreatDirection.Line | ThreatDirection.Grade) == false) { //if we have an opposing piece in the next square, make hte move if (_board.NeighboringLocationIsOccupiedBy(playerPieceLocation, slopeAttackDirection, opposingPlayer)) { var neighbor = playerPieceLocation.Neighbor(slopeAttackDirection).Value; var row = neighbor.Row(); //capture pawn promotion if (row == 0 || row == 7) { moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor], SpecialMoveType.PawnPromotionKnight)); moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor], SpecialMoveType.PawnPromotionBishop)); moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor], SpecialMoveType.PawnPromotionRook)); moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor], SpecialMoveType.PawnPromotionQueen)); } else//normal capture { moves.Add(new Move(playerPieceLocation, neighbor, _board[neighbor])); } } else if (LastMoveAllowsEnPassantFor(playerPieceLocation, slopeAttackDirection)) {//we can do an en passant. var neighbor = playerPieceLocation.Neighbor(slopeAttackDirection).Value; moves.Add(new Move(playerPieceLocation, neighbor, CurrentPlayer == Player.White ? ChessPiece.BlackPawn : ChessPiece.WhitePawn, SpecialMoveType.AuPassant)); } } }