Gomoku board in JavaScript EDIT: The result looks like this: http://gomokuu.glitch.me/

This is my code for gomoku. I made it with JavaScript and HTML. I think the checkWinner function can be improved or made shorter. Also, should the functions be re-organized? 

Here is the code:

Javascript:

var turn = 0;
var width = 15;
var height = 15;
var gameOver = false;
var board = Array(width * height);

function announceWinner(winner) {
  console.log("a");
  if (winner == 0) {
    window.alert("X wins");
  }
  if (winner == 1) {
    window.alert("O wins");
  }
  if (winner == 2) {
    window.alert("Board filled");
  }
}

function checkWinner() {
  var filled = true;
  for (var i = 0; i &lt; board.length; i++) {
    if (board[i] == undefined) filled = false;
    if (board[i] !== undefined) {
      if (
        (board[i] == board[i + 1] &amp;&amp;
          board[i + 1] == board[i + 2] &amp;&amp;
          board[i + 2] == board[i + 3] &amp;&amp;
          board[i + 3] == board[i + 4]) ||
        (board[i] == board[i + width] &amp;&amp;
          board[i + width] == board[i + 2 * width] &amp;&amp;
          board[i + 2 * width] == board[i + 3 * width] &amp;&amp;
          board[i + 3 * width] == board[i + 4 * width]) ||
        (board[i] == board[i + 1 + width] &amp;&amp;
          board[i + 1 + width] == board[i + 2 + 2 * width] &amp;&amp;
          board[i + 2 + 2 * width] == board[i + 3 + 3 * width] &amp;&amp;
          board[i + 3 + 3 * width] == board[i + 4 + 4 * width]) ||
        (board[i] == board[i - 1 + width] &amp;&amp;
          board[i - 1 + width] == board[i - 2 + 2 * width] &amp;&amp;
          board[i - 2 + 2 * width] == board[i - 3 + 3 * width] &amp;&amp;
          board[i - 3 + 3 * width] == board[i - 4 + 4 * width])
      ) {
        gameOver = true;
        announceWinner(board[i]);
      }
    }
  }
  if (filled) {
    announceWinner(2);
  }
}

function tileClick(row, tile) {
  var clicked = document.getElementById("board").children[row].children[tile];
  if (clicked.innerHTML || gameOver) return;
  board[tile + row * width] = turn;
  if (turn) {
    clicked.innerHTML = "o";
    clicked.style.color = "red";
    turn = 0;
  } else {
    clicked.innerHTML = "x";
    clicked.style.color = "blue";
    turn = 1;
  }
  checkWinner();
}

//generate board and listen to click event
var domBoard = document.createElement("table");
domBoard.id = "board";
for (let i = 0; i &lt; height; i++) {
  var row = document.createElement("tr");
  for (let j = 0; j &lt; width; j++) {
    var tile = document.createElement("td");
    tile.onclick = function() {
      tileClick(i, j);
    };
    row.appendChild(tile);
  }
  domBoard.appendChild(row);
}
document.body.appendChild(domBoard);


HTML:

&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;gomoku&lt;/title&gt;
    &lt;link rel="stylesheet" href="style.css" /&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;script src="script.js"&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
I don't have time to give you a full review, so I'll just add some comments about checkWinner:


It will read better if you remove the mutation of global state from it.  Make it a pure function that returns true or false.  
You might consider using a 2D array as your data structure.  This isn't necessary, but it maps more naturally to the visual board, and will likely clean up some of your logic.


As for the duplication, you can remove a lot of it by introducing a helper function to capture the abstract logic that's being repeated in every block.  This will also clarify the high-level logic of checking for a winner:

function checkWinner() {
  for (var i = 0; i &lt; board.length; i++) {
    var rightWin = winAt(i, 1)
    var downWin = winAt(i, width)
    if (rightWin || downWin) return true
  }
  return false
}

function winAt(i, step) {
  if ( board[i] === undefined ) return false
  for ( var j = 1; j &lt; 5; j++) {
    var nextIndex = i + (j * step)
    if ( board[i] !== board[nextIndex] ) return false
  }
  return true
}


EDIT: Answer to question

Green Ball, regarding the problem you mentioned with using a 2D array, there are ways around that: you can pad with extra rows of undefined, or you can abstract a cell(i, j) which hides the ugly bounds checking, and keeps it in one place.  Indeed, that last point is the key one, not whether you use a 1D or 2D array.

In your current implementation, the arithmetic logic around rows is forced out on the client: any code that wants to get an i, j pair must do the calculation itself.  Currently happens in checkWinner and tileClick: board[tile + row * width].  It also happens implicitly in the double loop that constructs the html.

Regardless of the underlying structure that holds the board, you want your client code to be able to work with the concepts of "rows" and "columns" as first class citizens, since that's how we humans are thinking about this.  It will make the code more natural.