tic-tac-toe

by Vladymyr Shevchuk

HTML

<div id="result"></div>
<table id="table">
  <tr>
    <td data-id="1"></td>
    <td data-id="2"></td>
    <td data-id="3"></td>
  </tr>
  <tr>
    <td data-id="4"></td>
    <td data-id="5"></td>
    <td data-id="6"></td>
  </tr>
  <tr>
    <td data-id="7"></td>
    <td data-id="8"></td>
    <td data-id="9"></td>
  </tr>
</table>
<button id="restart-btn">Restart Game</button>

CSS

html, body {
    font-size: 24px;
}
table {
    background: green;
}

td {
    width: 80px;
    height: 80px;
    text-align: center;
    border: 1px solid white;
    cursor: pointer;
}
td:hover {
    background: darkgreen;
}

.highlight,
.highlight:hover {
    background: orange;
    cursor: default;
}

button {
    cursor: pointer;
    font-size: 24px;
}

JavaScript

const $table = document.getElementById('table');
const $restartBtn = document.getElementById('restart-btn');
const $result = document.getElementById('result');

$restartBtn.addEventListener('click', () => document.location.reload());

const combinations = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],

  [1, 4, 7],
  [2, 5, 8],
  [3, 6, 9],

  [1, 5, 9],
  [3, 5, 7]
];

let store = combinations.slice();

const updateStore = (arr, id, value) =>
  arr.map(subArr =>
    subArr.map(item => item === id ? value : item));

const findWinner = (arr, value) =>
  arr.findIndex(subArr =>
    subArr.every(item => item === value));

const highlightWinner = winnerIndex => {
  const cellsArr = combinations[winnerIndex];

  cellsArr.forEach(item => {
    const $el = document.querySelector(`[data-id="${item}"]`);

    $el.classList.add('highlight');
  });
};

let clicksCounter = 0;

const step = event => {
  const {target} = event;
  const id = parseInt(target.dataset.id, 10);
  const value = clicksCounter % 2 ? 'O' : 'X';
  const isEmptyCell = target.tagName === 'TD' && !target.textContent;

  if (isEmptyCell) {
    store = updateStore(store, id, value);
    target.textContent = value;
    clicksCounter += 1;

    const winner = findWinner(store, value);

    if (winner >= 0) {
      highlightWinner(winner);
      $result.textContent = `${value} wins!`;
      $table.removeEventListener('click', step);
    } else if (clicksCounter === 9) {
      $result.textContent = 'Draw!';
    }
  }
};

$table.addEventListener('click', step);