尝试制作简单的 react-native-app 时无法显示警报
Cant show alert while trying to make a simple react-native-app
我正在尝试将井字棋游戏制作成简单的反应本机应用程序。但是我无法在尝试让游戏提醒玩家在获得“3 排”时获得 1 或 2 次胜利时发出警报。谁能看出我做错了什么或给我一些建议。
除了 Alert 和 this.initializeGame(); 之外一切正常。在我想获得获胜者的部分下。
如果有人知道是否有 "better" 将变量命名为 const 的做法,或者让我也想知道。 :)
谢谢!
代码如下:
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity, Alert, } from 'react-native';
import { MaterialCommunityIcons as Icon } from 'react-native-vector-icons'
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
gameState: [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
],
currentPlayer: 1,
}
}
componentDidMount() {
this.initializeGame();
}
initializeGame = () => {
this.setState({gameState:
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
],
currentPlayer: 1,
});
}
getWinner = () => {
const NUM_TILES = 3;
var arr = this.state.gameState;
var sum;
var i = 0;
//rows
for (i; 1 < NUM_TILES; i++) {
sum = arr[i][0] + arr[i][1] + arr[i][2];
if (sum == 3) { return 1; }
else if (sum == -3) { return -1; }
}
//colums
for (i; 1 < NUM_TILES; i++) {
sum = arr[0][i] + arr[1][i] + arr[2][i];
if (sum == 3) { return 1; }
else if (sum == -3) { return -1; }
}
//diagonals
sum = arr[0][0] + arr[1][1] + arr[2][2];
if (sum == 3) { return 1; }
else if (sum == -3) { return -1; }
sum = arr[2][0] + arr[1][1] + arr[0][2];
if (sum == 3) { return 1; }
else if (sum == -3) { return -1; }
//If no winners
return 0;
}
onTilePress = (row, col) => {
//makes sure that the tiles dont change
var value = this.state.gameState[row][col];
if (value !== 0) { return; }
//sets currant player
var currentPlayer = this.state.currentPlayer;
//sets the correct tile
var arr = this.state.gameState.slice();
arr [row][col] = currentPlayer;
this.setState({gameState: arr});
//switches player
var nextPlayer = (currentPlayer == 1) ? -1 : 1;
this.setState({currentPlayer: nextPlayer});
//check for winners
var winner = this.getWinner();
if (winner == 1) {
Alert.alert("Player 1 is the winner");
this.initializeGame();
} else if (winner == -1) {
Alert.alert("Player 2 is the winner");
this.initializeGame();
}
}
renderIcon = (row, col) => {
var value = this.state.gameState[row][col];
switch(value)
{
case 1: return <Icon name="close" style={styles.tileX} />;
case -1: return <Icon name="circle-outline" style={styles.tileO} />;
default: return <View />;
}
}
render() {
return (
<View style={styles.container}>
<View style={{flexDirection: "row"}}>
<TouchableOpacity onPress={() => this.onTilePress(0, 0)} style={[styles.tile, { borderLeftWidth: 0, borderTopWidth: 0 }]}>
{this.renderIcon(0, 0)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(0, 1)} style={[styles.tile, { borderTopWidth: 0, }]}>
{this.renderIcon(0, 1)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(0, 2)} style={[styles.tile, { borderRightWidth: 0, borderTopWidth: 0 }]}>
{this.renderIcon(0, 2)}
</TouchableOpacity>
</View>
<View style={{flexDirection: "row"}}>
<TouchableOpacity onPress={() => this.onTilePress(1, 0)} style={[styles.tile, { borderLeftWidth: 0 }]}>
{this.renderIcon(1, 0)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(1, 1)} style={[styles.tile, { }]}>
{this.renderIcon(1, 1)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(1, 2)} style={[styles.tile, { borderRightWidth: 0 }]}>
{this.renderIcon(1, 2)}
</TouchableOpacity>
</View>
<View style={{flexDirection: "row"}}>
<TouchableOpacity onPress={() => this.onTilePress(2, 0)} style={[styles.tile, { borderBottomWidth: 0, borderLeftWidth: 0, }]}>
{this.renderIcon(2, 0)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(2, 1)} style={[styles.tile, { borderBottomWidth: 0, }]}>
{this.renderIcon(2, 1)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(2, 2)} style={[styles.tile, { borderBottomWidth: 0, borderRightWidth: 0,
}]}>
{this.renderIcon(2, 2)}
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#fff',
alignItems: 'center',
},
tile: {
borderWidth: 10,
width: 100,
height: 100,
},
tileX: {
color: "red",
fontSize: 60,
},
tileO: {
color: "green",
fontSize: 60,
}
});
看起来您所做的一切都很好,除了 getWinner()
函数的算法。这个函数有很多错误,例如,你的 for 循环结束条件是 1 < NUM_OF_TILES
,其中 NUM_OF_TILES
是 3。而且你还必须在移动时将 i
重新初始化为 0从行到列,因为 i
在第一个 for 循环结束时已经是 2。
我已经为您更新了这个功能如下:
getWinner = () => {
const NUM_TILES = 3;
var arr = this.state.gameState;
var sum;
var i = 0;
//rows
for (i = 0; i < NUM_TILES; i++) {
sum = arr[i][0] + arr[i][1] + arr[i][2];
if (sum == 3) {
return 1;
} else if (sum == -3) {
return -1;
}
}
//colums
for (i = 0; i < NUM_TILES; i++) {
sum = arr[0][i] + arr[1][i] + arr[2][i];
if (sum == 3) {
return 1;
} else if (sum == -3) {
return -1;
}
}
//diagonals
sum = arr[0][0] + arr[1][1] + arr[2][2];
if (sum == 3) {
return 1;
} else if (sum == -3) {
return -1;
}
sum = arr[2][0] + arr[1][1] + arr[0][2];
if (sum == 3) {
return 1;
} else if (sum == -3) {
return -1;
}
//If no winners
return 0;
};
您可以在以下位置找到工作代码:https://codesandbox.io/s/react-native-4f2yu 顺便说一句,我还没有测试所有用例,但希望它能让您朝着正确的方向前进。
我正在尝试将井字棋游戏制作成简单的反应本机应用程序。但是我无法在尝试让游戏提醒玩家在获得“3 排”时获得 1 或 2 次胜利时发出警报。谁能看出我做错了什么或给我一些建议。
除了 Alert 和 this.initializeGame(); 之外一切正常。在我想获得获胜者的部分下。
如果有人知道是否有 "better" 将变量命名为 const 的做法,或者让我也想知道。 :)
谢谢!
代码如下:
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity, Alert, } from 'react-native';
import { MaterialCommunityIcons as Icon } from 'react-native-vector-icons'
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
gameState: [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
],
currentPlayer: 1,
}
}
componentDidMount() {
this.initializeGame();
}
initializeGame = () => {
this.setState({gameState:
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
],
currentPlayer: 1,
});
}
getWinner = () => {
const NUM_TILES = 3;
var arr = this.state.gameState;
var sum;
var i = 0;
//rows
for (i; 1 < NUM_TILES; i++) {
sum = arr[i][0] + arr[i][1] + arr[i][2];
if (sum == 3) { return 1; }
else if (sum == -3) { return -1; }
}
//colums
for (i; 1 < NUM_TILES; i++) {
sum = arr[0][i] + arr[1][i] + arr[2][i];
if (sum == 3) { return 1; }
else if (sum == -3) { return -1; }
}
//diagonals
sum = arr[0][0] + arr[1][1] + arr[2][2];
if (sum == 3) { return 1; }
else if (sum == -3) { return -1; }
sum = arr[2][0] + arr[1][1] + arr[0][2];
if (sum == 3) { return 1; }
else if (sum == -3) { return -1; }
//If no winners
return 0;
}
onTilePress = (row, col) => {
//makes sure that the tiles dont change
var value = this.state.gameState[row][col];
if (value !== 0) { return; }
//sets currant player
var currentPlayer = this.state.currentPlayer;
//sets the correct tile
var arr = this.state.gameState.slice();
arr [row][col] = currentPlayer;
this.setState({gameState: arr});
//switches player
var nextPlayer = (currentPlayer == 1) ? -1 : 1;
this.setState({currentPlayer: nextPlayer});
//check for winners
var winner = this.getWinner();
if (winner == 1) {
Alert.alert("Player 1 is the winner");
this.initializeGame();
} else if (winner == -1) {
Alert.alert("Player 2 is the winner");
this.initializeGame();
}
}
renderIcon = (row, col) => {
var value = this.state.gameState[row][col];
switch(value)
{
case 1: return <Icon name="close" style={styles.tileX} />;
case -1: return <Icon name="circle-outline" style={styles.tileO} />;
default: return <View />;
}
}
render() {
return (
<View style={styles.container}>
<View style={{flexDirection: "row"}}>
<TouchableOpacity onPress={() => this.onTilePress(0, 0)} style={[styles.tile, { borderLeftWidth: 0, borderTopWidth: 0 }]}>
{this.renderIcon(0, 0)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(0, 1)} style={[styles.tile, { borderTopWidth: 0, }]}>
{this.renderIcon(0, 1)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(0, 2)} style={[styles.tile, { borderRightWidth: 0, borderTopWidth: 0 }]}>
{this.renderIcon(0, 2)}
</TouchableOpacity>
</View>
<View style={{flexDirection: "row"}}>
<TouchableOpacity onPress={() => this.onTilePress(1, 0)} style={[styles.tile, { borderLeftWidth: 0 }]}>
{this.renderIcon(1, 0)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(1, 1)} style={[styles.tile, { }]}>
{this.renderIcon(1, 1)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(1, 2)} style={[styles.tile, { borderRightWidth: 0 }]}>
{this.renderIcon(1, 2)}
</TouchableOpacity>
</View>
<View style={{flexDirection: "row"}}>
<TouchableOpacity onPress={() => this.onTilePress(2, 0)} style={[styles.tile, { borderBottomWidth: 0, borderLeftWidth: 0, }]}>
{this.renderIcon(2, 0)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(2, 1)} style={[styles.tile, { borderBottomWidth: 0, }]}>
{this.renderIcon(2, 1)}
</TouchableOpacity>
<TouchableOpacity onPress={() => this.onTilePress(2, 2)} style={[styles.tile, { borderBottomWidth: 0, borderRightWidth: 0,
}]}>
{this.renderIcon(2, 2)}
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#fff',
alignItems: 'center',
},
tile: {
borderWidth: 10,
width: 100,
height: 100,
},
tileX: {
color: "red",
fontSize: 60,
},
tileO: {
color: "green",
fontSize: 60,
}
});
看起来您所做的一切都很好,除了 getWinner()
函数的算法。这个函数有很多错误,例如,你的 for 循环结束条件是 1 < NUM_OF_TILES
,其中 NUM_OF_TILES
是 3。而且你还必须在移动时将 i
重新初始化为 0从行到列,因为 i
在第一个 for 循环结束时已经是 2。
我已经为您更新了这个功能如下:
getWinner = () => {
const NUM_TILES = 3;
var arr = this.state.gameState;
var sum;
var i = 0;
//rows
for (i = 0; i < NUM_TILES; i++) {
sum = arr[i][0] + arr[i][1] + arr[i][2];
if (sum == 3) {
return 1;
} else if (sum == -3) {
return -1;
}
}
//colums
for (i = 0; i < NUM_TILES; i++) {
sum = arr[0][i] + arr[1][i] + arr[2][i];
if (sum == 3) {
return 1;
} else if (sum == -3) {
return -1;
}
}
//diagonals
sum = arr[0][0] + arr[1][1] + arr[2][2];
if (sum == 3) {
return 1;
} else if (sum == -3) {
return -1;
}
sum = arr[2][0] + arr[1][1] + arr[0][2];
if (sum == 3) {
return 1;
} else if (sum == -3) {
return -1;
}
//If no winners
return 0;
};
您可以在以下位置找到工作代码:https://codesandbox.io/s/react-native-4f2yu 顺便说一句,我还没有测试所有用例,但希望它能让您朝着正确的方向前进。