javascript React井字游戏-显示何时发生换牌

nnvyjq4y  于 2022-10-30  发布在  Java
关注(0)|答案(6)|浏览(126)

I'm following the tic tac toe tutorial.
我现在想添加一个功能,如果有一个平局(没有人赢得),然后它会更新消息“有一个平局”。看到完整的代码片段如下:

function Square(props) {
  return (
    <button className="square" onClick={props.onClick}>
      {props.value}
    </button>
  );
}

class Board extends React.Component {
  renderSquare(i) {
    return (
      <Square 
        value={this.props.squares[i]}
        onClick={() => this.props.onClick(i)}
      />
    );
  }

  render() {
     return (
      <div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
      </div>
    );
  }
}

class Game extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      history: [{
        squares: Array(9).fill(null),
      }],
      xIsNext: true,
      stepNumber: 0,
    };
  }

  handleClick(i) {
    const history = this.state.history.slice(0, this.state.stepNumber + 1);
    const current = history[history.length - 1];
    const squares = current.squares.slice();
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    squares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
      history: history.concat([{
        squares: squares,
      }]),
      stepNumber: history.length,
      xIsNext: !this.state.xIsNext,
    });
  }

  jumpTo(step) {
    this.setState({
      stepNumber: step,
      xIsNext: (step % 2) === 0,
    });
  }

  render() {
    const history = this.state.history;
    const current = history[this.state.stepNumber];
    const winner = calculateWinner(current.squares);

    const moves = history.map((step, move) => {
      const desc = move ?
        'Go to move #' + move :
        'Go to game start';
      return (
        <li key={move}>
          <button onClick={() => this.jumpTo(move)}>{desc}</button>
        </li>
      );
    });

    let status;
    if (winner) {
      status = 'Winner: ' + winner;
    } elseif (winner === null) {
      status = 'There has been a draw'
    }
    else {
      status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
    }

    return (
      <div className="game">
        <div className="game-board">
          <Board
            squares={current.squares}
            onClick={(i) => this.handleClick(i)}
          />
        </div>
        <div className="game-info">
          <div>{status}</div>
          <ol>{moves}</ol>
        </div>
      </div>
    );
  }
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

我尝试在Game类中实现这一点。在实际检查赢家的代码中--如果我理解正确的话--如果没有满足任何条件,它将返回null值。相关代码如下:

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}

我现在要做的是,在引用上述函数的代码中,显示一条消息,告诉我们谁赢了,我设置一个elseif,看看函数是否抛出null,如果抛出null,显示一条消息,告诉我们发生了平局。代码如下所示:

let status;
    if (winner) {
      status = 'Winner: ' + winner;
    } elseif (winner === null) {
      status = 'There has been a draw'
    }
    else {
      status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
    }

calculateWinner函数中return null;的用途是什么?如何才能最好地检查此应用程序上下文中的平局?有没有更好的方法?
问题代码:https://codepen.io/anon/pen/OOQxmw?editors=0010

fgw7neuy

fgw7neuy1#

每次渲染时都会调用calculateWinner(),如果在这次渲染中没有找到中奖线,则返回null,这不一定意味着游戏结束。您需要检查是否没有找到中奖线,以及整个棋盘是否已满。这将是平局的条件。

lp0sw83n

lp0sw83n2#

我正在寻找这个问题的答案,以及我也是新的React,我解决了它做以下:
calculateWinner更改为:

function calculateWinner(squares) {
    const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
];

for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if(squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
        return squares[a];
    }
    else if(!squares.includes(null)){
        return 'draw';
    }
}
return null;
}

并且将Gamerender函数中的赢家逻辑改变为:

if(winner && winner != 'draw'){
        status = 'Winner: ' + winner;
    } else if (winner && winner === 'draw'){
        status = "It's a " + winner;
    } else {
        status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
    }

See your codepen updated

ohfgkhjo

ohfgkhjo3#

如果将if语句编辑为

if(!winner && this.state.history.length === 10){
   status = 'Draw';
}

你应该得到你想要的结果。

hzbexzde

hzbexzde4#

我也在问同样的问题。我正在学习Reactjs,很快就要学习React Native了。我是一个初级程序员。
我的解答有点不同于@sherlockDev的回答:

const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);
const finalMove = 9; // We know that the game can have only 9 moves.

const moves = history.map(step, move) => {
   const desc = move ?
   'Back to round n°' + move :
   'Back to the beginning';
   return (
       <li key={move}>
           <button onClick={() => this.jumpTo(move)}>{desc}>/button>
       </li>
   );
});

let status;

if (winner) {
   status = 'Player ' + winner + ' win the game!';
} else {
  status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
  if (this.state.stepNumber === finalMove){
      status = 'Draw game!';//If we are in the last move and still no winner 
  }
}

让我解释一下为什么我选择这个代码来定义是否有一个平局游戏或没有。
首先,我在考虑创建类似于calculateWinner()函数的东西,因为我正在研究一个可以给予获胜游戏的位置并将其转换为Chess形式的函数([A0,B4,C8]一个对角线获胜的游戏为例)但我太固执了,我没有看到它会不会在声明之外寻找一个赢家,最重要的是我没有看到我“我有关于游戏的一切,所有获胜的游戏解决方案,谁开始游戏,等等。。
我记得最后一步只能是const finalMove = 9,因为我们在这里定义了:

`class Game extends React.Component {
 constructor(props) {
     super(props);
     this.state = {
          history: [{
               squares: Array(9).fill(null), // Here we decide that the game will have 9 squares.
          }];
// etc... you know the rest of it
                   `

如果游戏有9个方格,它只能有9步棋。
我之所以把它放在寻找赢家的语句里面,是因为} else {,这是我停下来冥顽不灵后的理解:

If there have a winner: the game celebrates a winner; if there no winner: the game has 2 options: the game is not over or draw game.

所以我决定将实际的移动与finalMove变量进行比较,finalMove变量是9。由于它在} else {中,所以它只能在没有赢家的情况下工作。游戏正在计算下一个玩家,所以我可以添加新的if语句,以寻找这两个变量之间的匹配。
即使最后一步棋是一场胜利的游戏,if (winner)也会起作用。
我希望这会有帮助。
顺祝商祺
背201

ss2ws0br

ss2ws0br5#

在**calculateWinner()**中,我修改了:

return null;

for(let j = 0; j < squares.length; j++) {
   if (squares[j] == null) {
     return null;
   }
}
return "DRAW";

而在**render()**中,我改变了:

if (winner) {
  status = "Winner: " + winner;
else {
  status = "Next player: " + (this.state.xIsNext ? "X" : "O");
}

if (winner) {
  status = "Winner: " + winner;

//ADDED THIS NEW IF
  if (status == "Winner: DRAW") {
    status = "There has been a draw.";
  }
//END OF NEW IF

}
else {
  status = "Next player: " + (this.state.xIsNext ? "X" : "O");
}

注意:这不是最好的解决方案,只是一种绕过复杂代码的方法。

7y4bm7vi

7y4bm7vi6#

我实际上是直接在游戏组件中编辑状态的,如果已经做了10步,那就做平局。

let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else if (this.state.stepNumber === 9) {
    status = 'Draw! ';
  } else {
    status = 'Next Player: ' + (this.state.xIsNext ? 'X' : 'O');
  }

相关问题