import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
function Square(props) {
return (
<button onClick={props.onClick} className={"square" + " " + props.clas}>
{props.value}
</button>
);
}
//let t;
function isWin(squares) {
let line = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
// console.log("aaaa")
for (let i = 0; i < line.length; i++) {
let [a, b, c] = line[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return [a, b, c];
}
}
return null;
}
class Board extends React.Component {
renderSquare(i) {
return (
<Square
key={i}
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
clas={this.props.win.includes(i) ? "gaoliang" : ""}
/>
);
}
render() {
let row = [0, 3, 6];
let col = [0, 1, 2];
return (
<div>
{row.map((value, index) => (
<div key={index} className="board-row">
{col.map((value1, index1) => this.renderSquare(value + value1))}
</div>
))}
</div>
// <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),
local: [null, null],
},
],
isX: true,
curentStep: 0,
t: null,
revers: true,
};
this.setCurrentIndex = this.setCurrentIndex.bind(this);
}
setCurrentIndex(event) {
//console.log("aa"+event.currentTarget.getAttribute('key'))
this.setState({
t: parseInt(event.target.getAttribute("index"), 10),
});
}
handClick(i) {
const history = this.state.history.slice(0, this.state.curentStep + 1);
const squares = history[history.length - 1].squares.slice();
//const squares = curentSquare.slice();
if (squares[i] || isWin(squares)) {
return;
}
squares[i] = this.state.isX ? "x" : "o";
const local = [];
local[0] = i % 3;
local[1] = Math.trunc(i / 3);
const newHistory = history.concat({ squares, local });
//console.log("newhistory"+newHistory.toString())
this.setState({
history: newHistory,
isX: !this.state.isX,
curentStep: this.state.curentStep + 1,
});
}
jumpTo(move) {
this.setState({
curentStep: move,
isX: move % 2 === 0,
});
}
render() {
//const squares=this.state.history[this.setState.history.length-1]
let history = this.state.history.slice();
//console.log(t);
//console.log(history)
const squares = history[this.state.curentStep].squares;
let win = [];
let rz = null;
if (isWin(squares)) {
win = isWin(squares);
rz = squares[win[0]];
}
if (this.state.revers) {
history = history.reverse();
}
const moves = history.map((step, move) => {
if (this.state.revers) {
move = history.length - move - 1;
}
let dest = move ? "go to " + move : "go to restart";
return (
<li
key={move}
className={this.state.t === move ? "actclass" : ""}
onClick={(event) => {
//console.log(event);
//console.log(event.target.getAttribute('index'));
this.jumpTo(move);
this.setCurrentIndex(event);
//this.state.t=parseInt(event.target.getAttribute('index'),10);
//console.log(this.state.t);
}}
>
<button
index={move}
className={this.state.t === move ? "actclass" : ""}
>
{dest}坐标x:{step.local[0]}坐标y:{step.local[1]}
</button>
</li>
);
});
let status;
if (rz) {
status = "winner is " + rz;
} else if (history.length === 10) {
status = "ping jun";
} else {
status = "Next player: " + (this.state.isX ? "x" : "o");
}
return (
<div className="game">
<div className="game-board">
<Board
squares={squares}
win={win}
onClick={(i) => this.handClick(i)}
/>
</div>
<div className="game-info">
<div>{status}</div>
<ol reversed={this.state.revers}>{moves}</ol>
<button onClick={() => this.setState({ revers: !this.state.revers })}>
{" "}
倒转
</button>
</div>
</div>
);
}
}
// ========================================
ReactDOM.render(<Game />, document.getElementById("root"));
css代码
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}
ol, ul {
padding-left: 30px;
}
.board-row:after {
clear: both;
content: "";
display: table;
}
.status {
margin-bottom: 10px;
}
.square {
background: #fff;
border: 1px solid #999;
float: left;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 34px;
margin-right: -1px;
margin-top: -1px;
padding: 0;
text-align: center;
width: 34px;
}
.square:focus {
outline: none;
}
.kbd-navigation .square:focus {
background: #ddd;
}
.gaoliang{
color: red;
}
.actclass{
color: red;
font-weight: 1000;
}
.game {
display: flex;
flex-direction: row;
}
.game-info {
margin-left: 20px;
}