shantanu rahut
shantanu rahut

Reputation: 329

How can I find clicked div element from class id using JavaScript?

I am new to JavaScript. I am trying to make a Tic-Tac-Toe with AI capabilities. Here is the full code.

const statusDisplay = document.querySelector('.game--status');

let gameActive = true;
let currentPlayer = "X";
let gameState = ["", "", "", "", "", "", "", "", ""];

let winingScores = {
    X: 10,
    O: -10,
    tie: 0
};

const winningMessage = () => `Player ${currentPlayer} has won!`;
const drawMessage = () => `Game ended in a draw!`;
const currentPlayerTurn = () => `It's ${currentPlayer}'s turn`;

statusDisplay.innerHTML = currentPlayerTurn();

const winningConditions = [
    // Horizontal wins
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    // Vertical wins
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    // Diagonal wins
    [0, 4, 8],
    [2, 4, 6]
];

function handleCellPlayed(clickedCell, clickedCellIndex) {
    gameState[clickedCellIndex] = currentPlayer;
    clickedCell.innerHTML = currentPlayer;
}

function handlePlayerChange() {
    currentPlayer = currentPlayer === "X" ? "O" : "X";
    statusDisplay.innerHTML = currentPlayerTurn();
}

function handleResultValidation() {
    let roundWon = false;
    for (let i = 0; i <= 7; i++) {
        const winCondition = winningConditions[i];
        let a = gameState[winCondition[0]];
        let b = gameState[winCondition[1]];
        let c = gameState[winCondition[2]];
        if (a === '' || b === '' || c === '') {
            continue;
        }
        if (a === b && b === c) {
            roundWon = true;
            break
        }
    }

    if (roundWon) {
        statusDisplay.innerHTML = winningMessage();
        gameActive = false;
        return;
    }

    let roundDraw = !gameState.includes("");
    if (roundDraw) {
        statusDisplay.innerHTML = drawMessage();
        gameActive = false;
        return;
    }

    handlePlayerChange();
}

function handleCellClick(clickedCellEvent) {
    if(currentPlayer === "X"){
        const clickedCell = clickedCellEvent.target;
        const clickedCellIndex = parseInt(clickedCell.getAttribute('data-cell-index'));

        if (gameState[clickedCellIndex] !== "" || !gameActive) {
            return;
        }

        handleCellPlayed(clickedCell, clickedCellIndex);
        handleResultValidation();
    }
    else{
        const clickedCellIndex = bestMoveForAI();
        const clickedCell = 

        handleCellPlayed(clickedCell, clickedCellIndex);
        handleResultValidation();
    }

}

function handleRestartGame() {
    gameActive = true;
    currentPlayer = "X";
    gameState = ["", "", "", "", "", "", "", "", ""];
    statusDisplay.innerHTML = currentPlayerTurn();
    document.querySelectorAll('.cell').forEach(cell => cell.innerHTML = "");
}

function bestMoveForAI(){
    let bestScore = -Infinity;
    let bestMove = -1;
    for(let i = 0; i < 9; i++){
        if(shadowGameState[i] === ""){
            shadowGameState[i] = "O";
            let score = minimax(gameState,0, false);
            gameState[i] = "";
            if(score > bestScore){
                bestScore = score;
                bestMove = i;
            }
        }
    }

    return bestMove;
}

function minimax(gameState, depth, isMaximizing){
    // check for AI win as "O" only
    let result = checkWinner();
    if (result !== null) {
      return winingScores[result];
    }

    if(isMaximizing===false){
        for(let i = 0; i < 9; i++){
            if(gameState[i] === ""){
                gameState = "O";
                let score = minimax(gameState, depth + 1, false);
                gameState = "";
                bestScore = max(score, bestScore);
            }
        }
        return bestScore;
    }
    
}

function checkWinner(){
    let winner;
    for(let i = 0; i <= 7; i++){
        const winCondition = winningConditions[i];
        let a = gameState[winCondition[0]];
        let b = gameState[winCondition[1]];
        let c = gameState[winCondition[2]];
        if(a === '' || b === '' || c === ''){
            continue;
        }
        if(a === b && b === c){
            winner = a;
            break;
        }
    }
    return winner;
}

document.querySelectorAll('.cell').forEach(cell => cell.addEventListener('click', handleCellClick));
document.querySelector('.game--restart').addEventListener('click', handleRestartGame);

Human player (in this case first player with "X") can click a cell and javascript update the value of the game state and the cell in question.

For AI player's (in this case second player with "O") move, I am finding the best move and then updating the game state accordingly. But I don't know how to update the cell according to the best move.

Can anyone please help me ?

This is the function I am stuck at:

function handleCellClick(clickedCellEvent) {
if(currentPlayer === "X"){
    const clickedCell = clickedCellEvent.target;
    const clickedCellIndex = parseInt(clickedCell.getAttribute('data-cell-index'));

    if (gameState[clickedCellIndex] !== "" || !gameActive) {
        return;
    }

    handleCellPlayed(clickedCell, clickedCellIndex);
    handleResultValidation();
}
else{
    const clickedCellIndex = bestMoveForAI();
    const clickedCell = // how to find the clickedCell based on clickedCellIndex ?

    handleCellPlayed(clickedCell, clickedCellIndex);
    handleResultValidation();
}}

I know the index of clickedCell. I want to find the clickedCell , so that I can show "O" in the clickedCell.

Upvotes: 0

Views: 131

Answers (1)

Edy Bourne
Edy Bourne

Reputation: 6187

You can query elements by the attribute. For example, for index 0, you could:

const clickedCell = document.querySelector('[data-cell-index="0"]');

Or in your case:

const clickedCell = document.querySelector(`[data-cell-index="${clickedCellIndex}"]`);

Upvotes: 1

Related Questions