In this article we are going to create a chess game with React. I based this article off of another article that I read recently by Varun Pujari. Here's the link to that if you want to check it out.
We'll use a package called chessboardjsx, which will give us an easy way to display the chess game. On top of that we will use the chess.js library to implement moves and how the game should be played.
This chess game will have one player playing against an AI that will make a random move for every turn. Lastly, we will add a timer to our chess game so we can time how fast we beat the AI!
Setup is pretty simple. First, we'll run a couple commands in the terminal/command prompt to get everything installed.
yarn create react-app chess-game --template typescript
. You can also run npx create-react-app chess-game --template typescript
but yarn worked better for me. I was getting an error saying my create-react-app was out of date. Every time I would uninstall and try to run the npx command I would get the same out of date error. So yarn was what I went with.chessboard.jsx
with this yarn add chessboardjsx
command.yarn add chess.js
. This package is what we will use for the AI logic.chess.js
. We can do this by running yarn add @types/chess.js
.yarn add react-compound-timer
.Now for the fun part, the actual code behind the game. Below you will find the code for the only file you'll need to edit in this project, the
App.tsx
file. I've tried to comment on the main parts so it's easier to understand what is going on.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;
Once you have updated your
App.tsx
file to look like this you should be able to run your project with yarn start
and play chess against an AI that you created. Don't forget to start the timer and see how quick you can win!One thing I thought was really interesting about this project was Forsyth-Edwards Notation, or FEN. It is the notation that describes a chess position. You'll notice it being used on line 21 of the
App.tsx
code. It stood out to me because when I first saw it I was certain it was just a bunch of gibberish. Can you figure out what the letters on the initial starting state of the Forsyth-Edwards Notation mean? I'm sure you'll pick it up quick, but if you need a hint, it has to do with names of the pieces on the chess board.
Welp, that’s about it. Pretty short and simple. I hope you enjoyed making this chess game and hopefully have more fun playing it.
If you want a little bit of extra credit, try deploying this out online somewhere and see how fast your friends and family can beat the AI.
I would recommend deploying it to Netlify. That's my go to hosting service.
Like always, happy coding! Love y'all. Peace.
Also published on: https://dev.to/tyry327/create-a-chess-game-with-react-and-chessboardjsx-214e