MInimax function not working properly in next js

29 Views Asked by At

SO i wrote this code in next js. For some reason, it is not working properly. I've tried almost everything but still it's not working properly. I even tried using alpha beta pruning but it still isn't working at all. All it does is return the value on sequential order. Like if the places 0,1,2,3,4 are available bot will play 0 and then 1 and 2 and so on. Help me fix it.

"use client";
import React, { useState, useEffect } from "react";
import "./GameMenu.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faRefresh } from "@fortawesome/free-solid-svg-icons/faRefresh";
import WonScreen from "./WonScreen";
import { Tooltip } from "react-tooltip";

const GameMenu = () => {
  type board = {
    [key: number]: string;
  };

  const defaultBoard: board = {
    0: "",
    1: "",
    2: "",
    3: "",
    4: "",
    5: "",
    6: "",
    7: "",
    8: "",
  };

  const [turn, setTurn] = useState<"human" | "bot">("human");
  const [won, setWon] = useState(false);
  const [boardData, setBoardData] = useState<board>(defaultBoard);
  const ai = "O";
  const human = "X";
  const [tries, setTries] = useState(0);

  const winCondition = [
    [0, 1, 2],
    [0, 4, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [3, 4, 5],
    [2, 4, 6],
    [6, 7, 8],
  ];

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

  const updateBoardData = (idx: keyof board) => {
    if (won || boardData[idx] !== "") return;
    setTurn("bot");

    setTries(tries + 1);
    setBoardData({ ...boardData, [idx]: "X" });
  };

  useEffect(() => {
    if (tries < 9 && turn === "bot") {
      findBestMove();
    }
  }, [boardData, tries, turn]);

  const checkWinner = (board: board) => {
    let winner = null;
    winCondition.forEach((bd) => {
      const [a, b, c] = bd;

      if (board[a] && board[a] === board[b] && board[a] === board[c]) {
        winner = board[a];
      }
      for (let i = 0; i < 3; i++) {
        if (board[i] !== "" && board[i + 3] !== "" && board[i + 6] !== "") {
          winner = "tie";
        }
      }
    });
    return winner;
  };

  useEffect(() => {
    let win = checkWinner(boardData);
    if (win == "X" || win == "O") {
      setWon(true);
    }
  }, [boardData]);

  const restart = () => {
    setBoardData(defaultBoard);
    setWon(false);
    setTries(0);
    setTurn("human");
  };
  const minimax = (board: board, isMaximizing: boolean): number => {
    const result = checkWinner(board);

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

    let bestScore = isMaximizing ? -Infinity : Infinity;

    for (let i = 0; i < Object.keys(board).length; i++) {
      if (board[i] === "") {
        board[i] = isMaximizing ? ai : human;

        const score = minimax(board, !isMaximizing);
        console.log(score);
        board[i] = ""; // Reset the board for the next iteration

        if (isMaximizing) {
          bestScore = Math.max(score, bestScore);
        } else {
          bestScore = Math.min(score, bestScore);
        }
      }
    }

    return bestScore;
  };

  const findBestMove = () => {
    let bestMove = -Infinity;
    let move;
    const board = { ...boardData };

    for (let i = 0; i < Object.keys(board).length; i++) {
      if (board[i] === "") {
        board[i] = ai;
        const score = minimax(board, false);
        board[i] = "";
        if (score > bestMove) {
          bestMove = score;
          move = i;
        }
      }
    }

    const updatedBoard = { ...boardData, [move]: ai };
    setTurn("human");
    setBoardData(updatedBoard);
    setTries(tries + 1);
  };

Result is not accurate

1

There are 1 best solutions below

0
Coder4689 On

Minimax algo is used to play computer games. Maybe you should try minimizing the value of that variable called best move and then you'll be able to get the correct answer.And maybe you're asking the human to make the first move. That could very well be the problem too.