react官网井字棋附加题

效果图

在这里插入图片描述


代码

import { useState } from "react";

function Square({ value, onSquareClick, win }) {
  return (
    <button className={win ? "square win" : "square"} onClick={onSquareClick}>
      {value}
    </button>
  );
}

function Board({ xIsNext, squares, onPlay, currentMove }) {
  const boardSize = 3;
  const res = calculateWinner(squares);
  let winner = "";
  let winList = [];
  if (res) {
    winner = res.winner;
    winList = res.winList;
  }

  const handleClick = (i) => {
    if (squares[i] || calculateWinner(squares)) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = "X";
    } else {
      nextSquares[i] = "O";
    }
    onPlay(nextSquares);
  };

  const renderSquare = (i, win) => {
    return (
      <Square
        value={squares[i]}
        onSquareClick={() => handleClick(i)}
        win={win}
        key={i}
      />
    );
  };
  const renderRow = (rowIndex, winList) => {
    const row = [];
    for (let j = 0; j < boardSize; j++) {
      row.push(
        renderSquare(
          rowIndex * boardSize + j,
          winList && winList.includes(rowIndex * boardSize + j)
        )
      );
    }
    return (
      <div className="board-row" key={rowIndex}>
        {row}
      </div>
    );
  };
  const rows = Array.from({ length: boardSize }, (_, i) =>
    renderRow(i, winList)
  );

  let status;
  if (winner) {
    status = "Winner:" + winner;
  } else if (currentMove === boardSize * boardSize) {
    status = "对局结果:平局";
  } else {
    status = "Next player: " + (xIsNext ? "X" : "O");
  }
  return (
    <>
      <div className="status">{status}</div>
      {rows}
    </>
  );
}

export default function Game() {
  const [IsAsc, setIsAsc] = useState(true);
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const [currentMove, setCurrentMove] = useState(0);
  const currentSquares = history[currentMove];

  const handlePlay = (nextSquares) => {
    const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
    setHistory(nextHistory);
    setCurrentMove(nextHistory.length - 1);
    setXIsNext(!xIsNext);
  };

  function jumpTo(nextMove) {
    setCurrentMove(nextMove);
    setXIsNext(nextMove % 2 === 0);
  }

  const moves = history.map((_, move) => {
    let description;
    if (move > 0) {
      description = "这是第 " + move + " 步";
    } else {
      description = "开始游戏";
    }

    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  if (!IsAsc) {
    moves.reverse();
  }
  return (
    <div className="game">
      <div className="game-borad">
        <Board
          xIsNext={xIsNext}
          squares={currentSquares}
          onPlay={handlePlay}
          currentMove={currentMove}
        />
      </div>
      <div className="game-info">
        <button onClick={() => setIsAsc(true)}>升序</button>
        <button onClick={() => setIsAsc(false)}>降序</button>
        <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 {
        winner: squares[a],
        winList: [a, b, c]
      };
    }
  }
  return null;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值