I wanted a quick side project that blends Python with the web, so I built a Tic-Tac-Toe game that runs entirely in the browser using Brython (Python for the front-end). The whole game is self-contained in a single HTML file—you can drop it straight into a WordPress Custom HTML block and it just works. You can play either against another person or challenge a simple computer opponent. It’s a fun way to show how Python can live on the client side, no server setup required.
🎮 Tic-Tac-Toe
What Brython Does
Brython is a JavaScript library that lets you write client-side code in Python instead of JavaScript. It provides a runtime that translates Python into JavaScript on the fly, exposing browser APIs (like the DOM, events, and timers) directly to Python scripts. That means instead of writing document.getElementById() in JavaScript, you can work with the page using familiar Python code. Brython handles the translation and execution in the browser, so everything runs locally with no server required.
What the Python Code Is Doing
The Python block in this project is the actual game logic:
- Game State: A list called
boardtracks the 9 cells of the Tic-Tac-Toe grid. Variablescurrentandfirst_playerhold whose turn it is.game_overis a flag to prevent further moves when the game ends. - Winning Lines: The
winning_lineslist stores all possible three-in-a-row combinations (rows, columns, and diagonals). - Winner Checking: The
check_winner()function loops through those winning lines. If three identical marks are found, it declares a winner. If the board is full with no winner, it returns a draw. - UI Updates: The
update_ui()function synchronizes the Python game state with the HTML board. It sets X or O text into each cell, highlights winning cells, updates the status banner, and changes the turn display. - Game Controls:
reset_board()clears the board and starts a new game.swap_first()toggles who goes first between X and O.
- CPU Opponent: The
try_best_move()function implements a simple AI. It first checks if the CPU can win immediately. If not, it checks if it needs to block the opponent. If neither, it prefers the center, then corners, then sides.cpu_move()calls this logic and places the O piece. - Gameplay Flow: The
handle_click()function runs whenever a player clicks a cell. It places the current player’s mark, checks for a winner, switches turns, and if in CPU mode, triggers the computer’s move after a short delay for responsiveness. - Event Wiring: At the bottom, the script attaches click handlers to all nine cells and the control buttons (restart and swap). Finally,
update_ui()paints the first empty board and sets up the initial status.