簡體   English   中英

while 中的 useState 導致死循環

[英]useState in while cause infinite loop

我試圖在 React 中制作二十一點游戲。 一個機器人一開始有 2 張牌。 如果用戶站着,bots 的牌值小於 17,它應該抽上癮的牌,但程序會導致死循環。 這是我的代碼:

  const [playerCards, setPlayerCards] = useState<Card[]>([]);
  const shuffledDeck = shuffleDeck(deck);
  const [dealerCards, setDealerCards] = useState<Card[]>([]);
const shuffleDeck = (deck: Card[]): Card[] => {
  for (let i = deck.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [deck[i], deck[j]] = [deck[j], deck[i]];
  }
  return deck;
};
  const handleStand = () => {
    if (gameState === 'playing') {
      console.log(shuffledDeck[playerCards.length + dealerCards.length]);
      while(getHandValue(dealerCards) < 17) {
        setDealerCards([
          ...dealerCards,
          shuffledDeck[playerCards.length + dealerCards.length],
        ]);
      }
    }
    let dealerHandValue = getHandValue(dealerCards);
    const playerHandValue = getHandValue(playerCards);
    if (dealerHandValue > 21 || dealerHandValue < playerHandValue) {
      setGameState('won');
      setPlayerBalance(playerBalance + currentBet);
    } else if (dealerHandValue > playerHandValue) {
      setGameState('lost');
      setPlayerBalance(playerBalance - currentBet);
    } else {
      setGameState('tied');
    }
  };
const getHandValue = (cards: Card[]): number => {
  let value = 0;
  let numAces = 0;
  for (const card of cards) {
    if (card.rank === Rank.Ace) {
      numAces++;
    } else if (card.rank === 'J' || card.rank === 'K' || card.rank === 'Q') {
      value += 10;
    } else {
      value += Number(card.rank);
    }
  }
  while (numAces > 0) {
    if (value + 11 > 21) {
      value += 1;
    } else {
      value += 11;
    }
    numAces--;
  }
  return value;
};

目標是讓機器人抽一張牌,直到他的牌的價值至少達到 17。

正如評論中所討論的,在while循環中使用setDealerCards可能會出現問題。 設置狀態會導致重新渲染組件,並可能根據其使用情況再次觸發該功能。 另一個問題可能是,由於 React 會安排它的更新,所以每次在while循環中再次設置狀態時,您可能無法獲得最新的狀態。

所以這可能有幫助

  const handleStand = () => {
    let newDealerCards = [...dealerCards];
    if (gameState === 'playing') {
      while(getHandValue(newDealerCards) < 17) {
             newDealerCards = 
             [...newDealerCards, shuffledDeck[playerCards.length + newDealerCards.length]];
      }
      setDealerCards(newDealerCards);
    }
    let dealerHandValue = getHandValue(newDealerCards);
    const playerHandValue = getHandValue(playerCards);
    if (dealerHandValue > 21 || dealerHandValue < playerHandValue) {
      setGameState('won');
      setPlayerBalance(playerBalance + currentBet);
    } else if (dealerHandValue > playerHandValue) {
      setGameState('lost');
      setPlayerBalance(playerBalance - currentBet);
    } else {
      setGameState('tied');
    }
  };

我們創建新的newDealerCards變量來傳播dealerCards狀態,然后我們根據您的條件執行while循環並相應地更新newDealerCards 完成后,我們才使用更新后的變量再次設置狀態,從而避免在while循環內多次調用setDealerCards

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM