0
0
LldHow-ToBeginner ยท 4 min read

How to Design Tic Tac Toe Game: Simple System Design Guide

To design a Tic Tac Toe game, create a Board to hold the game state, a Game controller to manage turns and rules, and a Player entity to represent users. Use simple methods to check for wins or draws and update the board after each move.
๐Ÿ“

Syntax

The design includes three main parts:

  • Board: Holds the 3x3 grid and tracks moves.
  • Game: Controls the game flow, player turns, and win/draw checks.
  • Player: Represents each player with a symbol (X or O).

Each part has clear responsibilities to keep the design simple and maintainable.

javascript
class Board {
    constructor() {
        this.grid = Array(3).fill(null).map(() => Array(3).fill(null));
    }

    placeMark(row, col, mark) {
        if (this.grid[row][col] === null) {
            this.grid[row][col] = mark;
            return true;
        }
        return false;
    }

    checkWin(mark) {
        // Check rows, columns, diagonals for win
    }

    isFull() {
        return this.grid.flat().every(cell => cell !== null);
    }
}

class Player {
    constructor(name, mark) {
        this.name = name;
        this.mark = mark;
    }
}

class Game {
    constructor(player1, player2) {
        this.board = new Board();
        this.players = [player1, player2];
        this.currentPlayerIndex = 0;
        this.isOver = false;
    }

    playTurn(row, col) {
        if (this.isOver) return 'Game over';
        const player = this.players[this.currentPlayerIndex];
        if (this.board.placeMark(row, col, player.mark)) {
            if (this.board.checkWin(player.mark)) {
                this.isOver = true;
                return `${player.name} wins!`;
            } else if (this.board.isFull()) {
                this.isOver = true;
                return 'Draw!';
            } else {
                this.currentPlayerIndex = 1 - this.currentPlayerIndex;
                return 'Next turn';
            }
        } else {
            return 'Invalid move';
        }
    }
}
๐Ÿ’ป

Example

This example shows a simple Tic Tac Toe game flow where two players take turns placing marks. It demonstrates board updates, win checking, and turn switching.

javascript
class Board {
    constructor() {
        this.grid = Array(3).fill(null).map(() => Array(3).fill(null));
    }

    placeMark(row, col, mark) {
        if (this.grid[row][col] === null) {
            this.grid[row][col] = mark;
            return true;
        }
        return false;
    }

    checkWin(mark) {
        const g = this.grid;
        for (let i = 0; i < 3; i++) {
            if (g[i][0] === mark && g[i][1] === mark && g[i][2] === mark) return true;
            if (g[0][i] === mark && g[1][i] === mark && g[2][i] === mark) return true;
        }
        if (g[0][0] === mark && g[1][1] === mark && g[2][2] === mark) return true;
        if (g[0][2] === mark && g[1][1] === mark && g[2][0] === mark) return true;
        return false;
    }

    isFull() {
        return this.grid.flat().every(cell => cell !== null);
    }

    printBoard() {
        console.log(this.grid.map(row => row.map(cell => cell || '-').join(' ')).join('\n'));
    }
}

class Player {
    constructor(name, mark) {
        this.name = name;
        this.mark = mark;
    }
}

class Game {
    constructor(player1, player2) {
        this.board = new Board();
        this.players = [player1, player2];
        this.currentPlayerIndex = 0;
        this.isOver = false;
    }

    playTurn(row, col) {
        if (this.isOver) return 'Game over';
        const player = this.players[this.currentPlayerIndex];
        if (this.board.placeMark(row, col, player.mark)) {
            if (this.board.checkWin(player.mark)) {
                this.isOver = true;
                return `${player.name} wins!`;
            } else if (this.board.isFull()) {
                this.isOver = true;
                return 'Draw!';
            } else {
                this.currentPlayerIndex = 1 - this.currentPlayerIndex;
                return 'Next turn';
            }
        } else {
            return 'Invalid move';
        }
    }
}

// Usage example
const p1 = new Player('Alice', 'X');
const p2 = new Player('Bob', 'O');
const game = new Game(p1, p2);

console.log(game.playTurn(0, 0)); // Alice places X
console.log(game.playTurn(0, 0)); // Bob tries same spot
console.log(game.playTurn(1, 1)); // Bob places O
console.log(game.playTurn(0, 1)); // Alice places X
console.log(game.playTurn(2, 2)); // Bob places O
console.log(game.playTurn(0, 2)); // Alice places X and wins

game.board.printBoard();
Output
Next turn Invalid move Next turn Next turn Next turn Alice wins! X X X - O - - - O
โš ๏ธ

Common Pitfalls

Common mistakes include:

  • Not checking if a move is valid before placing a mark.
  • Forgetting to switch players after a valid move.
  • Incorrectly checking win conditions, missing diagonals or rows.
  • Not handling draw situations when the board is full.

Always validate moves, update game state carefully, and test all win/draw scenarios.

javascript
/* Wrong: Not checking if cell is empty before placing */
function placeMarkWrong(board, row, col, mark) {
    board[row][col] = mark; // overwrites existing mark
}

/* Right: Check before placing */
function placeMarkRight(board, row, col, mark) {
    if (board[row][col] === null) {
        board[row][col] = mark;
        return true;
    }
    return false;
}
๐Ÿ“Š

Quick Reference

Tic Tac Toe Design Tips:

  • Use a 3x3 grid to represent the board.
  • Keep game logic separate from UI or input handling.
  • Check rows, columns, and diagonals for wins.
  • Switch players after each valid move.
  • Detect draw when board is full with no winner.
โœ…

Key Takeaways

Separate the board, game logic, and player entities for clean design.
Always validate moves and update the board state carefully.
Check all win conditions including rows, columns, and diagonals.
Switch turns correctly and detect draw when the board is full.
Keep the design simple and test all game scenarios.