简体   繁体   English

while 中的 useState 导致死循环

[英]useState in while cause infinite loop

I trying to make Blackjack game in React.我试图在 React 中制作二十一点游戏。 A bot has got 2 cards at start.一个机器人一开始有 2 张牌。 If user stands, and bots card value is less than 17, it should draw addictional card, but then program cause infinite loop.如果用户站着,bots 的牌值小于 17,它应该抽上瘾的牌,但程序会导致死循环。 This is my code:这是我的代码:

  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;
};

The goal is to make bot draw a cards until value of his cards will be at least 17.目标是让机器人抽一张牌,直到他的牌的价值至少达到 17。

As discussed in the comments, using setDealerCards inside the while loop can be problematic.正如评论中所讨论的,在while循环中使用setDealerCards可能会出现问题。 Setting the state causes a re-render to the component and may trigger the function again depending on it's use.设置状态会导致重新渲染组件,并可能根据其使用情况再次触发该功能。 Another problem may be that since React schedules it's updates you may not get the most updated state every time you set the state again in the while loop.另一个问题可能是,由于 React 会安排它的更新,所以每次在while循环中再次设置状态时,您可能无法获得最新的状态。

So this might help所以这可能有帮助

  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');
    }
  };

We make the new newDealerCards variable to spread dealerCards state, we then do the while loop with your condition and update newDealerCards accordingly.我们创建新的newDealerCards变量来传播dealerCards状态,然后我们根据您的条件执行while循环并相应地更新newDealerCards When we're done, only then we set the state again with the updated variable we made and thus we avoid calling setDealerCards multiple times inside the while loop.完成后,我们才使用更新后的变量再次设置状态,从而避免在while循环内多次调用setDealerCards

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM