直接看效果
x是先手、o是后手
当然还有很多优化空间,下面看看代码
import React, { useEffect, useState } from 'react';
const rowStyle = {
display: 'flex'
}
const squareStyle = {
'width':'60px',
'height':'60px',
'backgroundColor': '#ddd',
'margin': '4px',
'display': 'flex',
'justifyContent': 'center',
'alignItems': 'center',
'fontSize': '20px',
'color': 'white'
}
const boardStyle = {
'backgroundColor': '#eee',
'width': '208px',
'alignItems': 'center',
'justifyContent': 'center',
'display': 'flex',
'flexDirection': 'column',
'border': '3px #eee solid'
}
const containerStyle = {
'display': 'flex',
'alignItems': 'center',
'flexDirection': 'column'
}
const instructionsStyle = {
'marginTop': '5px',
'marginBottom': '5px',
'fontWeight': 'bold',
'fontSize': '16px',
}
const buttonStyle = {
'marginTop': '15px',
'marginBottom': '16px',
'width': '80px',
'height': '40px',
'backgroundColor': '#8acaca',
'color': 'white',
'fontSize': '16px',
}
function Square(props) {
// console.log(props)
return (
<div
className={`square ${props.className}`}
style={squareStyle}>
{props.innerHtml}
</div>
);
}
function Board(props) {
const [xo, setXo] = useState('x')
const [winner, setWinner] = useState('None')
const [board, setBoard] = useState(
{
arr: [
['', '',''],
['','',''],
['', '','']
]})
const [canPlay, setCanPlay] = useState(true)
function handlePlay(e) {
if (canPlay && e.target.innerHTML === '') {
let row = e.target.parentElement.id.match(/\d/)[0];
let col = e.target.classList[1].match(/\d/)[0];
setBoard((prevBoard) => {
let {arr} = prevBoard;
arr[row][col] = xo;
return {arr,row,col}
})
if(xo==='x'){
setXo('o')
}else{
setXo('x')
}
}
}
useEffect(() => {
if (board.row) {
handlejudge()
}
}, [board])
function handlejudge() {
const { arr ,row, col} = board
let mayWinner = arr[row][col]
if (
(arr[row][0] === mayWinner && arr[row][1] === mayWinner && arr[row][2] === mayWinner)
||( arr[0][col] === mayWinner && arr[1][col] === mayWinner && arr[2][col] === mayWinner)
||(arr[1][1]!=''&&arr[0][0] === mayWinner && arr[1][1] === mayWinner && arr[2][2] === mayWinner)
||(arr[1][1]!=''&&arr[0][2] === mayWinner && arr[1][1] === mayWinner && arr[2][0] === mayWinner)
) {
setWinner(mayWinner);
setCanPlay(false);
}
}
function reset() {
setXo('x');
setWinner('None')
setBoard({
arr: [
['', '',''],
['','',''],
['', '','']
]
});
setCanPlay(true);
}
return (
<div style={containerStyle} className="gameBoard">
<div id="statusArea" className="status" style={instructionsStyle}>Next player: <span>{xo}</span></div>
<div id="winnerArea" className="winner" style={instructionsStyle}>Winner: <span>{winner}</span></div>
<button style={buttonStyle} onClick={reset}>Reset</button>
<div style={boardStyle} onClick={(e)=>handlePlay(e)}>
<div className="board-row" id="row0" style={rowStyle}>
<Square className="square0" innerHtml={ board.arr[0][0]}/>
<Square className="square1" innerHtml={ board.arr[0][1]} />
<Square className="square2" innerHtml={ board.arr[0][2]}/>
</div>
<div className="board-row" id="row1" style={rowStyle}>
<Square className="square0" innerHtml={ board.arr[1][0]}/>
<Square className="square1" innerHtml={ board.arr[1][1]}/>
<Square className="square2" innerHtml={ board.arr[1][2]}/>
</div>
<div className="board-row" id="row2" style={rowStyle}>
<Square className="square0" innerHtml={ board.arr[2][0]}/>
<Square className="square1" innerHtml={ board.arr[2][1]}/>
<Square className="square2" innerHtml={ board.arr[2][2]}/>
</div>
</div>
</div>
);
}
export default function Game() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
</div>
);
}
个人觉得还有很多地方写的都不优雅,比如说棋盘的初始化,再比如说输赢的判断。
朋友们有兴趣可以帮忙优化。
这是前两天笔试的一道题,个人觉得这样的笔试对前端是更有意义的,不过大多数考的还是算法。