Problem

You are presented with an 8 by 8 matrix representing the positions of pieces on a chess board. The only pieces on the board are the black king and various white pieces. Given this matrix, determine whether the king is in check.

A king is in check when it is under attack by one or more enemy pieces. Each chess piece has specific movement patterns:

  • Queen (Q): Moves any number of squares horizontally, vertically, or diagonally
  • Rook (R): Moves any number of squares horizontally or vertically
  • Bishop (B): Moves any number of squares diagonally
  • Knight (N): Moves in an L-shape (2 squares in one direction, 1 square perpendicular)
  • Pawn (P): Attacks diagonally forward (one square diagonally up for white pieces)

Examples

Example 1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Input: board = [
  "...K....",
  "........",
  ".B......",
  "......P.",
  ".......R",
  "..N.....",
  "........",
  ".....Q.."
]
Output: true
Explanation: The bishop at position (2,1) is attacking the king at (0,3) diagonally.

Example 2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Input: board = [
  "........",
  "........",
  "........",
  "...K....",
  "........",
  "........",
  "........",
  "........"
]
Output: false
Explanation: The king is alone on the board with no attacking pieces.

Example 3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Input: board = [
  "........",
  "........",
  "........",
  "...KR...",
  "........",
  "........",
  "........",
  "........"
]
Output: true
Explanation: The rook at position (3,4) is attacking the king at (3,3) horizontally.

Example 4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Input: board = [
  "........",
  "........",
  "..N.....",
  "........",
  "....K...",
  "........",
  "........",
  "........"
]
Output: true
Explanation: The knight at position (2,2) is attacking the king at (4,4) with an L-shaped move.

Similar Problems

Queens That Can Attack the King

Solution

Method 1 - Direct Attack Pattern Validation

Intuition

To determine if a king is in check, we need to find the king’s position and then check if any white piece can attack that position using their specific movement patterns. Each piece type has distinct attack patterns that we can validate by checking all possible directions and distances.

Approach

  1. Find the king’s position on the board
  2. For each white piece on the board, determine if it can attack the king’s position:
    • Queen: Check all 8 directions (horizontal, vertical, diagonal)
    • Rook: Check 4 directions (horizontal, vertical)
    • Bishop: Check 4 diagonal directions
    • Knight: Check all 8 L-shaped positions
    • Pawn: Check 2 diagonal forward positions
  3. For sliding pieces (Queen, Rook, Bishop), ensure no other pieces block the attack path
  4. Return true if any piece can attack the king

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class Solution {
public:
    bool isKingInCheck(vector<string>& board) {
        int kingRow = -1, kingCol = -1;
        
        // Find king position
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (board[i][j] == 'K') {
                    kingRow = i;
                    kingCol = j;
                    break;
                }
            }
            if (kingRow != -1) break;
        }
        
        // Check if any white piece attacks the king
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                char piece = board[i][j];
                if (piece != '.' && piece != 'K') {
                    if (canAttack(board, i, j, kingRow, kingCol, piece)) {
                        return true;
                    }
                }
            }
        }
        
        return false;
    }
    
private:
    bool canAttack(vector<string>& board, int pieceRow, int pieceCol, 
                   int kingRow, int kingCol, char piece) {
        switch (piece) {
            case 'Q': return canQueenAttack(board, pieceRow, pieceCol, kingRow, kingCol);
            case 'R': return canRookAttack(board, pieceRow, pieceCol, kingRow, kingCol);
            case 'B': return canBishopAttack(board, pieceRow, pieceCol, kingRow, kingCol);
            case 'N': return canKnightAttack(pieceRow, pieceCol, kingRow, kingCol);
            case 'P': return canPawnAttack(pieceRow, pieceCol, kingRow, kingCol);
            default: return false;
        }
    }
    
    bool canQueenAttack(vector<string>& board, int r1, int c1, int r2, int c2) {
        return canRookAttack(board, r1, c1, r2, c2) || canBishopAttack(board, r1, c1, r2, c2);
    }
    
    bool canRookAttack(vector<string>& board, int r1, int c1, int r2, int c2) {
        if (r1 != r2 && c1 != c2) return false;
        return hasClearPath(board, r1, c1, r2, c2);
    }
    
    bool canBishopAttack(vector<string>& board, int r1, int c1, int r2, int c2) {
        if (abs(r1 - r2) != abs(c1 - c2)) return false;
        return hasClearPath(board, r1, c1, r2, c2);
    }
    
    bool canKnightAttack(int r1, int c1, int r2, int c2) {
        int dr = abs(r1 - r2), dc = abs(c1 - c2);
        return (dr == 2 && dc == 1) || (dr == 1 && dc == 2);
    }
    
    bool canPawnAttack(int r1, int c1, int r2, int c2) {
        return r1 + 1 == r2 && abs(c1 - c2) == 1;
    }
    
    bool hasClearPath(vector<string>& board, int r1, int c1, int r2, int c2) {
        int dr = (r2 - r1) == 0 ? 0 : (r2 - r1) / abs(r2 - r1);
        int dc = (c2 - c1) == 0 ? 0 : (c2 - c1) / abs(c2 - c1);
        
        int r = r1 + dr, c = c1 + dc;
        while (r != r2 || c != c2) {
            if (board[r][c] != '.') return false;
            r += dr;
            c += dc;
        }
        
        return true;
    }
};
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
func isKingInCheck(board []string) bool {
    kingRow, kingCol := -1, -1
    
    // Find king position
    for i := 0; i < 8; i++ {
        for j := 0; j < 8; j++ {
            if board[i][j] == 'K' {
                kingRow, kingCol = i, j
                break
            }
        }
        if kingRow != -1 {
            break
        }
    }
    
    // Check if any white piece attacks the king
    for i := 0; i < 8; i++ {
        for j := 0; j < 8; j++ {
            piece := board[i][j]
            if piece != '.' && piece != 'K' {
                if canAttack(board, i, j, kingRow, kingCol, piece) {
                    return true
                }
            }
        }
    }
    
    return false
}

func canAttack(board []string, pieceRow, pieceCol, kingRow, kingCol int, piece byte) bool {
    switch piece {
    case 'Q':
        return canQueenAttack(board, pieceRow, pieceCol, kingRow, kingCol)
    case 'R':
        return canRookAttack(board, pieceRow, pieceCol, kingRow, kingCol)
    case 'B':
        return canBishopAttack(board, pieceRow, pieceCol, kingRow, kingCol)
    case 'N':
        return canKnightAttack(pieceRow, pieceCol, kingRow, kingCol)
    case 'P':
        return canPawnAttack(pieceRow, pieceCol, kingRow, kingCol)
    default:
        return false
    }
}

func canQueenAttack(board []string, r1, c1, r2, c2 int) bool {
    return canRookAttack(board, r1, c1, r2, c2) || canBishopAttack(board, r1, c1, r2, c2)
}

func canRookAttack(board []string, r1, c1, r2, c2 int) bool {
    if r1 != r2 && c1 != c2 {
        return false
    }
    return hasClearPath(board, r1, c1, r2, c2)
}

func canBishopAttack(board []string, r1, c1, r2, c2 int) bool {
    if abs(r1-r2) != abs(c1-c2) {
        return false
    }
    return hasClearPath(board, r1, c1, r2, c2)
}

func canKnightAttack(r1, c1, r2, c2 int) bool {
    dr, dc := abs(r1-r2), abs(c1-c2)
    return (dr == 2 && dc == 1) || (dr == 1 && dc == 2)
}

func canPawnAttack(r1, c1, r2, c2 int) bool {
    return r1+1 == r2 && abs(c1-c2) == 1
}

func hasClearPath(board []string, r1, c1, r2, c2 int) bool {
    dr, dc := 0, 0
    if r2-r1 != 0 {
        dr = (r2 - r1) / abs(r2-r1)
    }
    if c2-c1 != 0 {
        dc = (c2 - c1) / abs(c2-c1)
    }
    
    r, c := r1+dr, c1+dc
    for r != r2 || c != c2 {
        if board[r][c] != '.' {
            return false
        }
        r += dr
        c += dc
    }
    
    return true
}

