教 JS 嘗試做一個 ticatactoe 游戲并遇到遞回問題,特別是“超出最大呼叫堆疊大小”。
當我嘗試由計算機玩家進行隨機移動時,我會生成一個亂數,然后將檢查他在名為 gameState 的陣列中的值。因此,如果該值已經定義(單元格中有 X 或 O 標記),我需要再次生成一個亂數。因此,當所有單元格都被標記時,我需要停止這個無限回圈,否則我會收到錯誤“超出最大呼叫堆疊大小”。
你能看一下,我做的事情是對的還是通常是錯的?其實我想過這個游戲場景的另一種實作,但我想如果我從那個開始我應該把這個引到最后
let gameState = ["", "", "", "", "", "", "", "", "",];
let playerAi = "O";
// ai's turn
function playerAiTurn() {
let randomNum = Math.floor(Math.random() * gameState.length);
if (gameState[randomNum] === '') {
gameState[randomNum] = playerAi;
document.getElementById(randomNum).innerHTML = playerAi;
resultCheck();
} else {
playerAiTurn()
};
};
uj5u.com熱心網友回復:
重復隨機呼叫將繼續獲得相同數字的可能性非常小,因此嚴格來說,簡單地保持滾動亂數并不正確(即使在實踐中它極不可能遇到)。
為了確定地避免這種情況,應該只根據未使用的地方取一個亂數。例如:
let gameState = ["", "", "", "", "", "", "", "", "",];
let playerAi = "O";
// ai's turn
function playerAiTurn() {
let unusedPlaces = [];
for(let i=0; i<gameState.length; i ) {
if( gameState[i] === "") unusedPlaces.push(i);
}
if( unusedPlaces.length > 0 ){
let randomUnusedPlace = unusedPlaces [ Math.floor(Math.random() * unusedPlaces.length) ];
gameState[randomUnusedPlace] = playerAi
document.getElementById(randomUnusedPlace).innerHTML = playerAi;
}
resultCheck();
}
沒有遞回呼叫。
uj5u.com熱心網友回復:
您必須檢查游戲何時結束并停止遞回呼叫。我不知道實作,resultCheck但它應該回傳有關游戲是否完成的資訊。如果它完成了,不要進行遞回呼叫。
話雖如此,您的代碼的性能是不可預測的,因為它甚至在知道結果槽是否可用之前就生成亂數。你可以像這樣優化它:
const gameState = ["", "", "", "", "", "", "", "", "",];
const playerAi = "O";
function playerAiTurn() {
const emptySlots = Array.from(gameState.entries()).filter(([, x]) => x === '');
if(!emptySlots.length)
return; //Game over
const randomNum = Math.floor(Math.random() * emptySlots.length);
const [index] = emptySlots[randomNum];
gameState[index] = playerAi;
document.getElementById(index).innerHTML = playerAi;
resultCheck();
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/448939.html
標籤:javascript 递归 调用栈
上一篇:重試機制以從不同主機發送電子郵件
下一篇:遞回函式的裝飾器
