繁体   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