func abs(x int) int {
    if x < 0 {
        return -x
    }
    return x
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class Solution {
    public boolean isKingInCheck(String[] board) {
        int kingRow = -1, kingCol = -1;
        
        // Find king position
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (board[i].charAt(j) == 'K') {
                    kingRow = i;
                    kingCol = j;
                    break;
                }
            }
            if (kingRow != -1) break;
        }
        
        // Check if any white piece attacks the king
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                char piece = board[i].charAt(j);
                if (piece != '.' && piece != 'K') {
                    if (canAttack(board, i, j, kingRow, kingCol, piece)) {
                        return true;
                    }
                }
            }
        }
        
        return false;
    }
    
    private boolean canAttack(String[] board, int pieceRow, int pieceCol, 
                              int kingRow, int kingCol, char piece) {
        switch (piece) {
            case 'Q': return canQueenAttack(board, pieceRow, pieceCol, kingRow, kingCol);
            case 'R': return canRookAttack(board, pieceRow, pieceCol, kingRow, kingCol);
            case 'B': return canBishopAttack(board, pieceRow, pieceCol, kingRow, kingCol);
            case 'N': return canKnightAttack(pieceRow, pieceCol, kingRow, kingCol);
            case 'P': return canPawnAttack(pieceRow, pieceCol, kingRow, kingCol);
            default: return false;
        }
    }
    
    private boolean canQueenAttack(String[] board, int r1, int c1, int r2, int c2) {
        return canRookAttack(board, r1, c1, r2, c2) || canBishopAttack(board, r1, c1, r2, c2);
    }
    
    private boolean canRookAttack(String[] board, int r1, int c1, int r2, int c2) {
        if (r1 != r2 && c1 != c2) return false;
        return hasClearPath(board, r1, c1, r2, c2);
    }
    
    private boolean canBishopAttack(String[] board, int r1, int c1, int r2, int c2) {
        if (Math.abs(r1 - r2) != Math.abs(c1 - c2)) return false;
        return hasClearPath(board, r1, c1, r2, c2);
    }
    
    private boolean canKnightAttack(int r1, int c1, int r2, int c2) {
        int dr = Math.abs(r1 - r2), dc = Math.abs(c1 - c2);
        return (dr == 2 && dc == 1) || (dr == 1 && dc == 2);
    }
    
    private boolean canPawnAttack(int r1, int c1, int r2, int c2) {
        return r1 + 1 == r2 && Math.abs(c1 - c2) == 1;
    }
    
    private boolean hasClearPath(String[] board, int r1, int c1, int r2, int c2) {
        int dr = (r2 - r1) == 0 ? 0 : (r2 - r1) / Math.abs(r2 - r1);
        int dc = (c2 - c1) == 0 ? 0 : (c2 - c1) / Math.abs(c2 - c1);
        
        int r = r1 + dr, c = c1 + dc;
        while (r != r2 || c != c2) {
            if (board[r].charAt(c) != '.') return false;
            r += dr;
            c += dc;
        }
        
        return true;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Solution:
    def is_king_in_check(self, board: List[str]) -> bool:
        king_row, king_col = -1, -1
        
        # Find king position
        for i in range(8):
            for j in range(8):
                if board[i][j] == 'K':
                    king_row, king_col = i, j
                    break
            if king_row != -1:
                break
        
        # Check if any white piece attacks the king
        for i in range(8):
            for j in range(8):
                piece = board[i][j]
                if piece != '.' and piece != 'K':
                    if self._can_attack(board, i, j, king_row, king_col, piece):
                        return True
        
        return False
    
    def _can_attack(self, board: List[str], piece_row: int, piece_col: int, 
                    king_row: int, king_col: int, piece: str) -> bool:
        if piece == 'Q':
            return self._can_queen_attack(board, piece_row, piece_col, king_row, king_col)
        elif piece == 'R':
            return self._can_rook_attack(board, piece_row, piece_col, king_row, king_col)
        elif piece == 'B':
            return self._can_bishop_attack(board, piece_row, piece_col, king_row, king_col)
        elif piece == 'N':
            return self._can_knight_attack(piece_row, piece_col, king_row, king_col)
        elif piece == 'P':
            return self._can_pawn_attack(piece_row, piece_col, king_row, king_col)
        return False
    
    def _can_queen_attack(self, board: List[str], r1: int, c1: int, r2: int, c2: int) -> bool:
        return (self._can_rook_attack(board, r1, c1, r2, c2) or 
                self._can_bishop_attack(board, r1, c1, r2, c2))
    
    def _can_rook_attack(self, board: List[str], r1: int, c1: int, r2: int, c2: int) -> bool:
        if r1 != r2 and c1 != c2:
            return False
        return self._has_clear_path(board, r1, c1, r2, c2)
    
    def _can_bishop_attack(self, board: List[str], r1: int, c1: int, r2: int, c2: int) -> bool:
        if abs(r1 - r2) != abs(c1 - c2):
            return False
        return self._has_clear_path(board, r1, c1, r2, c2)
    
    def _can_knight_attack(self, r1: int, c1: int, r2: int, c2: int) -> bool:
        dr, dc = abs(r1 - r2), abs(c1 - c2)
        return (dr == 2 and dc == 1) or (dr == 1 and dc == 2)
    
    def _can_pawn_attack(self, r1: int, c1: int, r2: int, c2: int) -> bool:
        return r1 + 1 == r2 and abs(c1 - c2) == 1
    
    def _has_clear_path(self, board: List[str], r1: int, c1: int, r2: int, c2: int) -> bool:
        dr = 0 if r2 - r1 == 0 else (r2 - r1) // abs(r2 - r1)
        dc = 0 if c2 - c1 == 0 else (c2 - c1) // abs(c2 - c1)
        
        r, c = r1 + dr, c1 + dc
        while r != r2 or c != c2:
            if board[r][c] != '.':
                return False
            r += dr
            c += dc
        
        return True

Complexity

  • ⏰ Time complexity: O(1), since we have a fixed 8×8 board and at most check 64 positions with constant-time piece validation
  • 🧺 Space complexity: O(1), only using constant extra space for variables

Method 2 - Direction-Based Attack Vector Analysis

Intuition

Instead of checking each piece individually, we can scan from the king’s position in all possible attack directions and see if we encounter attacking pieces. This approach is more systematic and can be more efficient for sparse boards.

Approach

  1. Find the king’s position
  2. From the king’s position, scan in all 8 directions (horizontal, vertical, diagonal):
    • Check for Queen/Rook in horizontal/vertical directions
    • Check for Queen/Bishop in diagonal directions
  3. Check all 8 knight positions around the king
  4. Check the 2 pawn attack positions (diagonally forward)
  5. Return true if any attacking piece is found

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Solution {
public:
    bool isKingInCheck(vector<string>& board) {
        int kingRow = -1, kingCol = -1;
        
        // Find king position
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (board[i][j] == 'K') {
                    kingRow = i;
                    kingCol = j;
                    break;
                }
            }
            if (kingRow != -1) break;
        }
        
        // Check horizontal and vertical directions for Queen/Rook
        vector<vector<int>> directions = {{-1,0},{1,0},{0,-1},{0,1}};
        for (auto dir : directions) {
            if (checkDirection(board, kingRow, kingCol, dir[0], dir[1], "QR")) {
                return true;
            }
        }
        
        // Check diagonal directions for Queen/Bishop
        vector<vector<int>> diagonals = {{-1,-1},{-1,1},{1,-1},{1,1}};
        for (auto dir : diagonals) {
            if (checkDirection(board, kingRow, kingCol, dir[0], dir[1], "QB")) {
                return true;
            }
        }
        
        // Check knight positions
        vector<vector<int>> knightMoves = {{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
        for (auto move : knightMoves) {
            int nr = kingRow + move[0], nc = kingCol + move[1];
            if (isValid(nr, nc) && board[nr][nc] == 'N') {
                return true;
            }
        }
        
        // Check pawn attacks (diagonally forward)
        if (isValid(kingRow - 1, kingCol - 1) && board[kingRow - 1][kingCol - 1] == 'P') return true;
        if (isValid(kingRow - 1, kingCol + 1) && board[kingRow - 1][kingCol + 1] == 'P') return true;
        
        return false;
    }
    
private:
    bool checkDirection(vector<string>& board, int startR, int startC, 
                        int dr, int dc, string attackers) {
        int r = startR + dr, c = startC + dc;
        
        while (isValid(r, c)) {
            char piece = board[r][c];
            if (piece != '.') {
                return attackers.find(piece) != string::npos;
            }
            r += dr;
            c += dc;
        }
        
        return false;
    }
    
    bool isValid(int r, int c) {
        return r >= 0 && r < 8 && c >= 0 && c < 8;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Solution {
    public boolean isKingInCheck(String[] board) {
        int kingRow = -1, kingCol = -1;
        
        // Find king position
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (board[i].charAt(j) == 'K') {
                    kingRow = i;
                    kingCol = j;
                    break;
                }
            }
            if (kingRow != -1) break;
        }
        
        // Check horizontal and vertical directions for Queen/Rook
        int[][] directions = {{-1,0},{1,0},{0,-1},{0,1}};
        for (int[] dir : directions) {
            if (checkDirection(board, kingRow, kingCol, dir[0], dir[1], "QR")) {
                return true;
            }
        }
        
        // Check diagonal directions for Queen/Bishop
        int[][] diagonals = {{-1,-1},{-1,1},{1,-1},{1,1}};
        for (int[] dir : diagonals) {
            if (checkDirection(board, kingRow, kingCol, dir[0], dir[1], "QB")) {
                return true;
            }
        }
        
        // Check knight positions
        int[][] knightMoves = {{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
        for (int[] move : knightMoves) {
            int nr = kingRow + move[0], nc = kingCol + move[1];
            if (isValid(nr, nc) && board[nr].charAt(nc) == 'N') {
                return true;
            }
        }
        
        // Check pawn attacks
        if (isValid(kingRow - 1, kingCol - 1) && board[kingRow - 1].charAt(kingCol - 1) == 'P') return true;
        if (isValid(kingRow - 1, kingCol + 1) && board[kingRow - 1].charAt(kingCol + 1) == 'P') return true;
        
        return false;
    }
    
    private boolean checkDirection(String[] board, int startR, int startC, 
                                   int dr, int dc, String attackers) {
        int r = startR + dr, c = startC + dc;
        
        while (isValid(r, c)) {
            char piece = board[r].charAt(c);
            if (piece != '.') {
                return attackers.indexOf(piece) != -1;
            }
            r += dr;
            c += dc;
        }
        
        return false;
    }
    
    private boolean isValid(int r, int c) {
        return r >= 0 && r < 8 && c >= 0 && c < 8;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class Solution:
    def is_king_in_check_vectorized(self, board: List[str]) -> bool:
        king_row, king_col = -1, -1
        
        # Find king position
        for i in range(8):
            for j in range(8):
                if board[i][j] == 'K':
                    king_row, king_col = i, j
                    break
            if king_row != -1:
                break
        
        # Check horizontal and vertical directions for Queen/Rook
        directions = [(-1,0), (1,0), (0,-1), (0,1)]
        for dr, dc in directions:
            if self._check_direction(board, king_row, king_col, dr, dc, "QR"):
                return True
        
        # Check diagonal directions for Queen/Bishop
        diagonals = [(-1,-1), (-1,1), (1,-1), (1,1)]
        for dr, dc in diagonals:
            if self._check_direction(board, king_row, king_col, dr, dc, "QB"):
                return True
        
        # Check knight positions
        knight_moves = [(-2,-1), (-2,1), (-1,-2), (-1,2), (1,-2), (1,2), (2,-1), (2,1)]
        for dr, dc in knight_moves:
            nr, nc = king_row + dr, king_col + dc
            if self._is_valid(nr, nc) and board[nr][nc] == 'N':
                return True
        
        # Check pawn attacks
        if (self._is_valid(king_row - 1, king_col - 1) and 
            board[king_row - 1][king_col - 1] == 'P'):
            return True
        if (self._is_valid(king_row - 1, king_col + 1) and 
            board[king_row - 1][king_col + 1] == 'P'):
            return True
        
        return False
    
    def _check_direction(self, board: List[str], start_r: int, start_c: int, 
                         dr: int, dc: int, attackers: str) -> bool:
        r, c = start_r + dr, start_c + dc
        
        while self._is_valid(r, c):
            piece = board[r][c]
            if piece != '.':
                return piece in attackers
            r += dr
            c += dc
        
        return False
    
    def _is_valid(self, r: int, c: int) -> bool:
        return 0 <= r < 8 and 0 <= c < 8

Complexity

  • ⏰ Time complexity: O(1), scanning at most 8 directions with maximum 7 steps each, plus 8 knight positions and 2 pawn positions
  • 🧺 Space complexity: O(1), using only constant extra space

Performance Comparison

Method Time Complexity Space Complexity Best Use Case
Direct Attack Validation O(1) O(1) General purpose, clear logic
Direction-Based Analysis O(1) O(1) More efficient for sparse boards

Key Chess Rules Implemented

  1. Queen: Combines rook and bishop movements (8 directions)
  2. Rook: Horizontal and vertical lines only
  3. Bishop: Diagonal lines only
  4. Knight: L-shaped moves (2+1 or 1+2 squares)
  5. Pawn: Attacks diagonally forward only (not backward)

Edge Cases Handled

  • King not found on board
  • Pieces blocking attack paths
  • Board boundary validation
  • Empty board scenarios
  • Multiple attacking pieces

Both methods provide efficient solutions with constant time complexity, making them suitable for chess engines and game analysis systems.