Available Captures for Rook: Direct Simulation
You are given an 8x8 chessboard represented as a 2D array. Each cell contains one of four characters: 'R' (white rook), 'B' (white bishop), 'p' (black pawn), or '.' (empty). There is exactly one white rook on the board. Return the number of black pawns the rook can capture.
The rook moves horizontally or vertically, any number of squares. It captures the first pawn it encounters in each direction but cannot move through bishops. This is LeetCode 999: Available Captures for Rook.
Why this problem matters
This problem is pure simulation. There is no clever algorithm, no tricky data structure. You find the rook, scan in four directions, and count what you hit. That makes it a great exercise for building confidence with 2D grid traversal before tackling harder matrix problems like spiral traversal or island counting.
The skill it reinforces is the "direction vector" pattern: defining a list of (dr, dc) pairs and iterating along each one. You will use this same pattern in flood fill, BFS on grids, and any problem that requires moving through a matrix in specific directions.
The approach
The algorithm has two phases:
- Find the rook. Scan every cell of the 8x8 board until you find
'R'. Record its row and column. - Scan four directions. For each direction (up, down, left, right), walk outward from the rook one square at a time. If you hit a pawn
'p', increment your capture count and stop. If you hit a bishop'B'or the edge of the board, stop without capturing.
That is the entire solution. The board is always 8x8, so the work is constant regardless of piece placement.
The solution
def num_rook_captures(board: list[list[str]]) -> int:
rook_r, rook_c = 0, 0
for r in range(8):
for c in range(8):
if board[r][c] == "R":
rook_r, rook_c = r, c
captures = 0
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for dr, dc in directions:
r, c = rook_r + dr, rook_c + dc
while 0 <= r < 8 and 0 <= c < 8:
if board[r][c] == "p":
captures += 1
break
if board[r][c] == "B":
break
r += dr
c += dc
return captures
The first nested loop finds the rook. Since the board is 8x8 and there is exactly one rook, this takes at most 64 checks.
The second loop iterates over four direction vectors. For each direction, it starts one step away from the rook and walks until it hits the board boundary, a pawn, or a bishop. If it finds a pawn, it increments captures and breaks. If it finds a bishop, it breaks without incrementing. If it reaches the edge, the while condition fails and the loop ends naturally.
The break statements are important. Once you hit any piece (pawn or bishop), you must stop scanning in that direction. The rook cannot jump over pieces.
The direction vector pattern [(-1, 0), (1, 0), (0, -1), (0, 1)] is one of the most reusable building blocks in grid problems. Memorize it. You will use it in flood fill, BFS traversal, and dozens of other matrix problems. Some problems add diagonals with four more pairs, but the four cardinal directions are the foundation.
Visual walkthrough
Let's trace through the example board step by step. The rook is at (4,3). We scan each of the four directions and check what we encounter first.
Step 1: Find the rook at (4,3).
Scan the board to locate R. The rook is at row 4, column 3.
Step 2: Scan up from (4,3).
Move up: (3,3) is empty, (2,3) is a pawn. Capture it. Captures so far: 1.
Step 3: Scan down from (4,3).
Move down: (5,3) is empty, (6,3) is a pawn. Capture it. Captures so far: 2.
Step 4: Scan left from (4,3).
Move left: (4,2) is empty, (4,1) is a pawn. Capture it. Captures so far: 3.
Step 5: Scan right from (4,3).
Move right: (4,4) and (4,5) are empty, (4,6) is a bishop B. Blocked. No capture. Final answer: 3.
The rook captures pawns in three directions (up, down, left) and is blocked by a bishop to the right. The answer is 3.
Complexity analysis
| Approach | Time | Space |
|---|---|---|
| Direct simulation | O(1) | O(1) |
Time is O(1) because the board is always 8x8. Finding the rook takes at most 64 steps. Scanning four directions takes at most 7 steps each (at most 28 steps total). The total work is bounded by a constant.
Space is O(1). You only store the rook position and a capture counter. No additional data structures are needed.
Note: if the board were n x n instead of fixed at 8x8, time would be O(n^2) for finding the rook and O(n) for scanning directions, giving O(n^2) overall. Space would remain O(1).
The building blocks
1. Grid scanning to find a target
The pattern of iterating over every cell to locate a specific element:
for r in range(rows):
for c in range(cols):
if grid[r][c] == target:
target_r, target_c = r, c
This is the simplest grid operation and it comes up constantly. In "Number of Islands" you scan for '1' cells to start DFS from. In "Rotting Oranges" you scan for all rotten oranges to seed the BFS queue. In this problem you scan for the single rook. The pattern is always the same: nested loops over rows and columns, checking each cell against a condition.
2. Directional ray casting on a grid
The pattern of walking from a starting cell in a fixed direction until you hit a boundary or obstacle:
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for dr, dc in directions:
r, c = start_r + dr, start_c + dc
while 0 <= r < rows and 0 <= c < cols:
if grid[r][c] == obstacle:
break
r += dr
c += dc
This "ray cast" pattern appears in problems involving queens, rooks, and bishops on chessboards, as well as in problems like "Search a 2D Matrix" where you walk along a row or column. The key detail is the while loop with boundary checking and the dr, dc increment. Once you have this pattern memorized, you can adapt it to any direction-based grid traversal.
Edge cases
Before submitting, think through these scenarios:
- No pawns on the board: the rook scans all four directions and never hits a
'p'. Return0. - Rook in a corner: only two directions have cells to scan. The other two immediately go out of bounds.
- Rook completely surrounded by bishops: every direction is immediately blocked. Return
0. - Pawn directly adjacent to the rook: the while loop body executes once, finds the pawn, and increments captures immediately.
- Pawns in all four directions with no bishops: the rook captures 4 pawns. This is the maximum possible answer.
- Bishop between rook and pawn: the bishop blocks the rook. The pawn behind the bishop is not captured.
From understanding to recall
You now understand the approach: find the rook, scan four directions, count captures. The code is short and the logic is clean. But when you sit down in an interview and need to write it from scratch, the details matter. Do you check the boundary before or after incrementing? Do you break on the bishop or on the pawn? Do you include the rook's own cell in the scan?
These are not conceptual questions. They are muscle memory questions. Spaced repetition helps you internalize the direction vector pattern and the ray casting loop so you can write them without thinking. After a few rounds of practice, scanning a grid in four directions becomes as automatic as writing a for loop.
Related posts
- Number of Islands - Grid traversal with DFS flood fill, using the same direction vector pattern to explore neighbors
- Search a 2D Matrix - Another matrix problem that requires systematic traversal, using binary search on a flattened grid
- Spiral Matrix - Directional movement through a matrix with boundary tracking, building on the same
(dr, dc)pattern
CodeBricks breaks Available Captures for Rook into its grid scanning and directional ray casting building blocks, then drills them independently with spaced repetition. You type each piece from scratch until the pattern is automatic. When a grid traversal problem shows up in your interview, you do not hesitate. You just write it.