尝试制作简单的 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 顺便说一句,我还没有测试所有用例,但希望它能让您朝着正确的方向前进。