Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
179 lines (163 sloc) 5.49 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>井字棋</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="main.css">
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function Square(props) {
return (
<button className="square btn btn-outline-secondary" onClick={props.onClick}>
{props.value}
</button>
);
}
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;
}
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),
},
],
location: [[0, 0]],
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();
const location = this.state.location.slice(0, this.state.stepNumber + 1);
if(calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? 'X' : 'O';
location.push(this.getLocation(i));
this.setState({
history: history.concat([{
squares,
}]),
location: location,
xIsNext: !this.state.xIsNext,
stepNumber: history.length,
});
}
getLocation(i) {
const x = Math.floor(i / 3) + 1;
let y = 0;
y = ((i + 1) % 3 === 0) ? 3 : (i + 1) % 3;
return [x, y];
}
jumpTo(e, step) {
const list = e.target.parentNode.parentNode.childNodes;
for(let i = 0; i < list.length; i++) {
let item = list[i];
if(item.childNodes[0].classList.contains('active')) {
item.childNodes[0].classList.remove('active');
}
}
e.target.classList.add('active');
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 location = this.state.location.slice();
const moves = history.map((item, index) => {
const desc = index ? 'Go to move #' + index : 'Go to move start';
return (
<li key={index}>
<button className="btn btn-outline-secondary btn-sm" type="button" onClick={(e) => this.jumpTo(e, index)}>{desc} ({location[index][0]}, {location[index][1]})</button>
</li>
);
});
let status;
const fillLength = current.squares.filter((item) => item != null).length;
if(winner) {
status = '恭喜 ' + winner + ' 获得了本次的胜利👏🏻👏🏻👏🏻';
} else if(fillLength === 9) {
status = '和棋了,再来一局定胜负吧';
} else {
status = '该你落子了: ' + (this.state.xIsNext ? 'X' : 'O');
}
return (
<div className="container">
<h1 className="mt-5 mb-5 text-center">井字棋(Tic Tac Toe)</h1>
<div className="message mb-5 text-center">{status}</div>
<div className="row justify-content-center">
<div className="col-md-auto">
<Board squares={current.squares} onClick={(i) => this.handleClick(i)} />
</div>
<div className="col-md-auto">
<ol className="step-item">{moves}</ol>
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<Game />,
document.getElementById('root')
);
</script>
</body>
</html>
You can’t perform that action at this time.