
The renju rule
The renju rule, the international standard for Gomoku, assumes that Black, who moves first, has the advantage, and imposes forbidden moves on Black only. Black may not make a double-three, a double-four or an overline (six or more in a row), while White has no restrictions at all. An overline is even a win for White.
When we first built the engine with the renju rule, White became almost invincible. Black's attacking shapes are blocked as forbidden moves, while White can win freely with the same shapes.
The same forbidden moves for Black and White
So we changed the rules so that there is no difference between Black and White.
- Double-three: forbidden for both Black and White. Broken threes (●_●●, ●●_●) also count as threes.
- Overline: forbidden for both, and six or more in a row does not count as a win. Only exactly five wins.
- Double-four: allowed for both.
- A move that makes five is checked before the forbidden-move check. A winning move can always be played.

White still won after the change
The time of the rule change is not on record, so we split the games at the fifth day of automatic play, when the engine file last changed. In the 445 games before it, White won 419 (94%); in the 42 games after it, 38 (90%).
In the training games, White was always the VLM and Black was always the local AI. So these records alone cannot tell whether White won because of the rules or because the local AI playing Black was weak. We need to play again with the same AI alternating between Black and White.
The actual code for this step
This is the forbidden-move check in the web engine. It first checks whether the move wins, then blocks only overlines and double-threes.
omook-web/lib/board.ts
export function hasKyungsuBan(
board: Stone[],
row: number,
col: number,
stone: Stone,
size: number,
): RejectReason | null {
if (!inBounds(row, col, size)) return "out_of_bounds";
if (cell(board, row, col, size) !== EMPTY) return "occupied";
if (wouldWinIfPlaced(board, row, col, stone, size)) return null;
const g = withStone(board, row, col, stone, size);
if (hasOverline(g, row, col, stone, size)) return "changmok";
if (countOpenThreeAxes(g, row, col, stone, size) >= 2) return "sansan";
return null;
}The next post is "3. An AI that cannot see wins through a broken four".
COMMENTS · CHAPTER 02
The renju rule made White invincible 0 comments
No comments yet. Leave a question or anything you would like to add.
To post a comment, continue with Google and register a nickname and email address.
Continue with Google