Open In App

Building a Web-based Chess Game with React and Chess.js

Last Updated : 22 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we’ll walk through the step-by-step process of creating a Chess game using Chess.js, ReactJS, ExpressJS, and NodeJS. This application will provide users with a platform for users to play chess. It will be a single player game, where the opponent will be played by the application itself.

Output Preview: Let us have a look at how the final output will look like.

Chess-JS-GFG-Output

Output Preview

Pre-requisites

Approach to Create Chess Game using Reactjs and Chess.js:

  • Set up a new React project with create-react-app. Initialize a Git repository. Define the project structure.
  • Create a folder called “chess-game” within the project directory.
  • Within the “chess-game” folder, create the following files and directories:
    • src/index.js: Entry point of the application. Renders the <App /> component.
    • src/styles/App.css: CSS styles specific to the <App /> component.
    • src/styles/index.css: Global CSS styles.
    • src/components/App.js: Main component of the application. Contains the chess game logic.
  • Inside the “chess-game” folder, run the command npm install react react-dom chess.js to install the React library.

Steps to Create Chess Game using Reactjs and Chess.js:

Step 1: Set up React project using the command

npx create-react-app chess-game

Step 2: Navigate to the project folder using

cd chess-game

Step 3: Installing the required packages:

npm install react react-dom chess.js@0.13.3 react-chessboard@1.2.5

Project Structure:

Screenshot-2024-03-07-193257

Project Folder Structure

The updated Dependencies in package.json file of frontend will look like:

"dependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"chess.js": "^0.13.3",
"react": "^18.2.0",
"react-chessboard": "^1.2.5",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}

Example: Create the required files and write the following code.

CSS
/* App.css */

.app {
  color: white;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.header {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
}

.game-image {
  width: 150px; /* Adjust the width as needed */
  height: auto; /* Maintain aspect ratio */
  margin-right: 20px;
}

.game-info {
  display: flex;
  flex-direction: column;
}

.chessboard-container {
  position: relative;
}

.game-over {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: rgba(0, 0, 0, 0.7);
  padding: 20px;
  border-radius: 5px;
  text-align: center;
}

.game-over p {
  margin: 5px 0;
}
CSS
/* index.css */

body {
  margin: 0;
  background-color: #222;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}
Javascript
// App.js

import '../styles/App.css';
import { useState, useEffect } from 'react';
import { Chessboard } from 'react-chessboard';
import { Chess } from 'chess.js';

function App() {
  const [game, setGame] = useState(new Chess());
  const [winner, setWinner] = useState(null);
  const [gameOver, setGameOver] = useState(false);

  // Let's perform a function on the game state
  function safeGameMutate(modify) {
    setGame((g) => {
      const update = { ...g };
      modify(update);
      return update;
    });
  }

  // Movement of computer
  function makeRandomMove() {
    const possibleMove = game.moves();

    // exit if the game is over
    if (game.game_over() || game.in_draw() || possibleMove.length === 0) {
      setGameOver(true);
      const winner = game.turn() === 'w' ? 'Black' : 'White';
      setWinner(winner);
      return;
    }

    // select random move
    const randomIndex = Math.floor(Math.random() * possibleMove.length);
    // play random move
    safeGameMutate((game) => {
      game.move(possibleMove[randomIndex]);
    });
  }

  // Perform an action when a piece is dropped by a user
  function onDrop(source, target) {
    if (gameOver) return false;

    let move = null;
    safeGameMutate((game) => {
      move = game.move({
        from: source,
        to: target,
        promotion: 'q',
      });
    });
    // illegal move
    if (move === null) return false;
    // valid move
    setTimeout(makeRandomMove, 200);
    return true;
  }

  // Reset the game
  function restartGame() {
    setGame(new Chess());
    setGameOver(false);
    setWinner(null);
  }

  // Listen for Enter key press to restart the game
  useEffect(() => {
    function handleKeyPress(event) {
      if (event.key === 'Enter') {
        restartGame();
      }
    }
    window.addEventListener('keydown', handleKeyPress);
    return () => {
      window.removeEventListener('keydown', handleKeyPress);
    };
  }, []);

  return (
    <div className="app">
      <div className="header">
        <img src=
"https://media.geeksforgeeks.org/wp-content/cdn-uploads/20210420155809/gfg-new-logo.png" 
        alt="Game Image" className="game-image" />
        <div className="game-info">
          <h1>GeeksforGeeks Chess Game</h1>
        </div>
      </div>
      <div className="chessboard-container">
        <Chessboard position={game.fen()} onPieceDrop={onDrop} />
        {gameOver && (
          <div className="game-over">
            <p>Game Over</p>
            <p>Winner: {winner}</p>
            <p>Press Enter to restart</p>
          </div>
        )}
      </div>
    </div>
  );
}

export default App;
Javascript
// index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import App from './components/App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);

Start your application using the following command.

npm start

Output:

Web-Chess-Output

Final Output Preview



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads