Build a Five‑in‑a‑Row (Gomoku) Game with Pure JavaScript: Step‑by‑Step Guide

This tutorial walks you through creating a complete five‑in‑a‑row (Gomoku) web game using vanilla JavaScript, covering development approaches, board rendering, event delegation, win‑checking algorithms, piece placement logic, game reset, testing strategies, and essential JavaScript event handling techniques.

Aotu Lab
Aotu Lab
Aotu Lab
Build a Five‑in‑a‑Row (Gomoku) Game with Pure JavaScript: Step‑by‑Step Guide

Game Development Approaches

Small‑scale games can be built by one or two developers directly in the browser without formal specifications. Large‑scale games typically follow three phases: design (concept and target audience), specification (class and method definitions), and implementation (edit‑run cycle).

Gobang Rules

Two players use opposite‑colored stones.

The board starts empty.

Black moves first; players alternate placing one stone per turn.

Stones are placed on intersecting points and never moved or removed.

Black’s first stone may be placed on any intersection.

Core Implementation

Drawing the Board

The board is a 15×15 grid (n = 15). The drawGobang function creates a div for each cell, assigns an id block_i_j, and adds edge‑specific classes ( top, bottom, left, right) for styling.

function drawGobang(n) {
  for (var i = 0; i < n; i++) {
    for (var j = 0; j < n; j++) {
      var block = document.createElement("div");
      block.className = "gobang_block";
      block.id = "block_" + i + "_" + j;
      gobang.appendChild(block);
      if (i === 0) block.className += " top";
      if (i === n - 1) block.className += " bottom";
      if (j === 0) block.className += " left";
      if (j === n - 1) block.className += " right";
    }
  }
}
Gobang board layout
Gobang board layout

Placing Pieces with Event Delegation

A single click handler is attached to the board’s container element. The handler extracts the cell coordinates from the element’s id (e.g., block_3_7) and draws the appropriate stone.

var gobang = document.getElementById("gobang_main");
EventUtil.addHandler(gobang, "click", drawPiece);

When the event fires, the target id is split to obtain i and j:

i = +targetId.split("_")[1];
j = +targetId.split("_")[2];

Tracking Moves and Preventing Overwrites

Active stones receive the active class together with black or white.

Before drawing, the code checks target.className.indexOf("active") < 0 to ensure the cell is empty.

Relying solely on a board array (e.g., gobangArr[i][j]) is unsafe unless the array is explicitly cleared during reset.

Win Detection Algorithm

The chessWin(i, j, color) function counts consecutive stones of the same color in four directions: horizontal, vertical, diagonal (45°), and anti‑diagonal (135°). It starts with count = 1 (the newly placed stone) and scans up to four cells forward and backward in each direction. If count == 5 at any point, the player wins.

function chessWin(i, j, color) {
  var dirs = [
    {x: 0, y: 1},   // vertical
    {x: 1, y: 0},   // horizontal
    {x: 1, y: 1},   // 45° diagonal
    {x: 1, y: -1}   // 135° diagonal
  ];
  for (var d = 0; d < dirs.length; d++) {
    var count = 1;
    // forward direction
    for (var step = 1; step < 5; step++) {
      var x = i + dirs[d].x * step;
      var y = j + dirs[d].y * step;
      if (x < 0 || x >= 15 || y < 0 || y >= 15) break;
      if (gobangArr[x][y] === color) count++; else break;
    }
    // backward direction
    for (var step = 1; step < 5; step++) {
      var x = i - dirs[d].x * step;
      var y = j - dirs[d].y * step;
      if (x < 0 || x >= 15 || y < 0 || y >= 15) break;
      if (gobangArr[x][y] === color) count++; else break;
    }
    if (count >= 5) return true;
  }
  return false;
}
Win detection illustration
Win detection illustration

Resetting the Game

Reset clears all stones, empties the gobangArr matrix, restores the default turn (black first), updates UI prompts, and re‑binds the click handler. After a win, the click handler is removed to prevent further moves until the game is restarted.

Testing the Implementation

Validate edge cases such as placing stones on the board’s border cells.

Verify win detection for vertical, horizontal, 45°, and 135° lines.

JavaScript Event Fundamentals

Event Handler Types

HTML attribute handlers (e.g., onclick="...") – discouraged because they tightly couple markup and logic.

DOM0 – assign a function to element.onclick; only one handler per event.

DOM2 – addEventListener / removeEventListener support multiple listeners and allow capture/bubble control.

IE attachEvent – similar to DOM2 but runs in the global scope and invokes listeners in reverse order.

Cross‑browser utility – a lightweight EventUtil object abstracts the differences.

var EventUtil = {
  addHandler: function (element, type, handler) {
    if (element.addEventListener) {
      element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
      element.attachEvent("on" + type, handler);
    } else {
      element["on" + type] = handler;
    }
  },
  getEvent: function (event) {
    return event ? event : window.event;
  },
  getTarget: function (event) {
    return event.target || event.srcElement;
  }
};

Event Object and Target Normalization

Both DOM0 and DOM2 pass an event object to the handler. In older IE versions the event is accessed via window.event. EventUtil.getEvent returns a normalized event, and EventUtil.getTarget returns the actual element that triggered the event.

Source Code and References

Online demo: http://labs.qiang.it/qqpai/test/wcn/gobang/gobang.html

GitHub repository: https://github.com/Newcandy/gobang

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendJavaScriptGame Developmentevent delegationGomoku
Aotu Lab
Written by

Aotu Lab

Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.