Four-in-a-row against Monte Carlo Tree Search, its search tree blooming as a flower.
Monte Carlo Tree Search plays four-in-a-row knowing nothing but the rules. Each playout walks down its tree picking the child with the best UCB1 score (win rate plus an exploration bonus weighted by c), adds the children of the node it reaches, plays the game out with quick semi-random moves that take a win or block a loss when one is there, and credits every node on the way back up. The flower is that tree: the center is the current position, each petal a node whose angular share follows its parent's visit split, whose width follows its own visit count, and whose tint is the win rate for gold or rose. Bright threads are the selection paths of the latest playouts. Thousands of playouts run in time-sliced chunks each frame, and you can watch attention pile onto one petal: the move it is about to play.
Try it. Click a column (or press 1 to 7) to take over the side to move; on your turn the bloom becomes a hint of what MCTS would play. Choose 1k to 40k playouts per move and drag the exploration constant c from greedy to reckless. Play Gold or Play Rose starts a game as that side; Watch AI vs AI (W) hands it back. Keys: + and - change playouts, [ and ] change c, N starts a new game.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a four-in-a-row game (7 columns, 6 rows) where I play against Monte Carlo Tree Search, with JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Draw the board and let me click a column to drop a disc; discs stack from the bottom. Detect four in a row horizontally, vertically and on both diagonals, and draws when the board is full.
- Write MCTS from scratch. Each node stores visits, wins and its children. One iteration: starting at the root, repeatedly pick the child with the highest UCB1 score, wins / visits + c * sqrt(ln(parent visits) / visits) with c around 1.4 (unvisited children first); when you reach a leaf, add its children; play the game out with random moves; then walk back up adding a visit to every node and a win to the nodes of the player who won.
- After a few thousand iterations play the most visited move. Run the iterations in chunks per animation frame so the page never freezes while it thinks.
Once that works, make it beautiful:
- Draw the search tree as a radial flower beside the board: the root in the center, each child a petal pointing outward whose angular share of its parent is proportional to its visits, whose width grows with its visit count and whose color shows its win rate.
- Ease the petals toward their new shapes each frame so the flower visibly blooms while the AI thinks, and glow the petal it is about to pick.
- Make the random playouts smarter: take an immediate win or block an immediate loss when there is one.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as sliders for the playout budget and the exploration constant, drawing the latest selection paths as glowing threads, or reusing the subtree after each move.