I have created a Tic Tac Toe game (Noughts and Crosses in the UK!) and have finished almost everything except perhaps improving the computer AI (its just random at the moment).
However, there is one bug that I can't seem to fix. When you first play the game you get the choice of playing against another human (player 2) or computer. Once this "human" or "computer" button is pressed it will save the information in a variable "let choiceComp" as either "human" or "comp". This will then call their respective functions, computerGame() or humanGame(), once the player enters their details and the subsequent start button is pressed.
This works fine the first time around but when the reset button is pressed and the alternative game mode is selected (e.g. human first, then computer second - or vice versa), the same game mode will continue as the first time. I've reset the choiceComp variable as an empty string, along with everything else I can think of, but this doesn't reset the game mode. Just wondering if someone can help me. I've added everything I can think of into the reset button but there is still something that I am missing, but I cannot figure out what.
Here is my HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Noughts & Crosses</title>
<link rel="stylesheet" href="styles.css" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Black+Ops+One&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
<script src="script.js" defer></script>
</head>
<body>
<div class="outer-container">
<div class="title-container">
<img src="noughts.PNG" alt="noughts-image">
<h1 class="title">NOUGHTS & CROSSES</h1>
<img src="crosses.PNG" alt="crosses-image">
</div>
<button class="reset-button">Reset</button>
<div class="container">
<div id="0" class="square"></div>
<div id="1" class="square"></div>
<div id="2" class="square"></div>
<div id="3" class="square"></div>
<div id="4" class="square"></div>
<div id="5" class="square"></div>
<div id="6" class="square"></div>
<div id="7" class="square"></div>
<div id="8" class="square"></div>
</div>
<div>
<div>
<div class="display"></div>
<div class="display2"></div>
<div>
<div class="display-images-container">
<img class="player1-display-pic" src="player1.PNG" alt="player1-image">
<img class="player2-display-pic" src="player2.PNG" alt="player2-image">
<img class="comp-display-pic" class="computer-button" src="computer.PNG" alt="computer-image">
</div>
</div>
</div>
<div class="human-or-comp-container">
<div class="human-or-comp-title">Play against Human or Computer?</div>
<div class="image-container">
<img class="human-button" src="human.PNG" alt="human-image">
<img class="computer-button" src="computer.PNG" alt="computer-image">
</div>
</div>
</div>
<form>
<div class="input-container">
<div class="player-input-container" id="player-one-form">
<p>Player One</p>
<div class="player-image-container">
<img src="player1.PNG" alt="player1-image">
</div>
<input type="text" id="nameOne" placeholder="Player 1" />
<div class="radio-buttons-container">
<label for="radio">Selection</label>
<input type="radio" name="typeSelectOne" id="noughtsOne" value="0"></input>
<label for="noughtsOne">0's</label>
<input type="radio" name="typeSelectOne" id="crossesOne" value="X"></input>
<label for="crossesOne">X's</label>
</div>
</div>
<div class="player-input-container" id="player-two-form">
<p>Player Two</p>
<div class="player-image-container">
<img src="player2.PNG" alt="player2-image">
</div>
<div>
<input type="text" id="nameTwo" placeholder="Player 2" />
</div>
</div>
<div class="player-input-container" id="computer-form">
<p>Computer</p>
<div class="computerForm">
<img class="computer-button" src="computer.PNG" alt="computer-image">
</div>
</div>
</div>
<div class="button-container">
<button class="start-button" type="start" id="start-button">Start</button>
</div>
</form>
</div>
</div>
</body>
</html>
My JS
const container = document.querySelector(".container");
const squares = document.querySelectorAll(".square");
const playerOneName = document.querySelector("#nameOne");
const playerTwoName = document.querySelector("#nameTwo");
const startButton = document.querySelector("#start-button");
const display = document.querySelector(".display");
const display2 = document.querySelector(".display2");
const inputContainer = document.querySelector(".input-container");
const noughtsSymbol = document.getElementById("noughts");
const humanOrComp = document.querySelector(".human-or-comp-container");
const playerOneForm = document.querySelector("#player-one-form");
const playerTwoForm = document.querySelector("#player-two-form");
const computerForm = document.querySelector("#computer-form");
const resetButton = document.querySelector(".reset-button");
const playerOnePic = document.querySelector(".player1-display-pic");
const playerTwoPic = document.querySelector(".player2-display-pic");
const compPic = document.querySelector(".comp-display-pic");
const humanButton = document.querySelector(".human-button");
const computerButton = document.querySelector(".computer-button");
// Create Player Object (Factory)humanOrComp
function createPlayer(name, type) {
const newPlayer = {};
newPlayer.name = name;
newPlayer.type = type;
return newPlayer;
}
let playerOne;
let playerTwo;
let player;
// GameBoard (IIFE Module)
const GameBoard = (function () {
const gameBoardArr = ["", "", "", "", "", "", "", "", ""];
let squareID = "";
const computerGame = function () {
squares.forEach((square) => {
square.addEventListener("click", (event) => {
if (square.innerText === "") {
player = playerOne.type;
square.innerText = playerOne.type;
squareID = event.target.id;
gameBoardArr[squareID] = playerOne.type;
computerAI();
winner();
}
});
});
};
const humanGame = function () {
let turn = 0;
squares.forEach((square) => {
square.addEventListener("click", (event) => {
if (turn == 0 && square.innerText === "") {
player = playerOne.type;
square.innerText = playerOne.type;
squareID = event.target.id;
gameBoardArr[squareID] = playerOne.type;
turn = 1;
winner();
display2.innerText = `${playerTwo.name}'s turn`;
} else if (turn === 1 && square.innerText === "") {
player = playerTwo.type;
square.innerText = playerTwo.type;
squareID = event.target.id;
gameBoardArr[squareID] = playerTwo.type;
turn = 0;
winner();
display2.innerText = `${playerOne.name}'s turn`;
}
});
});
};
let choiceComp = "";
humanButton.addEventListener("click", () => {
choiceComp = "human";
inputContainer.style.display = "flex";
humanOrComp.style.display = "none";
playerOneForm.style.display = "flex";
playerTwoForm.style.display = "flex";
startButton.style.display = "block";
});
computerButton.addEventListener("click", () => {
choiceComp = "comp";
inputContainer.style.display = "flex";
humanOrComp.style.display = "none";
playerOneForm.style.display = "flex";
computerForm.style.display = "flex";
startButton.style.display = "block";
});
startButton.addEventListener("click", (event) => {
event.preventDefault();
playerOne = createPlayer(playerOneName.value, document.querySelector(`input[name="typeSelectOne"]:checked`).value);
playerTwo = createPlayer(playerTwoName.value, playerOne.type === "X" ? "0" : "X");
container.style.display = "grid";
resetButton.style.display = "block";
display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;
if (choiceComp === "human") {
playerOnePic.style.display = "block";
playerTwoPic.style.display = "block";
display2.innerText = `${playerOne.name}'s turn`;
humanGame();
} else if (choiceComp === "comp") {
playerTwo.name = "Computer";
display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;
playerOnePic.style.display = "block";
compPic.style.display = "block";
computerGame();
}
inputContainer.style.display = "none";
startButton.style.display = "none";
});
resetButton.addEventListener("click", () => {
playerOne = {};
playerTwo = {};
GameBoard.gameBoardArr = ["", "", "", "", "", "", "", "", ""];
display.innerText = "";
display2.innerText = "";
clearBoard();
container.style.display = "none";
playerOneForm.style.display = "none";
playerTwoForm.style.display = "none";
computerForm.style.display = "none";
humanOrComp.style.display = "flex";
playerOneName.value = "";
playerTwoName.value = "";
choiceComp = "";
resetButton.style.display = "none";
playerOnePic.style.display = "none";
playerTwoPic.style.display = "none";
compPic.style.display = "none";
});
const computerAI = function () {
const emptySquares = [];
for (let i = 0; i < gameBoardArr.length; i++) {
if (gameBoardArr[i] === "") {
emptySquares.push(i);
}
}
if (emptySquares.length > 0) {
const randomIndex = Math.floor(Math.random() * emptySquares.length);
const squareID = emptySquares[randomIndex];
document.getElementById(squareID).innerText = playerTwo.type;
gameBoardArr[squareID] = playerTwo.type;
}
};
const winner = function () {
const winnerLines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
let isDraw = true;
for (const line of winnerLines) {
const [a, b, c] = line;
if (gameBoardArr[a] === "0" && gameBoardArr[b] === "0" && gameBoardArr[c] === "0") {
setTimeout(function () {
display.innerText = `${playerOne.name} wins`;
}, 200);
setTimeout(function () {
display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;
clearBoard();
}, 3000);
isDraw = false;
} else if (gameBoardArr[a] === "X" && gameBoardArr[b] === "X" && gameBoardArr[c] === "X") {
setTimeout(function () {
display.innerText = `${playerTwo.name} wins`;
}, 200);
setTimeout(function () {
display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;
clearBoard();
}, 3000);
isDraw = false;
}
}
if (isDraw && gameBoardArr.every((el) => el !== "")) {
setTimeout(function () {
display.innerText = "Draw";
}, 200);
setTimeout(function () {
display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;
clearBoard();
}, 3000);
}
};
const clearBoard = function () {
for (let i = 0; i < gameBoardArr.length; i++) {
gameBoardArr[i] = "";
}
squares.forEach((square) => (square.innerText = ""));
};
return { gameBoardArr };
})();
And CSS
.outer-container {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.title-container {
display: flex;
align-items: center;
}
.title {
font-size: 60px;
font-family: "Black Ops One";
margin: 20px;
}
p {
font-size: 30px;
font-weight: bold;
font-family: "Black Ops One";
}
/* Main Square Grid */
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
padding: 30px 30px;
display: none;
}
.square {
border: 1px solid black;
display: flex;
align-items: center;
justify-content: center;
font-size: 80px;
font-family: "Black Ops One";
}
.square:hover {
background-color: yellow;
opacity: 0.5;
cursor: pointer;
}
/* Human or Computer Form */
.human-or-comp-container {
margin-top: 100px;
display: flex;
flex-direction: column;
}
.human-or-comp-title {
font-size: 30px;
margin-bottom: 20px;
font-family: "VT323", monospace;
}
.image-container {
display: flex;
justify-content: space-between;
}
.human-or-comp-container img {
cursor: pointer;
}
.human-or-comp-container img:hover {
width: 120px;
height: 120px;
}
img {
width: 100px;
height: 100px;
}
/* Display */
.display,
.display2 {
font-size: 30px;
font-size: 40px;
text-align: center;
margin-bottom: 20px;
font-family: "VT323", monospace;
}
.display-images-container {
display: flex;
justify-content: space-between;
}
.player1-display-pic,
.player2-display-pic,
.comp-display-pic {
display: none;
}
/* Input forms */
.input-container {
display: flex;
justify-content: space-between;
width: 600px;
margin-top: 100px;
}
.player-input-container {
display: flex;
flex-direction: column;
width: 250px;
text-align: center;
}
#player-one-form {
display: none;
}
#player-two-form {
display: none;
}
#computer-form {
display: none;
}
.button-container {
display: flex;
justify-content: center;
}
.radio-buttons-container {
display: flex;
}
input[type="text"] {
background-color: #f5f5f5;
height: 25px;
width: 90%;
padding: 2px 23px 2px 30px;
border: 1px solid grey;
border-radius: 10px;
margin-bottom: 10px;
margin-top: 20px;
}
label {
font-family: "Black Ops One";
}
#nameOne,
#nameTwo {
font-family: "VT323", monospace;
}
#nameOne::placeholder,
#nameTwo::placeholder {
font-family: "VT323", monospace;
}
.start-button,
.reset-button,
.decide-button {
display: inline-block;
outline: 0;
border: 0;
cursor: pointer;
text-decoration: none;
position: relative;
color: #000;
background: #fff;
line-height: 30px;
border-radius: 40px;
padding: 20px;
font-size: 30px;
font-weight: 600;
box-shadow: rgb(255, 198, 0) -2px -2px 0px 2px, rgb(246, 84, 174) 0px 0px 0px 4px, rgba(0, 0, 0, 0.05) 0px 0px 2px 7px;
transition: all 0.2s;
}
.start-button:hover,
.reset-button:hover,
.decide-button:hover {
box-shadow: rgb(246, 84, 174) -2px -2px 0px 2px, rgb(255, 198, 0) 0px 0px 0px 4px, rgba(0, 0, 0, 0.05) 0px 0px 2px 7px;
transform: scale(1.01);
}
.start-button {
display: none;
}
.reset-button {
display: none;
}
Via Active questions tagged javascript - Stack Overflow https://ift.tt/VZvXegw
Comments
Post a Comment