I have this error in Tic tac Toe game Uncaught TypeError : Cannot read properties of undefined ( reading '0' )

63 Views Asked by At

This is my code Can anyone tell me why I have This error

Uncaught TypeError : Cannot read properties of undefined ( reading '0' )

document.addEventListener('DOMContentLoaded', function () {
  const board = document.getElementById('board');
  const resetBtn = document.getElementById('resetBtn');
  const message = document.getElementById('message');

  let currentPlayer = 'X';

  let gameActive = true;

  let boardState = ['', '', '', '', '', '', '', '', ''];

  function makeMove(index) {
    if (boardState[index] === '' && gameActive) {
      boardState[index] = currentPlayer;

      renderBoard();

      checkWinner();

      currentPlayer = currentPlayer === 'X' ? 'O' : 'X';

      if (currentPlayer === 'O' && gameActive) {
        makeComputerMove();
      }
    }
  }

  function makeComputerMove() {
    let bestScore = -Infinity;

    let bestMove;

    console.log('boardState before making moves:', boardState);

    for (let i = 0; i < boardState.length; i++) {
      if (boardState[i] === '') {
        boardState[i] = 'O';

        console.log('boardState after making move:', boardState);

        let score = minimax(boardState.slice(), 0, false); // Pass a copy of the boardState array

        boardState[i] = '';

        if (score > bestScore) {
          bestScore = score;

          bestMove = i;
        }
      }
    }

    makeMove(bestMove);
  }

  function minimax(board, depth, isMaximizing) {
    console.log('minimax called with board:', board);

    let result = checkWinner(board);

    console.log('checkWinner result:', result);

    if (result !== null) {
      return scores[result];
    }

    if (isMaximizing) {
      let bestScore = -Infinity;

      for (let i = 0; i < board.length; i++) {
        if (board[i] === '') {
          board[i] = 'O';

          let score = minimax(board.slice(), depth + 1, false);

          board[i] = '';

          bestScore = Math.max(score, bestScore);
        }
      }

      console.log('maximizing bestScore:', bestScore);

      return bestScore;
    } else {
      let bestScore = Infinity;

      for (let i = 0; i < board.length; i++) {
        if (board[i] === '') {
          board[i] = 'X';

          let score = minimax(board.slice(), depth + 1, true);

          board[i] = '';

          bestScore = Math.min(score, bestScore);
        }
      }

      console.log('minimizing bestScore:', bestScore);

      return bestScore;
    }
  }

  function checkWinner(board) {
    const winConditions = [
      [0, 1, 2],

      [3, 4, 5],

      [6, 7, 8],

      [0, 3, 6],

      [1, 4, 7],

      [2, 5, 8],

      [0, 4, 8],

      [2, 4, 6],
    ];

    for (let condition of winConditions) {
      const [a, b, c] = condition;

      if (board[a] !== '' && board[a] === board[b] && board[a] === board[c]) {
        gameActive = false;

        return board[a];
      }
    }

    if (!board.includes('')) {
      gameActive = false;

      return 'tie';
    }

    return null;
  }

  function renderBoard() {
    board.innerHTML = '';

    boardState.forEach((cell, index) => {
      const cellElement = document.createElement('div');

      cellElement.classList.add('cell');

      cellElement.innerText = cell;

      cellElement.addEventListener('click', () => makeMove(index));

      board.appendChild(cellElement);
    });
  }

  function resetBoard() {
    currentPlayer = 'X';

    gameActive = true;

    boardState = ['', '', '', '', '', '', '', '', ''];

    renderBoard();

    message.innerText = '';
  }

  resetBtn.addEventListener('click', resetBoard);

  const scores = {
    X: -10,

    O: 10,

    tie: 0,
  };

  renderBoard();
});
#board{ 
  max-width: 6.5em;
}
.cell {
  display: inline-block;
  width: 2em;
  height: 2em;
  text-align: center;
  border: thin solid blue;
  box-model: border-box;
  vertical-align: top;
  line-height: 2;
}
<div id="board">board</div>
<div id="message">message</div>
<button id="resetBtn" type="button">Start/Reset</button>

I want to make a Tic Tac Toe game playing with smart computer but I can't solve this error

Uncaught TypeError : Cannot read properties of undefined ( reading '0' )

Please help and rewrite the correct code

1

There are 1 best solutions below

0
traktor On

The question in the title is not reproducible, so this answer focuses on fixing bugs in the code to get it working.

  1. checkWinner has a parameter called board. This is a bit misleading as it takes a boardState array argument, not the board element in the DOM.

    • A quick solution is to change

       checkWinner();
      

      in makeMove to

       checkWinner(boardState);
      
  2. While checking for the best computer move, checkWinner is called with potential boardState solutions that could result in player 'X' winning rather than the computer. When this happens checkWinner clears activeGame to indicate the game is over. Consequently when the the computer does find a move to make, it doesn't get rendered because the game is flagged as over.

    • A quick solution is to insert the statement

          activeGame = true;
      

      into makeComputerMove immediately before the existing call to makeMove.

Although these changes get the game working, the code is probably best treated as a learning exercise - the first computer choice of move takes a long time to calculate and seems to hang the browser before the user's first X can be rendered, and seems to take a lot of memory garbage collection for the browser to recover and continue. It is, however, interesting :-)