[英]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.