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