Ahmed Doghri Logo Image
Ahmed Doghri

connectpuct

Every game AI repo has a benchmark table. Very few of them let you actually sit down and lose to the thing. connectpuct ships both, a browser game and a PUCT agent that beats random and center baselines 10 out of 10.

connectpuct, a Connect Four game with a PUCT search agent

A Board Game That Actually Plays Back

I did not want another game AI repo that only prints a score and asks you to believe it. connectpuct has the engine, the search agent, the benchmark, and a browser page you can open and get humbled by in under a minute.

The game is Connect Four because the tactics are simple enough to inspect and deep enough to punish a lazy agent. Immediate wins matter. Blocks matter. Center control matters. Search has to weigh all three in real time, no hiding behind a big model.

Search With Priors, Not Vibes

The Python agent uses PUCT-style Monte Carlo tree search. Priors favor center columns, immediate wins, and tactical blocks, then rollouts settle whatever the priors couldn't decide on their own.

The web game is dependency-free, no server and no build step. The benchmark pits the search agent against random and center-first baselines, so the result is a scoreline, not a screenshot with a board conveniently cropped in.

The Number

connectpuct wins 10 of 10 games against random and 10 of 10 against the center baseline in the checked benchmark. Neither of those is a hard bar to clear, which is exactly the point: an agent that fails easy opponents has no business calling itself an agent.

The playable game lives at `web/index.html`, no excuse not to open it.

"Not a Hard Bar" Deserved a Real Opponent

I wrote that sentence myself in the original README, that random and center-only were not a hard bar to clear, and then never actually followed up on what a hard bar would look like. So I checked. An opponent with zero search at all, no MCTS, no lookahead, that just always drops a piece in the center column, already beats the random baseline almost every single game on its own. A perfect scoreline against either one says the agent isn't actively broken. It does not say the agent is actually good.

I built a real opponent to find out: depth-limited alpha-beta minimax with a center-weighted positional heuristic. No learning, no opening book, just correct lookahead a fixed number of moves ahead, which is the first thing anyone building a real game AI reaches for to sanity-check strength. Twenty games against it, alternating who moves first each game, and the PUCT agent's win rate dropped from a perfect record to roughly 55 percent. A real contest, not a foregone conclusion.

This is not a regression in the agent. The search code and the published 10-out-of-10 numbers against random and center are completely untouched, and they still reproduce exactly. It is the honest measurement the easy baselines never gave me, and it is a genuinely more useful number if you are trying to decide whether this agent is actually strong or just strong compared to opponents that were never going to put up a fight.

12 tests pass locally and on GitHub Actions across Python 3.9, 3.11, and 3.13.

Tools Used

Python
JavaScript
MCTS
PUCT
Game AI
Alpha-Beta Search
pytest