Building an Enhanced Tic Tac Toe Game

From Basic Console Game to Interactive Web Experience


๐Ÿš€ Project Overview

What started as a simple Python console tic-tac-toe game quickly evolved into a fully-featured web application with smooth animations, AI opponents, and celebration effects. This blog post documents my journey from debugging Jupyter notebook issues to creating an engaging interactive experience.

Project Stats

  • 500+ Lines of Code
  • 3 AI Difficulty Levels
  • 50 Particle Effects

๐Ÿ› The Initial Challenge

The project began with a frustrating problem: my Python tic-tac-toe game wasnโ€™t working properly in Jupyter notebooks. The output was buggy, input prompts werenโ€™t appearing correctly, and the user experience was terrible. We also had to figure out how to work together to further better our game.

$ jupyter notebook tictactoe-game.ipynb
> ERROR: Input not displaying correctly
> ISSUE: Game state not updating properly
> PROBLEM: User experience is broken

The root cause? Jupyter notebooks donโ€™t handle interactive console input loops well, especially with input() functions in while loops. This led me to pivot toward a web-based solution.


๐Ÿ”„ The Pivot Decision

Instead of fighting with Jupyterโ€™s limitations, I decided to create a dedicated web page for the game. This opened up possibilities for much richer interactions and visual effects that simply werenโ€™t possible in a console environment.

Why Web Over Console?

โœ“ Better User Experience: Clickable interface instead of typing numbers

โœ“ Visual Feedback: Animations, hover effects, and visual cues

โœ“ Cross-Platform: Works on any device with a web browser

โœ“ Expandability: Easy to add features like sounds, themes, or multiplayer


โšก Development Timeline

Phase 1: Basic Web Layout - Tanay

Created a simple black background with 9 white clickable squares. Implemented basic game logic for move validation and win detection.

// Basic move function
function makeMove(index) {
    if (gameBoard[index] !== '' || !gameActive) return;
    gameBoard[index] = currentPlayer;
    // Update display and check win conditions
}

Phase 2: Enhanced Features - Moiz

Added smooth animations, player name input, score tracking, and particle effects for wins. The game started feeling more polished and engaging.

// Symbol animation
.square .symbol {
    animation: symbolAppear 0.5s ease-out;
    transform-origin: center;
}

Phase 3: AI Implementation - Aneesh

Built three difficulty levels for AI opponents: Easy (random), Medium (mix of smart/random), and Hard (optimal play with minimax-style logic).

// AI difficulty selection
switch(aiDifficulty) {
    case 'hard': move = getBestMove(); break;
    case 'medium': move = Math.random() > 0.3 ? getBestMove() : getRandomMove(); break;
    case 'easy': move = getRandomMove(); break;
}

Phase 4: Polish & Effects - Moiz

Added celebration particles, improved responsive design, and refined the user interface with better visual hierarchy and feedback.


๐ŸŽจ Key Features Implemented

โœ“ Smooth Animations: X and O symbols appear with rotating scale effects

โœ“ Particle Celebrations: 50 gold and silver particles fall when someone wins

โœ“ Player Customization: Custom names for both human and AI opponents

โœ“ Score Persistence: Track wins across multiple games in a session

โœ“ Smart AI Opponent: Three difficulty levels with strategic gameplay

โœ“ Responsive Design: Works perfectly on desktop, tablet, and mobile

โœ“ Game State Management: Proper turn switching and game flow control

โœ“ Visual Feedback: Hover effects, disabled states, and clear status messages


๐Ÿง  Technical Challenges & Solutions

Challenge 1: AI Strategy

Creating an AI thatโ€™s challenging but not impossible required implementing a priority system:

function getBestMove() {
    // 1. Try to win immediately
    // 2. Block player from winning
    // 3. Take center if available
    // 4. Take corners
    // 5. Take any remaining space
}

Challenge 2: Smooth Animations

CSS animations needed to feel natural without being jarring:

@keyframes symbolAppear {
    0% { opacity: 0; transform: scale(0) rotate(180deg); }
    50% { transform: scale(1.2) rotate(90deg); }
    100% { opacity: 1; transform: scale(1) rotate(0deg); }
}

Challenge 3: Particle Effects

Creating realistic falling particles that donโ€™t impact performance:

// Staggered particle creation with cleanup
for (let i = 0; i < 50; i++) {
    setTimeout(() => {
        createParticle();
        setTimeout(() => particle.remove(), 4000);
    }, i * 50);
}

๐ŸŽฏ Lessons Learned

โœ“ Pivot When Necessary: Donโ€™t be afraid to change direction when technology limitations arise

โœ“ User Experience First: Visual feedback and intuitive interfaces matter more than complex code

โœ“ Progressive Enhancement: Start with basic functionality, then add polish and features

โœ“ Test Across Devices: What works on desktop might not work on mobile

โœ“ Performance Matters: Smooth animations are better than flashy but laggy effects

โœ“ Teamwork: We all worked together to implement hacks to further better our game


๐Ÿš€ Try It Yourself

The complete game is available as a standalone HTML file that you can run in any modern web browser. It includes all the features mentioned above and provides a smooth, engaging tic-tac-toe experience.

๐ŸŽฎ Play the Enhanced Tic Tac Toe Game

Source Code: Available in the project repository with full documentation and comments explaining each feature and implementation detail.


Built with HTML, CSS, and JavaScript No frameworks required 100% vanilla code