"use strict"; function initiateGame(playersInput) { const game = (function() { const mainGameDiv = document.querySelector("#main-game"); let gameboard = new Array(9); gameboard.fill(null); // ----------------- function checkWin() { const combinations = [ "123", "456", "789", "147", "258", "369", "159", "357", ]; let combinationsValidate = {}; const allEqualInArray = arr => arr.every( v => v === arr[0] ) const player = activePlayer.player; let win = false; combinations.forEach(combination => { combinationsValidate[combination] = []; combination.split('').forEach(box => { combinationsValidate[combination].push(gameboard[+box - 1] == player.marker); }) if (allEqualInArray(combinationsValidate[combination]) && combinationsValidate[combination][0]) { player.addPoint(); console.log(`${JSON.stringify({name:player.name, marker:player.marker, points:player.points})} won`); pubsub.publish("winTrue"); return; } }); if (!win) { if (gameboard.find(field => field === null) === null) { pubsub.publish("continueGame"); } else { pubsub.publish("draw"); } } } // ----------------- function addDismissivePopup(popup, popupContent) { function dismissPopup() { popup.remove(); } popup.addEventListener("click", function(event) { if (this !== event.target) return; dismissPopup(); }, false); function dismissPopupKey(event) { if (event.key.toLowerCase() == "escape") { popup.remove(); document.body.removeEventListener("keydown", dismissPopupKey); } } const dismissBtn = document.createElement("button"); dismissBtn.setAttribute("type", "button"); dismissBtn.classList.add("dismiss-button"); dismissBtn.textContent = "Dismiss"; dismissBtn.addEventListener("click", dismissPopup); document.body.addEventListener("keydown", dismissPopupKey); return dismissBtn; } function generatePopup(dismissive) { const popup = document.createElement("div"); popup.classList.add("popup"); const popupContent = document.createElement("div"); popupContent.classList.add("popup-content"); popup.append(popupContent); document.body.append(popup); if (dismissive) { const dismissBtn = addDismissivePopup(popup, popupContent); return {popup, popupContent, dismissBtn}; } return {popup, popupContent}; } function popupWin() { const {popup, popupContent, dismissBtn} = generatePopup(true); popupContent.textContent = `${activePlayer.player.name} (${activePlayer.player.marker}) won!`; popupContent.append(dismissBtn); } function popupDraw() { const {popup, popupContent, dismissBtn} = generatePopup(true); popupContent.textContent = `It's a draw!`; popupContent.append(dismissBtn); } // ----------------- function clearController() { while(mainGameDiv.lastElementChild) { mainGameDiv.lastElementChild.remove(); } } function displayController() { clearController(); let boxes = []; for (let i = 0; i < 9; i++) { let boxDiv = document.createElement("div"); boxDiv.classList.add("box"); boxDiv.setAttribute("data-id", i); boxDiv.textContent = gameboard[boxDiv.getAttribute("data-id")]; boxDiv.addEventListener("click", function(event) { changeField(boxDiv.getAttribute("data-id")); }); boxes.push(boxDiv); } boxes.forEach(box => mainGameDiv.appendChild(box)); } // ----------------- class Player { constructor(name, marker) { this.name = name; this.marker = marker; this.points = 0; } changeName(newName) { this.name = newName; } changeMarker(newMarker) { this.marker = newMarker; } addPoint() { this.points++; } } let players = { player1: new Player(playersInput.player1.name, playersInput.player1.marker), player2: new Player(playersInput.player2.name, playersInput.player2.marker), } let activePlayer = Object.create({ change() { this.player == players.player1 ? this.player = players.player2 : this.player = players.player1; }, set(player) { if (player instanceof Player) { this.player = player; } else { throw new Error("No such player exists"); } } }); // ----------------- function changeField(field) { if (gameboard[field] === null) { gameboard[field] = activePlayer.player.marker; pubsub.publish("fieldChange"); } else if (gameboard[field] === undefined) { console.warn("No such field exists"); } else { console.warn("Value already set"); } } // ----------------- pubsub.subscribe("fieldChange", displayController); pubsub.subscribe("fieldChange", checkWin); pubsub.subscribe("continueGame", () => {activePlayer.change()}); pubsub.subscribe("draw", popupDraw); pubsub.subscribe("winTrue", popupWin); pubsub.subscribe("draw", () => {gameboard.fill(null);}) pubsub.subscribe("winTrue", () => {gameboard.fill(null);}) displayController(); activePlayer.change() })(); } initiateGame( {player1: { name: "Oskar", marker: "O", }, player2: { name: "NetMan", marker: "X", }} );