JSFiddle - React, Tailwind, and code Playground

by Yuriy Petrichenko

HTML

<h2 id="currentPlayerStatus"></h2>

		<button id="resetGame" onclick="initGame()" hidden>Play again</button>
	<div>
		<input type="button" value="&nbsp;" onclick="btnClick(event, 0)"/>
		<input type="button" value="&nbsp;" onclick="btnClick(event, 1)"/>
		<input type="button" value="&nbsp;" onclick="btnClick(event, 2)"/>
	</div>
	<div>
		<input type="button" value="&nbsp;" onclick="btnClick(event, 3)"/>
		<input type="button" id="centralBtn" value="&nbsp;" onclick="btnClick(event, 4)"/>
		<input type="button" value="&nbsp;" onclick="btnClick(event, 5)"/>
	</div>
	<div>
		<input type="button" value="&nbsp;" onclick="btnClick(event, 6)"/>
		<input type="button" value="&nbsp;" onclick="btnClick(event, 7)"/>
		<input type="button" value="&nbsp;" onclick="btnClick(event, 8)"/>
	</div>

CSS

input[type="button"]{
	height:75px;
	width:75px;
	font-size: 28px;
	border: 1px solid gray;
	background-color: lightgray;
    margin-right: -4px;
}

#resetGame {
	margin: 0 0 10px 0;
}

JavaScript

// gameStatus: 
// 1 - active
// 2 - result : draw
// 0 - result : smbd wins

var playerStatusElement = document.getElementById('currentPlayerStatus');
var resetGameButton = document.getElementById('resetGame');
var game, currentPlayer, gameStatus;
var playerX = 'x';
var playerO = 'o';
initGame();

var centralBtnTextChanged = new CustomEvent("btnTextChanged");
centralBtn.addEventListener("btnTextChanged", function(){
	console.log("Central button value changed!");	
});

function btnClick(event, arrId) {
	if(game[arrId] === '-' && gameStatus === 1) {
		event.target.value = currentPlayer;
		event.target.dispatchEvent(centralBtnTextChanged);

		game[arrId] = currentPlayer;

		var win = checkWin();
		if(win) {
			gameStatus = 0;
			setPlayerStatusElementText("Player '" + currentPlayer + "' win!");
			resetGameButton.hidden = false;
		} else if(!~game.indexOf('-')){
			gameStatus = 2;
			setPlayerStatusElementText("Draw!");
			resetGameButton.hidden = false;
		} else {
			switchPlayer();
			showGameStatus();
			setPlayerStatusElementText("Player '" + currentPlayer + "' move");
		}
	} else {
		event.target.style.borderColor = 'red';
		event.target.style.backgroundColor = 'pink';
		setTimeout(function(){
			event.target.style.borderColor = 'gray';
			event.target.style.backgroundColor = 'lightgray';
		}, 2000);
	}
}

function initGame() {
	game = ['-', '-', '-', '-', '-', '-', '-', '-', '-'];
	currentPlayer = playerX;
	gameStatus = 1;
	setPlayerStatusElementText("Player '" + currentPlayer + "' move");
	var butts = document.querySelectorAll("input[type='button'");
	for (var i = 0; i < butts.length; i++) {
		butts[i].value = " ";
	}
	resetGameButton.hidden = true;
}

function switchPlayer() {
	currentPlayer = currentPlayer === playerX 
	? playerO
	: playerX;
}

function setPlayerStatusElementText(text){
	playerStatusElement.innerHTML = text;
}

function checkWin() {
	var horizontal = currentPlayer === game[0] && currentPlayer === game[1] && currentPlayer === game[2] 
				 ...