Katkat

Detect a K-in-a-Row Win on a Rectangular Board

DatabricksSoftware Engineer · Onsite

Last updated

Implement an efficient win-detection function that checks whether a newly placed token forms at least k consecutive matching tokens along any linear axis on a rectangular grid.

Problem Statement

In generalized grid-based alignment games (such as Connect Four or Gomoku), players take turns placing tokens on a rectangular board. A player wins if they form an unbroken line of at least k identical tokens horizontally, vertically, or diagonally.

Given an m x n grid board where 0 represents an empty cell and any positive integer represents a player's token, implement the function winning_move(board, row, col, k). The function is called immediately after a player has placed their token at (row, col). It should return True if this move created a sequence of at least k consecutive tokens of the same player, and False otherwise.

An optimal solution should evaluate only the lines passing through (row, col) rather than re-scanning the entire board.

Function Signature

def winning_move(board: list[list[int]], row: int, col: int, k: int) -> bool:
    pass

Input Format

  • board: A 2D list of integers of dimensions m x n.
  • row: Integer index indicating the row of the latest move (0 <= row < m).
  • col: Integer index indicating the column of the latest move (0 <= col < n).
  • k: Positive integer representing the minimum consecutive tokens needed to win.

Output Format

  • Returns True if the token at (row, col) completes at least k in a row along any of the four axes; otherwise, returns False.

Constraints

  • 1 <= m, n <= 10^4
  • 1 <= m * n <= 10^6
  • 1 <= k <= max(m, n)
  • 0 <= row < m and 0 <= col < n
  • board[row][col] != 0

Examples

Example 1

board = [
    [0, 1, 0, 0],
    [0, 1, 2, 0],
    [0, 1, 0, 2],
    [0, 1, 0, 0]
]
row, col, k = 2, 1, 4
# Output: True
# Explanation: The player 1 token placed at (2, 1) completes a vertical run of 4 tokens from (0, 1) to (3, 1).

Example 2

board = [
    [1, 2, 1],
    [2, 1, 2],
    [0, 0, 0]
]
row, col, k = 1, 1, 3
# Output: False
# Explanation: The main diagonal has length 2 ([board[0][0], board[1][1]]). No direction has 3 in a row.

Edge Cases to Consider

  • k = 1: Any valid move is an immediate win.
  • k is larger than both m and n: Win is impossible, should return False quickly.
  • Boundaries: The move is on the perimeter or corner of the board.

Hints

Hint 1

Since only the latest move can have triggered a new win, only examine lines passing through `(row, col)`.

Hint 2

Pair opposing directions (e.g., left and right, up and down) and count consecutive matching tokens radiating outward from `(row, col)`.

Hint 3

You can stop scanning along any ray as soon as you encounter a boundary, an empty cell, a rival token, or after checking `k - 1` steps.

Follow-up questions

  • How would you adapt this for an unbounded or sparse grid where coordinates can be arbitrarily large and stored in a hash map?
  • If the game rule strictly requires *exactly* k in a row (an overline of k + 1 tokens does not count), how would your algorithm change?
  • How would you ensure thread-safety if multiple players or agents query and update the board concurrently?