使用 React 和 Chessboardjsx 创建一个国际象棋游戏 ♟️
引言
本文将介绍如何使用 React 创建一个国际象棋游戏。本文基于我最近阅读的 Varun Pujari 的一篇文章。如果您想了解更多信息,可以点击以下链接查看原文。
我们将使用名为chessboardjsx的软件包,它能让我们轻松地展示国际象棋棋局。此外,我们还将使用chess.js库来实现棋步以及游戏的玩法。
这个国际象棋游戏将由一名玩家对阵人工智能,人工智能每回合都会随机走一步。最后,我们会给游戏添加一个计时器,以便测试我们击败人工智能的速度!
设置
安装过程非常简单。首先,我们需要在终端/命令提示符中运行几个命令来完成所有安装工作。
- 运行
yarn create react-app chess-game --template typescript。你也可以运行,npx create-react-app chess-game --template typescript但对我来说 yarn 的效果更好。我之前一直收到一个错误提示,说我的 create-react-app 版本过旧。每次卸载并尝试运行 npx 命令时,都会出现同样的版本过旧错误。所以我最终选择了 yarn。 - 接下来我们将
chessboard.jsx使用以下yarn add chessboardjsx命令进行安装。 - 现在让我们安装游戏的核心组件。运行
yarn add chess.js此软件包。我们将使用此软件包来实现人工智能逻辑。 - 由于我们也在使用 TypeScript,所以我们需要添加类型
chess.js。我们可以通过运行以下命令来完成此操作yarn add @types/chess.js: - 最后,我想给这个游戏加个计时器,这样我们就能看到游戏花了多长时间。我们来运行以下命令来设置它
yarn add react-compound-timer。
代码
现在到了最有趣的部分——游戏背后的实际代码。下面是本项目中唯一需要编辑的文件的代码App.tsx。我已经尽量对主要部分添加了注释,以便您更容易理解其运行机制。
import React, { useState } from "react";
import "./App.css";
import Timer from "react-compound-timer";
// Lines 5-8: Bring in chessboard and chess.js stuff
import Chessboard from "chessboardjsx";
import { ChessInstance, ShortMove } from "chess.js";
const Chess = require("chess.js");
const paddingStyle = {
padding: 5
}
const marginStyle = {
margin: 5
}
const App: React.FC = () => {
const [chess] = useState<ChessInstance>(
// Set initial state to FEN layout
new Chess("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
);
const [fen, setFen] = useState(chess.fen());
// Logic for the setting up the random computer move.
const handleMove = (move: ShortMove) => {
// Line 29 validates the user move.
if (chess.move(move)) {
setTimeout(() => {
const moves = chess.moves();
// Lines 33-28: Computer random move.
if (moves.length > 0) {
const computerMove = moves[Math.floor(Math.random() * moves.length)];
chess.move(computerMove);
setFen(chess.fen());
}
}, 300);
// Sets state of chess board
setFen(chess.fen());
}
};
return (
<div className="flex-center">
<h1>Random Chess Game</h1>
<Chessboard
width={400}
position={fen}
// onDrop prop tracks everytime a piece is moved.
// The rest is handled in the the handleMove function.
onDrop={(move) =>
handleMove({
from: move.sourceSquare,
to: move.targetSquare,
// This promotion attribute changes pawns to a queen if they reach the other side of the board.
promotion: "q",
})
}
/>
{/* Timer code */}
<Timer initialTime={0} startImmediately={false}>
{/* I thought this was weird. Definitely a better way to do this, but I just wanted it to work. */}
{({ start, resume, pause, stop, reset, timerState } : {start:any, resume:any, pause:any, stop:any, reset:any, timerState:any}) => (
<>
<div>
<span style={paddingStyle}><Timer.Minutes /> minutes</span>
<span style={paddingStyle}><Timer.Seconds /> seconds</span>
<span style={paddingStyle}><Timer.Milliseconds /> milliseconds</span>
</div>
<div style={paddingStyle}>{timerState}</div>
<br />
<div>
<button style={marginStyle} onClick={start}>Start</button>
<button style={marginStyle} onClick={pause}>Pause</button>
<button style={marginStyle} onClick={resume}>Resume</button>
<button style={marginStyle} onClick={stop}>Stop</button>
<button style={marginStyle} onClick={reset}>Reset</button>
</div>
</>
)}
</Timer>
</div>
);
};
export default App;
将App.tsx文件更新成这样后,你应该就能运行你的项目,yarn start并与你创建的AI下棋了。别忘了启动计时器,看看你能多快获胜!
FEN(福赛斯-爱德华兹符号)
我觉得这个项目最有趣的地方在于福赛斯-爱德华兹记谱法(Forsyth-Edwards Notation,简称FEN)。它是一种描述国际象棋棋局的记谱法。你会注意到它在App.tsx代码的第21行被使用。它之所以让我印象深刻,是因为我第一次看到它时,还以为是一堆乱码。你能猜出福赛斯-爱德华兹记谱法初始状态的字母是什么意思吗?我相信你很快就能明白,但如果你需要提示,它与棋盘上棋子的名称有关。
结论
好了,差不多就是这样。很简单,也很简短。希望你喜欢制作这款国际象棋游戏,也希望你玩得开心。如果你想挑战一下自己,可以尝试把它部署到网上,看看你的朋友和家人能多快打败AI。我推荐你使用Netlify,那是我常用的托管服务。
一如既往,祝大家编程愉快!爱你们。再见。
文章来源:https://dev.to/tyry327/create-a-chess-game-with-react-and-chessboardjsx-214e