having issues implementing minimax code, the other codes I came across seemed hard to grasp, can someone tell me how to integrate algorithm into my app? I tried creating board for empty spaces define human/computer function, run the code on the turn fun, but yeah I created a hot mess, and used my git log to rewind, heres my code
I low key feel the issue lies in the structure of my app manifested in the lack of board variable, emptyspaces functions, minimax logic , or in the way I am integrating my logic with my other functions ,
const x_class = "x";
const circle_class = "circle";
const cellElement = document.querySelectorAll("[data-cell]");
const winningMessageElement = document.getElementById("winningMessage");
const winningCombination = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
const board = document.getElementById("board");
let circleTurn;
const winningTextMessageElement = document.querySelector(
"[data-winning-message-text]"
);
const reStartButton = document.getElementById("restartButton");
const optionX = document.getElementById("optionx");
const optionO = document.getElementById("optiono");
const submitBtn = document.getElementById("submitButton");
const selection_X = document.getElementById("xOption");
const selection_O = document.getElementById("oOption");
const startForm = document.getElementById("startForm");
optionX.addEventListener("click", optionHandler);
optionO.addEventListener("click", optionHandler);
submitBtn.addEventListener("click", submitHandler);
reStartButton.addEventListener("click", startGame);
function optionHandler(e) {
optionX.classList.remove("optionButtonStyle2");
optionX.classList.add("optionButtonStyle");
optionO.classList.remove("optionButtonStyle2");
optionO.classList.add("optionButtonStyle");
e.currentTarget.classList.remove("optionButtonStyle");
e.currentTarget.classList.add("optionButtonStyle2");
}
function submitHandler(e) {
e.preventDefault();
if (selection_O.checked) {
circleTurn = true;
startForm.classList.add("hide");
board.classList.add("show");
} else if (selection_X.checked) {
circleTurn = false;
startForm.classList.add("hide");
board.classList.add("show");
} else {
alert("please select an option");
}
startGame();
}
function startGame() {
cellElement.forEach((cell) => {
cell.classList.remove(x_class);
cell.classList.remove(circle_class);
cell.removeEventListener("click", handleClick);
cell.addEventListener("click", handleClick, { once: true });
});
setBoardHoverClass();
winningMessageElement.classList.remove("show");
}
function handleClick(e) {
const cell = e.target;
const currentClass = circleTurn ? circle_class : x_class;
placeMark(cell, currentClass);
if (checkWin(currentClass)) {
endGame(false);
} else if (isDraw()) {
endGame(true);
} else {
swapTurns();
setBoardHoverClass();
}
}
function isDraw() {
return [...cellElement].every((cell) => {
return (
cell.classList.contains(x_class) || cell.classList.contains(circle_class)
);
});
}
function endGame(draw) {
if (draw) {
winningTextMessageElement.innerText = "Tie!";
} else {
winningTextMessageElement.innerText = `${circleTurn ? "O's" : "X's"} Win!`;
}
winningMessageElement.classList.add("show");
}
function placeMark(cell, currentClass) {
cell.classList.add(currentClass);
}
function swapTurns() {
circleTurn = !circleTurn;
}
function setBoardHoverClass() {
board.classList.remove(x_class);
board.classList.remove(circle_class);
if (circleTurn) {
board.classList.add(circle_class);
} else {
board.classList.add(x_class);
}
}
function checkWin(currentClass) {
return winningCombination.some((combination) => {
return combination.every((index) => {
return cellElement[index].classList.contains(currentClass);
});
});
}
*,
*::after,
*::before {
box-sizing: border-box;
}
:root {
--cell-size: 100px;
--mark-size: calc(var(--cell-size) * 0.9);
}
body {
margin: 0;
}
.formStyle {
background-color: rgb(236, 226, 221);
max-width: 30%;
min-height: 50vh;
}
.hide {
display: none;
}
.headerStyle {
color: #10213b !important;
}
.optionButtonStyle {
background-color: #10213b !important;
padding: 10px 70px !important;
color: white !important;
}
.optionButtonStyle:hover {
background-color: #183867 !important;
}
.submitButton {
background-color: #10213b !important;
padding: 10px 30px !important;
}
.submitButton:hover {
background-color: #183867 !important;
padding: 10px 30px !important;
}
.optionButtonStyle2 {
background-color: orange !important;
padding: 10px 70px !important;
color: #183867 !important;
font-weight: 400 !important;
}
.boardStyle {
background-image: linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)),
url("image/tic-tac-toe_1706536926613.jpg");
max-width: 100%;
height: 100vh;
background-size: cover;
background-position: top left;
padding: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.board {
display: /*grid;*/ none;
justify-content: center;
align-content: center;
justify-items: center;
align-items: center;
grid-template-columns: repeat(3, auto);
}
.show {
display: grid;
}
.cell {
position: relative;
min-width: var(--cell-size);
height: var(--cell-size);
border: 1px solid white;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.cell:first-child,
.cell:nth-child(2),
.cell:nth-child(3) {
border-top: none;
}
.cell:first-child,
.cell:nth-child(4),
.cell:nth-child(7) {
border-left: none;
}
.cell:nth-child(3),
.cell:nth-child(6),
.cell:nth-child(9) {
border-right: none;
}
.cell:nth-child(7),
.cell:nth-child(8),
.cell:nth-child(9) {
border-bottom: none;
}
.cell.x::before,
.cell.x::after,
.cell.circle::before,
.cell.circle::after {
background-color: pink;
}
.board.x .cell:not(.x):not(.circle):hover::before,
.board.x .cell:not(.x):not(.circle):hover::after,
.board.circle .cell:not(.x):not(.circle):hover::before,
.board.circle .cell:not(.x):not(.circle):hover::after {
background-color: pink;
}
.cell.x::before,
.cell.x::after,
.board.x .cell:not(.x):not(.circle):hover::before,
.board.x .cell:not(.x):not(.circle):hover::after {
content: "";
position: absolute;
width: calc(var(--mark-size) * 0.15);
height: var(--mark-size);
}
.cell.x::before,
.board.x .cell:hover::before {
transform: rotate(45deg);
}
.cell.x::after,
.board.x .cell:hover::after {
transform: rotate(-45deg);
}
.cell.circle::before,
.cell.circle::after,
.cell:not(.x):not(.circle):hover::before,
.cell:not(.x):not(.circle):hover::after {
content: "";
position: absolute;
width: var(--mark-size);
height: var(--mark-size);
border-radius: 50%;
}
.cell.circle::before,
.board.circle .cell:not(.x):not(.circle):hover::before {
width: var(--mark-size);
height: var(--mark-size);
}
.cell.circle::after,
.board.circle .cell:not(.x):not(.circle):hover::after {
width: calc(var(--mark-size) * 0.7);
height: calc(var(--mark-size) * 0.7);
background-color: /*white; #122b31;*/ #060f1d;
}
.cell.x,
.cell.circle {
cursor: not-allowed;
}
.winning-message {
display: none;
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.9);
flex-direction: column;
justify-content: center;
align-items: center;
color: pink;
font-size: 5rem;
margin: 0;
}
.winning-message button {
font-size: 3rem;
background-color: orange;
border: 1px solid black;
padding: 10px 70px; /* Combine the padding values into a single declaration */
cursor: pointer;
color: #081425;
}
.winning-message button:hover {
background-color: #081425;
color: pink;
border-color: white;
transition: background-color 0.2s ease-in, color 0.2s ease-in,
border-color 0.3s ease-in;
}
.winning-message.show {
display: flex;
}
@media screen and (min-width: 900px) and (max-width: 1379px) {
.formStyle {
background-color: rgb(236, 226, 221);
max-width: 50%;
min-height: 45vh;
}
.submitButton {
background-color: #10213b !important;
margin-bottom: 10px;
padding-top: 10px;
}
.optionButtonStyle {
margin-bottom: 10px;
}
.optionButtonStyle2 {
margin-bottom: 10px;
}
}
@media screen and (min-width: 500px) and (max-width: 899px) {
.formStyle {
background-color: rgb(236, 226, 221);
max-width: 80%;
min-height: 45vh;
overflow: none;
}
.submitButton {
background-color: #10213b !important;
margin-bottom: 10px;
padding-top: 10px;
}
.optionButtonStyle {
margin-bottom: 10px;
}
.optionButtonStyle2 {
margin-bottom: 10px;
}
}
@media screen and (max-width: 499px) {
.formStyle {
background-color: rgb(236, 226, 221);
max-width: 90%;
min-height: 45vh;
}
.submitButton {
background-color: #10213b !important;
margin-bottom: 10px;
padding-top: 10px;
overflow: none;
}
.optionButtonStyle {
margin-bottom: 10px;
overflow: none;
}
.optionButtonStyle2 {
margin-bottom: 10px;
overflow: none;
}
:root {
--cell-size: 60px;
--mark-size: calc(var(--cell-size) * 0.9);
}
.winning-message {
display: none;
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.9);
flex-direction: column;
justify-content: center;
align-items: center;
color: pink;
font-size: 2rem;
margin: 0;
}
.winning-message button {
font-size: 1rem;
background-color: orange;
border: 1px solid black;
padding: 10px 70px; /* Combine the padding values into a single declaration */
cursor: pointer;
color: #081425;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tic Tac Toe</title>
<link rel="stylesheet" href="style.css" />
<script defer src="main.js"></script>
<link
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
crossorigin="anonymous"
/>
</head>
<body>
<div class="boardStyle container-fluid">
<div class="formStyle" id="startForm">
<h1 class="text-center display-1 fw-medium headerStyle">Tic Tac Toe</h1>
<form action="" class="text-center">
<h2 class="text-center my-4 headerStyle">Choose a Symbol:</h2>
<div class="mt-4">
<label
class="btn rounded-0 btn-lg optionButtonStyle mx-3"
id="optionx"
>
<input
type="radio"
name="option"
id="xOption"
value="x"
class="visually-hidden"
/>
<span class="fw-medium display-6">X</span>
</label>
<label
class="btn rounded-0 btn-lg optionButtonStyle mx-3"
id="optiono"
>
<input
type="radio"
name="option"
id="oOption"
value="o"
class="visually-hidden"
/>
<span class="fw-medium display-6">O</span>
</label>
</div>
<button
class="btn btn-lg text-center rounded-0 text-white submitButton mt-5"
id="submitButton"
>
Start Game
</button>
</form>
</div>
<div class="board" id="board">
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
</div>
<div class="winning-message" id="winningMessage">
<div data-winning-message-text></div>
<button class="btn btn-lg rounded-0" id="restartButton">Restart</button>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
crossorigin="anonymous"
></script>
</body>
</html>