Skip to content

Instantly share code, notes, and snippets.

@aviwarner
Last active October 28, 2020 17:20
Show Gist options
  • Save aviwarner/59c75ccc32842a9925128749a1235a07 to your computer and use it in GitHub Desktop.
Save aviwarner/59c75ccc32842a9925128749a1235a07 to your computer and use it in GitHub Desktop.
Tic Tac Toe - vanilla
<div id="app">
<h1>Tic Tac Toe!</h1>
<h2>Current turn: <span id="current-turn"></span></h2>
<h2 id="result"></h2>
<div class="board">
<div class="row">
<div class="square no-left no-top" id="1"></div>
<div class="square no-top" id="2"></div>
<div class="square no-top no-right" id="3"></div>
</div>
<div class="row">
<div class="square no-left" id="4"></div>
<div class="square" id="5"></div>
<div class="square no-right" id="6"></div>
</div>
<div class="row">
<div class="square no-left no-bottom" id="7"></div>
<div class="square no-bottom" id="8"></div>
<div class="square no-right no-bottom" id="9"></div>
</div>
</div>
<button onclick="clearAll()">start over</button>
</div>
const winningCombos = [
[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 state = {
currentPlayer: 1,
player1Selections: [],
player2Selections: [],
winner: null
};
const players = {
1: "X",
2: "O"
};
const squares = Array.from(document.querySelectorAll(".square"));
const currentPlayerLabel = document.querySelector("#current-turn");
const resultLabel = document.querySelector("#result");
function handleSquareClick(e) {
let clickedSquare = e.target;
if (
clickedSquare.innerHTML !== "X" &&
clickedSquare.innerHTML !== "O" &&
!state.winner
) {
setSquareContent(state.currentPlayer, clickedSquare);
setNewPlayer(state.currentPlayer);
}
}
function setSquareContent(playerId, square) {
state[`player${playerId}Selections`].push(parseInt(square.id));
square.innerHTML = players[playerId];
const winner = checkWinner(playerId);
if (winner) {
state.winner = playerId;
resultLabel.innerHTML = `Player ${players[playerId]} has won! You can start over.`;
} else {
const selectedSquares =
state.player1Selections.length + state.player2Selections.length;
if (selectedSquares === 9) {
resultLabel.innerHTML = `It's a draw! You can start over.`;
}
}
}
function checkWinner(id) {
const playerSquares = state[`player${id}Selections`];
let isWinner = false;
winningCombos.forEach((combo) => {
const allPresent = combo.every((num) => {
return playerSquares.indexOf(num) > -1;
});
if (allPresent) {
isWinner = true;
}
});
return isWinner;
}
function setNewPlayer(id) {
if (id === 1) {
state.currentPlayer = 2;
} else {
state.currentPlayer = 1;
}
currentPlayerLabel.innerHTML = players[state.currentPlayer];
}
squares.forEach((square) =>
square.addEventListener("click", handleSquareClick)
);
const initialize = () => {
currentPlayerLabel.innerHTML = players[state.currentPlayer];
};
const clearAll = () => {
squares.forEach((square) => {
return (square.innerHTML = " ");
});
state = {
...state,
player1Selections: [],
player2Selections: [],
winner: null
};
resultLabel.innerHTML = "";
};
initialize();
body {
font-family: sans-serif;
}
.square {
height: 100px;
width: 100px;
border: 3px solid red;
color: blue;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
font-size: 70px;
}
.no-bottom {
border-bottom: 0px;
}
.no-right {
border-right: 0px;
}
.no-left {
border-left: 0px;
}
.no-top {
border-top: 0px;
}
.board {
padding: 5%;
}
.row {
display: flex;
flex-direction: row;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment