DEV Community

Cover image for Create a Chess game with React and Chessboardjsx ♟️
Tyler Reicks
Tyler Reicks

Posted on

Create a Chess game with React and Chessboardjsx ♟️

Intro

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

Setup is pretty simple. First, we'll run a couple commands in the terminal/command prompt to get everything installed.

  1. Run 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.
  2. Next we'll install chessboard.jsx with this yarn add chessboardjsx command.
  3. Now let's install the brains of the game. Run yarn add chess.js. This package is what we will use for the AI logic.
  4. Since we are also using typescript we have to add types for chess.js. We can do this by running yarn add @types/chess.js.
  5. Lastly, I was thinking it would be cool to add a timer to this game so we can see how long the game took. Let's set that up by running yarn add react-compound-timer.

Code

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;
Enter fullscreen mode Exit fullscreen mode

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!

FEN (Forsyth-Edwards Notation)

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.

Conclusion

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.

Top comments (2)

Collapse
 
bourandeave profile image
Jason Pascua

The component includes event handlers for dragging, dropping, and clicking squares, as well as a right-click handler to undo moves. The chess game with best travel chess sets logic is handled using the Chess.js library, and the board UI is rendered using the Chessboardjsx component.

Collapse
 
sveinhd profile image
Svein Håvard Djupvik

Interesting code. When I checkmated the engine the game did not end.