Build the game engine
Ask Claude to build the tic-tac-toe rules
⏱ Est. ~7 min
01 · Read
The game engine is the brain of your app. It doesn't know about WebSocket, HTML, or players. It just knows how tic-tac-toe works: 3x3 board, two symbols, turns, win conditions.
Putting this logic in its own file — separate from the server code — is a pattern called separation of concerns. The game engine is a standalone module that can be used by any server, any test framework, any UI.
💡 Picture thisThink of a basketball referee. The ref doesn't run the arena, sell tickets, or operate the scoreboard. They just enforce the rules. Your game engine is the referee — it only cares whether a move is valid and whether someone won.
Key points
- Separation of concerns: game logic in its own file
- The game engine doesn't know about WebSocket or HTML
- Handles: board state, move validation, turn tracking, win detection
- Makes it easy to test and reuse
02 · Prompt template
Ask Claude to build the game engine module. Be specific about what the class should do — this produces much better output than "make a tic-tac-toe game".
Help me create a game.js module containing a TicTacToeGame class. Requirements: (1) Initialize the board as an array of length 9, all filled with null. (2) Track whose turn it is — X always goes first. (3) Provide a makeMove(cellIndex) method that validates the move (cell must be 0-8, cell must be empty, must be that player's turn), places the corresponding symbol, checks for win or draw, and returns an object { valid, symbol, winner, isDraw, board }. (4) Provide a getState() method that returns the current board and whose turn it is. (5) Check all 8 winning lines (3 rows, 3 columns, 2 diagonals). (6) Export the class using module.exports.03 · Code example
After Claude produces the game engine, find the win-checking logic. This is the part you should understand, not just accept.
Win detection: 8 winning lines
const WINNING_LINES = [
[0, 1, 2], [3, 4, 5], [6, 7, 8], // rows
[0, 3, 6], [1, 4, 7], [2, 5, 8], // columns
[0, 4, 8], [2, 4, 6] // diagonals
];
// Board layout:
// 0 | 1 | 2
// ---+---+---
// 3 | 4 | 5
// ---+---+---
// 6 | 7 | 8
The board is a flat array of 9 cells. Indices 0-2 are the top row, 3-5 the middle row, 6-8 the bottom row. A player wins by filling three cells in any of 8 possible lines. After each move, the engine checks all 8 lines — if any line has three matching non-null symbols, that player wins. If all 9 cells are filled with no winner, it's a draw.
04 · Real-machine exercise
Test the game engine directly in the Node.js REPL. This is how real engineers verify code before wiring anything up.
05 · Checklist
Make sure your game engine handles these edge cases. Try each in the Node REPL, or ask Claude to write a quick test.
- X always goes first — the first move is always X
- Placing a move on an occupied cell returns valid: false
- Playing out of turn returns valid: false
- After a win, no more moves are allowed
- A full board with no winner correctly reports a draw
06 · Quiz
Why is it valuable to build the game engine as a module separate from the server?
- It can be tested independently, used in other projects, and keeps the server code focused
- JavaScript requires every class to be in its own file
- It makes the code harder to understand but faster to run
- Socket.io can't access code in the same file as Express
Other lessons in this chapter
⚠ The full interactive experience needs JavaScript. Please enable it and reload.
※ This is an independent Traditional Chinese teaching project — not an official Anthropic product. Claude™ is a trademark of Anthropic, PBC.