useEffect 在井字游戏中无法正常工作

时间:2021-03-31 11:35:15

标签: javascript reactjs react-hooks

所以我有一个基本的井字游戏对抗一个假 AI,因为它只使用 Math.random()。游戏有5回合,问题是AI在回合结束后移动,如果有平局,这会导致崩溃,因为AI无处可移动。

您可以在这里播放以见证错误:https://absolutezero13.github.io/tictactoe/

让我给你看代码;

 const [squares, setSquares] = useState(new Array(9).fill(""));
  const [activePlayer, setActivePlayer] = useState("Player 1");
  const [roundWinner, setRoundWinner] = useState<any>("");
  const [roundNumber, setRoundNumber] = useState(1);
  const [player1Score, setPlayer1Score] = useState(0);
  const [player2Score, setPlayer2Score] = useState(0);
  const [gameWinner, setGameWinner] = useState<string>("");
  const [isDraw, setIsDraw] = useState<boolean>(false);

  // GAME END
  useEffect(() => {
    if (player2Score >= 3 || player1Score >= 3) {
      player1Score > player2Score
        ? setGameWinner("Player 1")
        : setGameWinner("Player 2");
    }
  }, [roundWinner]);

  // Recursive AI move

  useEffect(() => {
    console.log(roundWinner);
    const aiMove = (): any => {
      if (activePlayer === "Player 2" && !roundWinner && !isDraw) {
        const randomNum = Math.floor(Math.random() * 9);

        if (squares[randomNum] === "") {
          squares[randomNum] = "O";
          setActivePlayer("Player 1");
        } else {
          aiMove();
        }
      }
    };
    setTimeout(() => aiMove(), 500);
  }, [activePlayer]);

  // NEXT ROUND

  useEffect(() => {
    console.log(roundWinner);
    if (roundWinner && !gameWinner && player2Score < 3 && player1Score < 3) {
      setTimeout(() => {
        setRoundNumber((prevNum) => prevNum + 1);
        reset();
      }, 2000);
    }
  }, [roundWinner]);

  // ROUND END

  useEffect(() => {
    const xOrO = isRoundOver(squares);

    if (xOrO && !roundWinner && !gameWinner) {
      if (xOrO === "X") {
        setPlayer1Score((prevScore) => prevScore + 1);
      }
      if (xOrO === "O") {
        setPlayer2Score((prevScore) => prevScore + 1);
      }
      setRoundWinner(xOrO);
    }
  }, [activePlayer]);

  // DRAW

  useEffect(() => {
    if (squares.indexOf("") === -1 && !roundWinner) {
      setIsDraw(true);
      setTimeout(() => {
        reset();
      }, 2000);
    }
  }, [squares]);

  //CLİCK FUNC

  const clickSquare = (id: number): void => {
    if (
      !squares[id] &&
      !roundWinner &&
      !gameWinner &&
      activePlayer === "Player 1"
    ) {
      setSquares((prevSquares) => {
        return prevSquares.map((square, i) => {
          if (i === id) {
            square = "X";
          }
          return square;
        });
      });
      setActivePlayer("Player 2");
    }
  };

  // ROUND RESET

  const reset = () => {
    setRoundWinner("");
    setSquares(new Array(9).fill(""));
    setActivePlayer("Player 1");
    setIsDraw(false);
  };

  // GAME RESET

  const newGame = () => {
    reset();
    setRoundNumber(1);
    setPlayer1Score(0);
    setPlayer2Score(0);
    setGameWinner("");
  };

这是 Board.tsx 组件,如您所见,当没有 roundWinner 或没有平局时 AI 应该移动。所以假设我赢了,它仍然会移动并将 O 放在某个方格上。根据这个 useEffect 它不应该这样做。我有点一团糟,所以我明白这是否太过分了..

0 个答案:

没有答案