Skip to content

Instantly share code, notes, and snippets.

@JuanCaicedo
Created December 4, 2019 01:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JuanCaicedo/3709b5c5ed6d2ebdcd0fb0e1483debe8 to your computer and use it in GitHub Desktop.
Save JuanCaicedo/3709b5c5ed6d2ebdcd0fb0e1483debe8 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app" class="grid game">
<div class="row">
<div class="cell" data-cell-id="1"></div>
<div class="cell" data-cell-id="2"></div>
<div class="cell" data-cell-id="3"></div>
</div>
<div class="row">
<div class="cell" data-cell-id="4"></div>
<div class="cell" data-cell-id="5"></div>
<div class="cell" data-cell-id="6"></div>
</div>
<div class="row">
<div class="cell" data-cell-id="7"></div>
<div class="cell" data-cell-id="8"></div>
<div class="cell" data-cell-id="9"></div>
</div>
</div>
<h3 class="message">It is X's turn</h3>
<script src="src/index.js"></script>
</body>
</html>
import "./styles.css";
window.TTT = window.TTT || { currentTurn: "X" };
const VERTICAL_LINES = [[1, 4, 7], [2, 5, 8], [3, 6, 9]];
const HORIZONTAL_LINES = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
const DIAGONAL_LINES = [[1, 5, 9], [7, 5, 3]];
const WINNING_COMBINATIONS = [
...VERTICAL_LINES,
...HORIZONTAL_LINES,
...DIAGONAL_LINES
];
function addListener(event, element, handler) {
element.addEventListener(event, handler);
}
function changeTurn(currentTurn) {
const nextTurn = currentTurn === "X" ? "O" : "X";
window.TTT.currentTurn = nextTurn;
setMessage(`It is ${nextTurn}'s turn`);
}
function convertToArray(nodeList) {
return [...nodeList];
}
function filterCells(_cells, player) {
const cells = convertToArray(_cells);
return cells.filter(cell => cell.textContent === player);
}
function getId(cell) {
const idAttribute = cell.getAttribute("data-cell-id");
return parseInt(idAttribute);
}
function containsAll(combination, cells) {
return combination.every(cellId => cells.includes(cellId));
}
function displayWinner(currentTurn) {
setMessage(`${currentTurn} is the winner`);
}
function displayTie() {
setMessage("It is a tie");
}
function areMovesRemaining(cells) {
return cells.some(cell => !cell.textContent);
}
function setMessage(text) {
const message = document.querySelector(".message");
message.textContent = text;
}
function checkGameover() {
const _cells = document.querySelectorAll(".cell");
const cells = convertToArray(_cells);
const player1Cells = filterCells(cells, "X").map(getId);
const player2Cells = filterCells(cells, "O").map(getId);
const someoneDidWin = WINNING_COMBINATIONS.some(combination => {
return (
containsAll(combination, player1Cells) ||
containsAll(combination, player2Cells)
);
});
if (someoneDidWin) {
disableAll(cells);
displayWinner(window.TTT.currentTurn);
return true;
}
if (!areMovesRemaining(cells)) {
displayTie();
return true;
}
return false;
}
function disableAll(cells) {
cells.forEach(cell => (cell.disabled = true));
}
function handleClick(e) {
const current = e.target;
const currentTurn = window.TTT.currentTurn;
if (current.disabled) {
return;
}
current.textContent = currentTurn;
current.disabled = true;
const isGameover = checkGameover();
if (!isGameover) {
changeTurn(currentTurn);
}
}
const cells = document.querySelectorAll(".cell");
cells.forEach(cell => addListener("click", cell, handleClick));
.grid {
display: flex;
flex-direction: column;
width: 300px;
height: 300px;
margin: auto;
}
.row {
display: flex;
height: 33%;
}
.cell {
background: cyan;
width: 33%;
height: 100%;
border: 1px solid blue;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
font-size: 48px;
}
.message {
text-align: center;
}
.game {
font-family: sans-serif;
margin-top: 50px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment