const tokens = [{
name: "Beemo",
img: "beemo-token.png",
},
{
name: "Princess Bubblegum",
img: "bubble-token.png",
}
]
let player1 = {
token: 0
}
let player2 = {
token: 1
}
let gameboard = [
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1]
]; // array representation of gameboard
let currentPlayer = 1; // indicates who's turn it is
let numTurn = 0; // counts the num of turns made
populateSpace();
let againBtn = document.getElementById("again-btn");
againBtn.addEventListener("click", playAgain);
// Populates the spaces for the gameboard
function populateSpace() {
// <div class="space"> </div>
let rows = document.querySelectorAll(".row");
// return [<div>, <div>, <div>]
for (let rowNum = 0; rowNum < rows.length; rowNum++) {
let row = rows[rowNum];
for (let col = 0; col < 3; col++) {
let space = document.createElement("div");
space.innerHTML = " ";
space.classList.add("space");
space.id = rowNum + "-" + col;
space.addEventListener("click", playerTurn);
row.appendChild(space);
}
}
}
// Implements functionality when a player turn is made
function playerTurn(event) {
let spaceContent = event.target;
let location = spaceContent.id.split("-");
let row = location[0];
let col = location[1];
// update the gameboard array ("placeToken")
placeToken(row, col);
// update the gameboard DOM
updateGameboard();
// check whether the current Player has won
numTurn++;
let won = checkWon();
if (won) {
report("Congratulations! Player " + currentPlayer + " has won!");
return
}
if (numTurn == 9) {
report("There was a tie");
return
}
updateTurn();
// if the player has not won => update the Turn
// if the player has won/tie => show the container-div
}
// Updates the gameboard variable to indicate a token was placed at a specific row, col
function placeToken(row, col) {
if (gameboard[row][col] == -1) {
if (currentPlayer == 1) {
gameboard[row][col] = 1;
} else { // currentPlayer == 2
gameboard[row][col] = 2;
}
}
}
// Update who's turn it is
function updateTurn() {
if (currentPlayer == 1) {
currentPlayer = 2;
} else { // currentPlayer = 1
currentPlayer = 1;
}
let turn = document.querySelector("span");
turn.textContent = "Player " + currentPlayer;
}
// Updates the gameboard generating the tokens based on the gameboard values
function updateGameboard() {
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 3; col++) {
let space = document.getElementById(row + "-" + col);
space.innerHTML = "";
if (gameboard[row][col] == 1) {
let token = makeToken(player1);
space.appendChild(token);
} else if (gameboard[row][col] == 2) {
let token = makeToken(player2);
space.appendChild(token);
} else { // gameboard[row][col] == -1
}
}
}
}
// Creates and returns the token DOM element of the given player
function makeToken(player) {
let token = document.createElement("img");
token.classList.add("token");
token.src = "./img/tokens/" + tokens[player.token].img;
token.alt = tokens[player.token].name;
return token;
}
// Report whether the player has won or lost
function report(message) {
let winContainer = document.getElementById("win-container");
let gameContainer = document.getElementById("gameboard");
winContainer.classList.remove("hidden");
gameContainer.classList.add("hidden");
let h2 = document.querySelector("#win-container h2");
h2.textContent = message;
}
// Restarts and shows the gameboard to play again
function playAgain() {
clearGameboard();
let winContainer = document.getElementById("win-container");
let gameContainer = document.getElementById("gameboard");
winContainer.classList.add("hidden");
gameContainer.classList.remove("hidden");
numTurn = 0;
}
// Clears the gameboard
function clearGameboard() {
let rows = document.querySelectorAll(".row");
for (let i = 0; i < rows.length; i++) {
let row = rows[i];
row.innerHTML = "";
}
gameboard = [
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1]
];
populateSpace();
}
// Returns true/false if the current player who just made a move won
function checkWon() {
// Horizontal
for (let row = 0; row < 3; row++) {
let count = 0;
for (let col = 0; col < 3; col++) {
if (gameboard[row][col] == currentPlayer) {
count++;
}
}
if (count == 3) {
return true;
}
count = 0;
}
// Vertical
for (let col = 0; col < 3; col++) {
let count = 0;
for (let row = 0; row < 3; row++) {
if (gameboard[row][col] == currentPlayer) {
count++;
}
}
if (count == 3) {
return true;
}
count = 0;
}
// Diagonal
if (gameboard[0][0] == currentPlayer &&
gameboard[1][1] == currentPlayer &&
gameboard[2][2] == currentPlayer) {
return true;
}
if (gameboard[0][2] == currentPlayer &&
gameboard[1][1] == currentPlayer &&
gameboard[2][0] == currentPlayer) {
return true;
}
return false
}
body {
font-family: 'Ranchers', Arial, Helvetica, sans-serif;
background-color: cornsilk;
}
button {
background-color: lightblue;
padding: 10px;
border: 1px solid grey;
border-radius: 5px;
}
.space {
width: 200px;
height: 200px;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
}
.row {
display: flex;
justify-content: center;
}
h1,
h2,
p {
text-align: center;
}
.hidden {
display: none;
}
#win-container {
border: 3px solid black;
border-radius: 5px;
padding: 15px;
width: 80%;
margin-left: auto;
margin-right: auto;
}
#win-container button {
display: block;
margin-left: auto;
margin-right: auto;
}
.token {
max-width: 200px;
}
* {
cursor: url("./img/uni.cur"), pointer;
}
<meta name="author" content="Elisa" />
<link href="https://fonts.googleapis.com/css2?family=Ranchers&display=swap" rel="stylesheet">
<link href="./style.css" rel="stylesheet" />
<body>
<h1>Tic Tac Toe Time</h1>
<p>It's <span>Player 1</span> turn</p>
<div id="gameboard">
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
</div>
<div id="win-container" class="hidden">
<h2>Hello</h2>
<button id="again-btn">Play Again?</button>
</div>
<script src="index.js"></script>
</body>