Problem
Design a Tic-tac-toe game that is played between two players on anxngrid. You may assume the following rules:
- A move is guaranteed to be valid and is placed on an empty block.
- Once a winning condition is reached, no more moves is allowed.
- A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game.
Examples
**Example 1: **
|
|
Follow up: Could you do better than O(n^2) permove()
operation?
Could you get O(1) per move()
operation?
Class structure
|
|
Solution
Method 1 - Use 2D char array
Here are the steps:
- Initialization:
- Create a
board
with sizen x n
. - Use characters ‘X’ and ‘O’ to represent the moves of the two players.
- Create a
- Making a Move:
- Validate the move to ensure it is placed on an empty block.
- Update the
board
with the player’s move. - Check if the current move results in a win by evaluating the row, column, primary diagonal, and anti-diagonal containing the move.
- Check Win Condition:
- For each move, check the corresponding row, column, and diagonals if they contain all identical marks (
X
orO
).
- For each move, check the corresponding row, column, and diagonals if they contain all identical marks (
This ensures that the game accurately tracks moves and winning conditions with each move evaluated in linear time relative to the grid size.
Code
|
|
|
|
Method 2 - Using arrays for rows and cols
The approach optimizes the process of determining the winner by utilizing counters for rows, columns, and diagonals, instead of maintaining the entire n x n
board.
Key Observations
- Winning Condition: To win Tic-tac-toe, a player must have all their marks in a single row, column, or diagonal.
- Optimized Tracking: Instead of tracking each cell, maintain counters for each row, column, and the two diagonals.
- Player Identification: Use +1 for Player 1 and -1 for Player 2, making it easy to count and identify winning conditions by the absolute value of the counters.
Steps
- Initialization:
- Create arrays to keep count of marks in each row and column (
rows
andcols
). - Use variables to keep track of the main diagonal and anti-diagonal counts.
- Create arrays to keep count of marks in each row and column (
- Making a Move:
- Update the corresponding row, column, and diagonal counters based on the player’s move.
- Check if the current move results in a win by evaluating if any counter equals
n
(the size of the grid), after adjusting for the player’s identifier.
- Check Win Condition:
- If any row, column, or diagonal counter reaches the absolute value
n
, the respective player has won.
- If any row, column, or diagonal counter reaches the absolute value
This ensures that each move and win check operates in constant time, making the implementation highly efficient.
Code
|
|
|
|
|
|
|
|