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

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 [email protected] [email protected]

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




Reffered: https://www.geeksforgeeks.org


Dev Scripter

Related
Real Estate Listings Platform using NextJS Real Estate Listings Platform using NextJS
Language Learning App using Django Language Learning App using Django
Convert Blob Image to PNG and JPG Using Python Convert Blob Image to PNG and JPG Using Python
Design a Business Agency Website in HTML CSS &amp; JavaScript Design a Business Agency Website in HTML CSS &amp; JavaScript
Types of Monitoring in System Design Types of Monitoring in System Design

Type:
Geek
Category:
Coding
Sub Category:
Tutorial
Uploaded by:
Admin
Views:
13