TicTactoe using javascript minmax algorithm

41 Views Asked by At

There's a function called "table" that creates a clickable table, where the clicked values are stored in a variable called "board". After initializing the "board", another matrix called "a" is created with values {0,1,2,3,4,5,6,7,8}. The "getlines" function checks all possible winning combinations in rows, columns, and diagonals. The problem is with the "checkWinner3()", "minimax()", and "computermovedifficult()" functions. In these functions:

Every move results in a score of -Infinity. Only the first 'O' is written on the board, and subsequent 'O's are not written.

let winner = null;
           let wins = 0;
         let turn = "X";
           let board = initializeBoard(3);
           function generateTable() {
           const table = document.getElementById("board");
           table.innerHTML = "";
           // Generate rows and cells based on the matrix size
           for (let i = 0; i < 3; i++) {
                      const row = document.createElement("tr");
                      for (let j = 0; j < 3; j++) {
                                 const cell = document.createElement("td");
                                 cell.setAttribute(
                                            "onclick",
                                            `cellClick(${i * 3 + j})`,
                                 );
                                 row.appendChild(cell);
                      }
                      table.appendChild(row);
           }}

         generateTable();
         function initializeBoard() {
           let board = [];
           for (let i = 0; i <= 9; i++) {
                      board.push(null);
           }
           return board;}
          console.log(board);
         let lines1 = [[]];
          function getlines(a) {
           let ijk = 3 - 2;
           for (let i = 0; i < 3; i++) {
                      for (let j = 0; j < 3; j++) {
                                 if (j < ijk) {
                                            if (
                                                       isValidIndex(a, i, j) &&
                                                       isValidIndex(
                                                                  a,
                                                                  i,
                                                                  j + 1,
                                                       ) &&
                                                       isValidIndex(a, i, j + 2)
                                            ) {
                                                       lines1.push([
                                                                  a[i][j],
                                                                  a[i][j + 1],
                                                                  a[i][j + 2],
                                                       ]);
                                            }
                                 }
                                 if (i < ijk) {
                                            if (
                                                       isValidIndex(a, i, j) &&
                                                       isValidIndex(
                                                                  a,
                                                                  i + 1,
                                                                  j,
                                                       ) &&
                                                       isValidIndex(a, i + 2, j)
                                            ) {
                                                       lines1.push([
                                                                  a[i][j],
                                                                  a[i + 1][j],
                                                                  a[i + 2][j],
                                                       ]);
                                            }
                                 }
                                 // for left diagonal
                                 if (i < ijk && j < ijk) {
                                            if (
                                                       isValidIndex(a, i, j) &&
                                                       isValidIndex(
                                                                  a,
                                                                  i + 1,
                                                                  j + 1,
                                                       ) &&
                                                       isValidIndex(
                                                                  a,
                                                                  i + 2,
                                                                  j + 2,
                                                       )
                                            ) {
                                                       lines1.push([
                                                                  a[i][j],
                                                                  a[i + 1][
                                                                             j +
                                                                                        1
                                                                  ],
                                                                  a[i + 2][
                                                                             j +
                                                                                        2
                                                                  ],
                                                       ]);
                                            }
                                 }
                                 //   for right diagonal
                                 if (i < ijk && j >= 2) {
                                            if (
                                                       isValidIndex(a, i, j) &&
                                                       isValidIndex(
                                                                  a,
                                                                  i + 1,
                                                                  j - 1,
                                                       ) &&
                                                       isValidIndex(
                                                                  a,
                                                                  i + 2,
                                                                  j - 2,
                                                       )
                                            ) {
                                                       lines1.push([
                                                                  a[i][j],
                                                                  a[i + 1][
                                                                             j -
                                                                                        1
                                                                  ],
                                                                  a[i + 2][
                                                                             j -
                                                                                        2
                                                                  ],
                                                       ]);
                                            }
                                 }
                                 lines1 = lines1.filter((arr) => arr.length > 0);
                      }
           }
           return lines1;
                  }
            function isValidIndex(array, row, col) {
           return (
                      row >= 0 &&
                      row < array.length &&
                      col >= 0 &&
                      col < array[row].length
           );
              }
          function generateMatrixWin(matrixSize) {
           let matrix = [];
           let count = 0;
           // Create the matrix
           for (let i = 0; i < 3; i++) {
                      let row = [];
                      for (let j = 0; j < 3; j++) {
                                 row.push(count);
                                 count++;
                      }
                      matrix.push(row);
           }
           return matrix;
                        }
          // Test the function with a matrix size of 5
           let resultMatrix = generateMatrixWin(3);
           let a = generateMatrixWin(3);
           // Print the result matrix
         for (let i = 0; i < resultMatrix.length; i++) {
           console.log(a[i].join("\t"));
              }
            function checkWinner3() {
           lines = getlines(a);
           // Iterate through rows
           for (let i = 0; i < lines.length; i++) {
                      const [a, b, c] = lines[i];
                      if (
                                 board[a] &&
                                 board[a] === board[b] &&
                                 board[a] === board[c]
                      ) {
                                 console.log(board[a]);
                                 return board[a];
                      }
           }
           for (let i = 0; i < 9; i++) {
                      if (!board[i]) {
                                 return null;
                      }
           }
           return "draw";
            }
            function printBoard() {
           const table = document.getElementById("board");
           for (let i = 0; i < 9; i++) {
                      const row = Math.floor(i / 3);
                      const col = i % 3;
                      table.rows[row].cells[col].textContent = board[i];
           }
               }
               function cellClick(index) {
           if (!winner && !board[index]) {
                      board[index] = turn;
                      printBoard();
                      winner = checkWinner3();
                      if (winner) {
                                 if (winner === "draw") {
                                            document.getElementById(
                                                       "result",
                                            ).textContent =
                                                       "It's a draw! Thanks for playing.";
                                 } else {
                                            document.getElementById(
                                                       "result",
                                            ).textContent =
                                                       `Congratulations! ${winner} have won! Thanks  for playing.`;
                                 }
                      } else {
                                 turn =
                                            turn === "X"
                                                       ? computermovedifficult()
                                                       : "X";
                      }
           }
                                  }
                                //   }
                 function computermoveeasy() {
           const table = document.getElementById("board");
           do {
                      index = Math.floor(Math.random() * board.length);
           } while (board[index] !== null);
           board[index] = "O"; // Place the computer's move at the randomly generated index
           for (let i = 0; i <= 9; i++) {
                      const row = Math.floor(i / 3);
                      const col = i % 3;
                      table.rows[row].cells[col].textContent = board[i];
           }
           turn = "X";
           lines = getlines(a);
           // Iterate through rows
           for (let i = 0; i < lines.length; i++) {
                      const [a, b, c] = lines[i];
                      if (
                                 board[a] &&
                                 board[a] === board[b] &&
                                 board[a] === board[c]
                      ) {
                                 console.log("WINS" + board[a]);
                            document.getElementById("result").textContent =
                                 `Congratulations! ${board[a]} have won! Thanks for                      playing.`;
                                 return board[a];
                      }
           }
                 }
          function computermovedifficult() {
           let bestScore = -Infinity;
           let bestMove = null;
           const table = document.getElementById("board");
           for (let index = 0; index < 9; index++) {
                      //   if (board[index] === null) {
                      if (
                                 board[index] === null ||
                                 board[index] === undefined ||
                                 board[index] === ""
                      ) {
                                 board[index] = "O";
                                 let score = minimax(board, 0, false);
                                 board[index] = ""; // Undo the move
                                 console.log(`Move: ${index}, Score: ${score}`);
                                 if (score > bestScore) {
                                            bestScore = score;
                                            bestMove = index;
                                 }
                      }
           }
           board[bestMove] = "O"; // Update the board with the best move
           console.log("Best Move:", bestMove); // Log the best move for debugging
           console.log("Best Score:", bestScore); // Log the best score for debugging
           console.log("Updated Board:", board); // Log the updated board array for debugging
           turn = "X";
           return turn;
             }
        function minimax(board, depth, isMaximizing) {
           lines = getlines(a);
           // Iterate through rows
           for (let i = 0; i < lines.length; i++) {
                      const [a, b, c] = lines[i];
                      for (let i = 0; i < 9; i++) {
                                 if (!board[i]) {
                                            result = null;
                                 }
                      }
                      result = "draw";
                      if (
                                 board[a] &&
                                 board[a] === board[b] &&
                                 board[a] === board[c]
                      ) {
                                 console.log(board[a]);
                                 result = board[a];
                      }
           }
           if (result !== null) {
                      // Adjust scores based on the result
                      if (result === "draw") {
                                 console.log("draw");
                                 return 0;
                      } else if (result === "O") {
                                 return 10 - depth;
                      } else if (result === "X") {
                                 return depth - 10;
                      }
           }
           if (depth >= 5) {
                      return 0; // Return 0 when reaching the maximum depth
           }
           if (isMaximizing) {
                      let bestScore = -Infinity;
                      for (let i = 0; i < 9; i++) {
                                 if (board[i] === "") {
                                            board[i] = "O";
                                            let score = minimax(
                                                       board,
                                                       depth + 1,
                                                       false,
                                            );
                                            board[i] = null;
                                            bestScore = Math.max(
                                                       score,
                                                       bestScore,
                                            );
                                            turn = "X";
                                 }
                      }
                      return bestScore;
           } else {
                      let bestScore = Infinity;
                      for (let i = 0; i < 9; i++) {
                                 //  ===''
                                 if (board[i] === "") {
                                            board[i] = "X";
                                            let score = minimax(
                                                       board,
                                                       depth + 1,
                                                       true,
                                            );
                                            board[i] = null;
                                            bestScore = Math.min(
                                                       score,
                                                       bestScore,
                                            );
                                            turn = "O";
                                 }
                      }
                      return bestScore;
           }
                 }
body, html {  height: 100%;
            margin: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction:column; }
        table {  border-collapse: collapse; }
        td {    border: 1px solid black;
            width: 50px;
            height: 50px;
            text-align: center;
            font-size: 20px; }

    
        .result {
            margin-top: 50px;
            font-size: 1.5em;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.4.2/d3.min.js"></script>
         <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

     <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tic Tac Toe</title>
     </head>

      <body>
    <h1>Tic Tac Toe</h1> <br>
    <table id="board"> </table>
    <div id="result" class="result"></div>
       </body>

        <!-- language: css -->    
 
     .result {
         margin-top: 50px;
       font-size: 1.5em;
         }


      <!-- end snippet -->

      <!-- language: html -->     
         <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.4.2/d3.min.js"></script>
         <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

     <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tic Tac Toe</title>
     </head>

      <body>
    <h1>Tic Tac Toe</h1> <br>
    <table id="board"> </table>
    <div id="result" class="result"></div>
       </body>



      <!-- end snippet -->
0

There are 0 best solutions below