直接上代码:
import {
BtnStype } from '../components';
import React, {
useState } from 'react';
import {
Button } from '@material-ui/core';
const Tictactoe = () => {
const [datas, Setdatas] = useState({
currentPlayer: "X",
winPlayer: "",
stepNumber: 0,
Msg: "当前选手:",
currentSquenes: Array(9).fill(""),
history: [{
squares: Array(9).fill(""),
}],
})
function onClickGrid(item) {
if (datas.currentSquenes[item] !== "" || datas.winPlayer !== "") {
return;
}
let squaresTemp = datas.currentSquenes;
squaresTemp[item] = datas.currentPlayer;
let currPlayer = datas.currentPlayer === "X" ? "O" : "X";
let currentHistory = datas.history;
if (datas.history.length !== datas.stepNumber + 1) {
currentHistory = datas.history.slice(0, datas.stepNumber + 1);
}
currentHistory.push(
{
squares: [...squaresTemp] }
);
let player = calculateWinner(squaresTemp);
let messages = "";
if (player === null) {
player = "";
messages = "当前选手";
if (datas.stepNumber + 1 === 9) {
messages = "平局";
currPlayer = '';
}
}
else {
messages = "胜利者:";
}
Setdatas({
...datas,
currentSquenes: datas.currentSquenes,
currentPlayer: currPlayer,
history: currentHistory,
winPlayer: player,
Msg: messages,
stepNumber: datas.stepNumber + 1,
})
}
function setGrid(item) {
return (
<Button
key={
item}
style={
BtnStype}
onClick={
() => onClickGrid(item)}
>{
datas.currentSquenes[item]}</Button>)
}
function step(num) {
let squenesTemp = datas.history[num].squares;
let currPlayer = num % 2 === 0 ? "X" : "O";
if (num === 0) {
squenesTemp = Array(9).fill(""); //patch
}
let player = calculateWinner(squenesTemp);
let messages = "";
if (player === null) {
player = "";
messages = "当前选手";
}
else {
messages = "胜利者:";
}
Setdatas({
...datas,
currentSquenes: squenesTemp,
currentPlayer: currPlayer,
winPlayer: player,
Msg: messages,
stepNumber: num,
})
}
return (
<div style={
{
display: 'flex', flexDirection: 'row' }}>
<div>
<div>{
[0, 1, 2].map(item => {
return setGrid(item) })}</div>
<div>{
[3, 4, 5].map(item => {
return setGrid(item) })}</div>
<div>{
[6, 7, 8].map(item => {
return setGrid(item) })}</div>
</div>
<div style={
{
marginLeft: '20px' }}>
<span>{
datas.Msg}{
datas.winPlayer === '' ? datas.currentPlayer : datas.winPlayer}</span>
{
datas.history.map((item, i) => {
return (<li key={
i}><Button key={
i} onClick={
() => step(i)}>步骤{
i}</Button></li>)
})}
</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;
}
}
export default Tictactoe;
export const BtnStype = ({
backgroundColor: 'gray',
border: 'solid 1px black',
width: '60px',
height: "60px",
color: 'black',
fontSize: "x-large"
});