Create a Chess game with React and Chessboardjsx ♟️
Tags: react, typescript, chess, netlify
Published: 2021-01-22 05:53:41

## 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](https://levelup.gitconnected.com/how-to-create-a-simple-chess-app-with-react-e18c0179b167) to that if you want to check it out. 

We'll use a package called [chessboardjsx](https://github.com/willb335/chessboardjsx), which will give us an easy way to display the chess game. On top of that we will use the [chess.js](https://github.com/jhlywa/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;
```
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](https://www.chessprogramming.org/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.