Find Winner on a Tic-Tac-Toe Game · Optimal Solution

Count moves. Detect a winner.

Two players take turns marking a 3×3 grid in a casual mobile game. Rather than scanning the entire board after every tap, the app tracks running signed counters — one per row, one per column, and one for each diagonal. Player A adds +1, Player B adds −1. If any counter reaches +3 or −3, that player wins immediately. After all moves, a full board with no winner is a draw; otherwise the game is still pending.


Interactive

Watch the algorithm run


Concept

Signed Counters

Maintain a score for each row, each column, and both diagonals. A's moves add +1; B's moves add −1. If any counter reaches +3 or −3, that player has completed a line and wins.

A move at (r, c) updates row[r] and col[c]. If r == c, it also updates the main diagonal. If r + c == 2, it updates the anti-diagonal. The center cell (1,1) sits on both diagonals.


Algorithm

Algorithm

Instead of scanning the board after each move, we maintain running sums for every row, column, and both diagonals. A sum of ±3 means a player owns an entire line.

  1. 1

    Initialize counters

    Create rows[3], cols[3], mainDiag, and antiDiag, all initialized to zero.

  2. 2

    Assign scores

    Player A (even turns) scores +1. Player B (odd turns) scores −1.

  3. 3

    Update and check

    For each move, add the score to the row, column, and diagonals (if applicable). If any counter reaches +3 or −3, that player wins.

  4. 4

    Determine outcome

    After all moves: if no winner and 9 moves were played, it's a draw. Otherwise, it's pending.


Edge Cases

Edge Patterns

Understanding boundary behavior is as important as the main algorithm path.

Diagonal wins

Diagonal sums are only updated when the move falls on the main diagonal (r == c) or anti-diagonal (r + c == 2). Corner cells affect both.

Draw vs pending

A draw requires exactly 9 moves with no winner. If fewer moves have been played and no winner exists, the game is still pending.


Complexity

Complexity

Time: O(n) — at most 9 moves, each updating O(1) counters.
Space: O(1) — six counters (3 rows + 3 columns + 2 diagonals).