reactjs - React native:为什么我会收到“未捕获的错误:超出最大调用堆栈大小”?
问题描述
我已经编写了下面的代码(请注意,一些不相关的功能已被删除)。
我正在尝试制作玩家与计算机的井字游戏。但是每次我尝试在 Android Studio 上运行代码时,Uncaught error: Maximum call stack size exceeded
都会显示,特别是当轮到计算机采取行动时。我认为错误出在onTilePress
函数中,但我不确定如何解决。有谁知道那里有什么问题?任何建议将不胜感激。先感谢您。
/* eslint-disable prettier/prettier */
...
export default class TicTacToe2 extends React.Component {
constructor(props){
super(props);
this.state = {
gameState: [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
] ,
currentPlayer: 1,
}
//tilesSelected : 0;
}
componentDidMount(){ //To start the first render... I guess
this.initializeGame();
}
//Reset the gameboard
initializeGame = () => {
this.setState({gameState:
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
],
currentPlayer: 1,
});
}
checkTie = () => {
...
}
//To check if the tile selected is owned
checkTilesOwner = (row, col) => {
var arr = this.state.gameState;
if (arr[row][col] == 1){ //Tile owned by Player 1
//Alert.alert("Owned by player 1!"); //remove comment for trial-and-error
this.BotMove();
}
else if (arr[row][col] == -1) { //Tile owned by Bot
//Alert.alert("Owned by Bot!"); //remove comment for trial-and-error
this.BotMove();
}
else { //Empty tile
this.onTilePress(row, col); //Select the tile
}
}
//Return 1 if player 1 won, -1 if player 2 / bot won, or 0 if no one has won
getWinner = () => {
...
}
BotMove = () => {
var RandRow = Math.floor(Math.random() * 3) + 0; //Generate random number for Row
var RandCol = Math.floor(Math.random() * 3) + 0; //Generate random number for Col
this.checkTilesOwner(RandRow, RandCol);
}
onTilePress = (row, col) => {
//Dont allow tiles to change
var value = this.state.gameState[row][col];
if (value !== 0) { return;}
//Identify and grab current player
var currentPlayer = this.state.currentPlayer;
//Set the correct tile...
var arr = this.state.gameState.slice();
arr[row][col] = currentPlayer;
this.setState({gameState: arr});
//Switch to other player
var nextPlayer = (currentPlayer == 1) ? -1 : 1; //if yes, then change to -1; else, then change to 1
this.setState({currentPlayer: nextPlayer});
//Alert.alert(nextPlayer);
//Check if the match is tie
var checkDraw = this.checkTie();
//check winner
var winner = this.getWinner(); //get the winner update
if (winner == 1) {
Alert.alert("Player 1 has won!");
this.initializeGame();
}
else if (winner == -1){
Alert.alert("Bot has won!");
this.initializeGame();
}
else if (checkDraw == 9){
Alert.alert("It's a draw!");
this.initializeGame();
}
//Identify the current player: 1 is human, -1 is bot
var takePlayer = '' + nextPlayer;
if (takePlayer == 1) {
Alert.alert("Player 1's turn!");
}
else if (takePlayer == -1) { //If it is Bot's turn to nmake a move, then trigger BotMove
Alert.alert("Bot's turn!");
this.BotMove(); //Uncaught error: Maximum call stack size exceeded //possible cause: endless loop
}
}
onNewGamePress = () => {
this.initializeGame();
}
renderIcon = (row, col) => {
var value = this.state.gameState[row][col];
switch(value) {
case 1:
return <TouchableOpacity><Text style={styles.tileX}>X</Text></TouchableOpacity>;
case -1:
return <TouchableOpacity><Text style={styles.tileO}>O</Text></TouchableOpacity>;
default:
return <View />
}
}
render() {
return (
//Container for Gameboard
...
);
}
}
解决方案
是的,你的BotMove
和checkTilesOwner
是循环的。
尝试将您的逻辑简化为
onTilePress(...) {
// think what needs to be done
// get only stuff you need without moving it
this.BotMove(...)
}
不要将思维代码(逻辑)与行动本身混为一谈。因为否则你最终会接到很多this.setState
电话。这不仅会导致很多循环问题,而且只会帮助您理解业务逻辑,在您的情况下,您的游戏逻辑:)
将您的逻辑与您的渲染分开。
推荐阅读
- c++ - 使用 minHeap 构建优先级队列
- time-series - 我可以计算包含某个值的 Prophet 模型的置信区间吗?
- python - 如何在 python 日志记录中从 .ini 文件配置运行 HttpHandler?
- azure-functions - 使用 Azure 数据工厂运行 Azure 函数以读取和处理 Blob 中的文件
- python - 检测异常时能知道是哪一列导致异常吗?
- logstash - 来自某些 lambda 函数的日志没有流过
- flutter - 在无状态小部件中初始化变量的正确方法是什么?
- python - 如何让乌龟转向特定的度数?
- python - re.search 查找字典键并返回一个值
- javascript - backgridjs中的上下文菜单