How would you write a function that calculates the number of mines adjacent to each cell in a minesweeper board?
Question Analysis
The question requires you to write a function for a minesweeper game. The goal is to calculate the number of mines adjacent to each cell on a board, where each cell can either be a mine or empty. This is a typical 2D grid problem where you need to consider the neighbors of each cell. The challenge lies in correctly handling the boundaries and efficiently counting the mines surrounding each cell. This involves understanding the grid traversal and boundary checks.
Answer
To solve this problem, we need to iterate over each cell of the board and for each cell, count the number of mines in its adjacent cells. Typically, a cell has up to 8 neighbors unless it's on the edge or corner of the board. Here's a step-by-step outline of how to implement this:
-
Initialize the Board: Create a result board of the same size as the input board to store the number of adjacent mines for each cell.
-
Define Directions: Use an array to define the 8 possible directions to move from a cell (up, down, left, right, and the four diagonals).
-
Traverse Each Cell: Loop through each cell in the board.
-
Count Adjacent Mines:
- For each cell, check all 8 neighboring directions.
- For each valid neighbor (within board boundaries), check if it is a mine.
- Increment the mine count for the current cell in the result board if a mine is found.
-
Boundary Conditions: Ensure you do not check outside the bounds of the board.
Here's a Python function implementing this logic:
def count_adjacent_mines(board):
rows = len(board)
cols = len(board[0]) if rows > 0 else 0
# Directions: (row_offset, col_offset)
directions = [(-1, -1), (-1, 0), (-1, 1),
(0, -1), (0, 1),
(1, -1), (1, 0), (1, 1)]
# Initialize result board
result = [[0 for _ in range(cols)] for _ in range(rows)]
for r in range(rows):
for c in range(cols):
# Only count adjacent mines for non-mine cells
if board[r][c] == 0: # Assuming 0 represents empty
mine_count = 0
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and board[nr][nc] == 1: # Assuming 1 represents a mine
mine_count += 1
result[r][c] = mine_count
else:
result[r][c] = -1 # Marking mine cells directly
return result
# Example usage:
# 1 represents a mine, 0 represents an empty cell
board = [
[0, 1, 0],
[0, 0, 1],
[1, 0, 0]
]
print(count_adjacent_mines(board))
Key Points:
- Efficient Traversal: The function efficiently checks each cell's neighbors by using direction vectors.
- Boundary Handling: Uses boundary checks to prevent out-of-bounds errors.
- Output Representation: The function marks cells with mines as
-1
in the result (for clarity), while other cells contain the count of adjacent mines.
This solution effectively addresses the problem requirements and should work for any valid minesweeper board configuration.