JSFiddle - React, Tailwind, and code Playground

by outis

HTML

<div id="h8">
  <div id="board">             
	<div id="sq0" onclick="move(0)"><div id="xo0"><span class="ex">&emsp;</span></div></div>
	<div id="sq1" onclick="move(1)"><div id="xo1"><span class="ex">&emsp;</span></div></div>
	<div id="sq2" onclick="move(2)"><div id="xo2"><span class="ex">&emsp;</span></div></div><br/>

	<div id="sq3" onclick="move(3)"><div id="xo3"><span class="ex">&emsp;</span></div></div>
	<div id="sq4" onclick="move(4)"><div id="xo4"><span class="ex">&emsp;</span></div></div>
	<div id="sq5" onclick="move(5)"><div id="xo5"><span class="ex">&emsp;</span></div></div><br/>

	<div id="sq6" onclick="move(6)"><div id="xo6"><span class="ex">&emsp;</span></div></div>
	<div id="sq7" onclick="move(7)"><div id="xo7"><span class="ex">&emsp;</span></div></div>
	<div id="sq8" onclick="move(8)"><div id="xo8"><span class="ex">&emsp;</span></div></div><br/>
</div></div>


<div id="msgX">X Wins</div>
<div id="msgO">O Wins</div>
<div id="h"></div>

<button id="ng" onclick="newgame();">New Game</button>

CSS

html,body{padding:0 0 0 5px;}
#board > div {
	cursor: pointer;
}
#board#h8{width:255px;margin:0;padding:0;border:0;}
#sq0,#sq1,#sq2,#sq3,#sq4,#sq5,#sq6,#sq7,#sq8{width:80px;height:80px;:inline-block;border:2px solid black;display:inline-block;
											 background: linear-gradient(to bottom, #444 0%, #111 100%);}
#xo0,#xo1,#xo2,#xo3,#xo4,#xo5,#xo6,#xo7,#xo8{padding:0 0 0 16px;color:#fff;font:700 60px Arial,sans-serif;display:inline-block;}
.oh{font-size:66px;color:#ff0;}
.ex{font-size:66px;color:#f0f;}
button{color:#fff;width:251px;background: linear-gradient(to bottom, rgba(0,0,255,1) 0%, rgba(0,0,64,1) 100%);}
#prefetch{display:none;}
#h8{opacity:1;}
#msgX,#msgO{display:none;width:250px;text-align:center;font:700 40px Arial,sans-derif;color:#f00;}
#ng{font:700 33px Arial,sans-serif;}

JavaScript

(function () {
	
	const xos = [],
		  squareMasks = [
			  0b000000000000000011,
			  0b000000000000001100,
			  0b000000000000110000,

			  0b000000000011000000,
			  0b000000001100000000,
			  0b000000110000000000,

			  0b000011000000000000,
			  0b001100000000000000,
			  0b110000000000000000,
		  ],
		  // bitmasks for lines of squares
		  lines = [
			  board => board & 0b000000000000111111,
			  board => (board & 0b000000111111000000) >> 6,
			  board => (board & 0b111111000000000000) >> 12,
			  
			  board => (board & squareMasks[0]) | ((board & squareMasks[3]) >> 4) | ((board & squareMasks[6]) >> 8),
			  board => ((board & squareMasks[1]) >> 2) | ((board & squareMasks[4]) >> 6) | ((board & squareMasks[7]) >> 10),
			  board => ((board & squareMasks[2]) >> 4) | ((board & squareMasks[5]) >> 8) | ((board & squareMasks[8]) >> 12),

			  board => (board & squareMasks[0]) | ((board & squareMasks[4]) >> 6) | ((board & squareMasks[8]) >> 12),
			  board => ((board & squareMasks[2]) >> 4) | ((board & squareMasks[4]) >> 6) | ((board & squareMasks[6]) >> 8),
		  ],
		  // which line each square participates in; indexes into lines
		  participation = [
			  [0, 3, 6],
			  [0, 4],
			  [0, 5, 7],

			  [1, 3],
			  [1, 4, 6, 7],
			  [1, 5],

			  [2, 3, 7],
			  [2, 4],
			  [2, 5, 6],
		  ],
		  wins = {
			  0b010101: 0,
			  0b101010: 1,
		  },
		  h = {
			  0: document.getElementById('h8'),
			  1: document.getElementById('h8'),
			  2: document.getElementById('h'),
		  },
		  msg = {
			  0: document.getElementById('msgX'),
			  1: document.getElementById('msgO'),
			  2: document.getElementById('h'),
		  },
		  img = ['<span class="ex">X</span>','<span class="oh">&#927;</span>','<span class="ex">&emsp;</span>'];

	for (let i = 0; i < 9; ++i) {
		xos[i] = document.getElementById('xo' + i);
	}
	
	var player = 0,
		board = 0x0;

	function win(id) {
		for (let line of participation[id]) {
			line = lines[line](board);
			if (line in wins) {
				return...