React.js ‘Championship Chess’ from Scratch — Part One

Anthony Mele
7 min readApr 18, 2022

“One Pawn at a Time”

Figure 1. Screenshot of Application — https://github.com/TMele54/Chess

Overview:

People who know me say I am only good at two things, writing React and chewing bubble gum… By the time you’ve finished reading this article, you should have learned some cool development ideas / strategies to build applications in React.js. This article is the first in a series of tutorials that will explore Application / Product Development and as we progress further we will branch into other Data Science disciplines with topics like Deep & Transfer Learning, Augmented Reality and Quantum Computing.

Follow Me here and Subscribe to this channel to continue learning and developing your Data Science background.

Project Details:

This project is a React.js Web Application that has been built from scratch using JavaScript, HTML and CSS. To run this project on your computer, simply clone the repo in the link above, install the node module libraries and start the development server. You can access the application via localhost on port 3000

Setup

## In Command Prompt# Clone Repo
git clone https://github.com/TMele54/Chess
# Open Directory
cd chess
# Install node modules
npm install
# Start the project
npm start

You’ll notice in the image above (Figure 1.)that there are three game modes — Simulation, One Player and Multi Player. Simulation and One Player both make use of a chess API that will either play itself (Simulation) or play the single user in One Player. Multiplayer requires a peer connection through a website so for now, since we’re looking at how the app itself was built with React.js we will focus on Simulation Game Mode. In future posts we’ll turn our focus to Single Player and Multi Player Game Modes.

Project Layout:

Building a chess app requires some customizations to be made but for the most part, React.js was very well suited to manage the states of pieces on a board and orchestrate a ‘game’. Below we see a conventional React project setup:

node_modules — contains the libraries declared in the package.json

public — holds our static assets, like PNGs of the chessmen

Static Asset — Black King — bk.PNG

src — holds our JavaScript or TypeScript component modules of the application

App.js — the entry point for our class and functional components to render in the browser

In the src/components folder are two files, Game.js and Boardgame.js and we can see in App.js that the class being called is <Game /> from Game.js. We can think of these two files in the following way. Boardgame.js is focused on the boardgame and it’s rules, making moves, choosing Game Modes and all the things that make it a boardgame. Game.js focuses on this particular game, the setup of pieces, the assertion of rank and file positions, creation of chessmen pieces from PNGs etc. Let’s explore methods in each file to understand how we built a chess app.

Game.js:

From the top down, Game.js is a fairly simple React.js Class Component with a single setup function initBoardMap() that is called in the render part of this components lifecycle. In initBoardMap, we set the simulation rate (timeout to make a move for the API), the number / size / locations of squares on the chessboard, and two arrays called RANK and FILE.

Game.js 50,000 foot view

In chess, Rank and File are used to mark the position of a piece on the board. For ex. when you start a new game, the King of the White players side will be on tile e1.

Position of the White Player’s king — e1 in top left corner of tile

We use the two array’s representing Rank and File to construct a matrix of pieces and their positions which are accessed via a React State.

// Transformation functions, RANK & FILE become a chess board
const transpose = a => a[0].map((_, c) => a.map(r => r[c]));
const mapp = FILE.flatMap(d => RANK.map(v => d + v))
const chessboard = new Array(Math.ceil(mapp.length / n)).fill().map(_ => mapp.splice(0, n))
const field = chessboard[0].map((_, colIndex) => chessboard.map(row => row[colIndex]));
const columns = transpose(field)

States in React are used for practically everything and we’re using them here in the following manner.

Construction of initial chessmen attributes

Here we see three arrays of objects which contain the white player pieces, the black player pieces and the chessmen which represents both groups. Each chess piece is represented here as an object. The black king looks like this: Player is b, id is b15, the picture of the king is ‘bk.svg’, it’s position is e8 (row 8, column e) and it’s name or piece type is a king.

{"player": "b", "id": "b15", "svg": "bk.svg", "pos": "e8", "name": "king"}

This is a typical way to handle something of this nature in a user interface and we will see that locating the piece programmatically by it’s Rank and File will be very useful for integrating with a chess API which speaks that language. However, there are also empty tiles on the board which we need to represent as well, and so we will use the constant emptySquare with all null values.

const emptySquare = { player: null, id: null, svg: null, pos: null, name: null }

Using the Rank and File Array’s in combination with the Chessmen we’re able to construct the input’s to the board game.

// Generate the Initial Position Map of the Board
columns.forEach((rows,i)=>{
rows.forEach((cell, j)=>{
const piece = chessmen.filter(d => d.pos === cell )[0]
const cellColor = i % 2 !== 0 ? j % 2 !== 0 ? colorB :colorA : j % 2 !== 0 ? colorA :colorB
if (piece === undefined){
let merged = {...{"cell": cell, "cellFill": cellColor, "iX": Left+squareSize*i, "iY": Top+squareSize*j, "bX": Left+squareSize*i, "bY": Top+squareSize*j}, ...emptySquare};
positions.push(merged)
}
else{
let merged = {...{"cell": cell, "cellFill": cellColor, "iX": Left+squareSize*i, "iY": Top+squareSize*j, "bX": Left+squareSize*i, "bY": Top+squareSize*j}, ...piece};
positions.push(merged)
}

})
})

In the loops above we basically are looping over our columns and rows from the Rank and File Matrix and applying board colors and the existence of pieces to the Tile they start the game with. The complete set of outputs from initBoardMap are passed to the <Chessset /> component which bring us to Boardgame.js

return {
simulationRate,
n,
RANK,
FILE,
squareSize,
chessmenSize,
Top,
Bottom,
Left,
Right,
boardHeight,
boardWidth,
colorA,
colorB,
positions
}

BoardGame.js:

BoardGame.js is a bit more complicated then Game.js for several reasons. The first major distinction is the fact that it is a functional component whereas Game.js is a class component. We’re using the functional component because we have a great use case to leverage React Hooks. I think of Hooks the same as a class component’s state but more focused on a particular aspect of the user interface. In our case, we’re using a Hook to manage the state of the Chessmen from Game.js; line 134 using the useState function takes in the positions of all pieces (this.props.positions) and has two outputs. BoardMap and updateBoardMap are the state variable and the change function of the state variable respectively. Next, let’s look at how the board and session are constructed so that we can explore how to Simulate a game between Chess Champions.

When the ChessSet functional component is rendered, several build functions are run and the move engine is enabled. To begin, the board function constructs and returns two separate layers which are the board itself and then the chess pieces. The board layer contains the light and dark brown squares with their Rank and File positions labeled. The chessmen layer contains SVG‘s (Scalable Vector Graphics) of the pieces like a pawn or king. Next, the chess engine is applied and several listeners begin evaluating state changes in the position of the chess pieces.

Move Engine listener types with iconic chess ‘Checkmate!’ phrase expanded

With the board and chessmen layers drawn the stage has been set to Simulate a game.

Simulation:

Simulating a chess game is pretty cool since it allows us to observe a really strong match that chess players can learn from. The chess.js API knows the initial positions of pieces when a game starts and it keeps tabs on changes as the game progresses. Every turn, we ask the API for a list of possible moves and then we use a random number generator to select one of those moves from an array. At the end of the turn we again ask the API to simulate the turn and voila, the game executes from start to finish animating the chessmen along the way.

Please Follow me, Subscribe, and become a Member to get notifications when Parts Two and Three are released.

About the Author:

Tony has deep experience working in the Data Sciences for roughly ten years across Banking, Startups, Pharma and Consulting industries with exposure to clients / projects across a myriad of additional industries.

He is very interested in Natural Language Processing, Computer Vision, Deep Learning, and Advanced Visualization/Product Development.

--

--

Anthony Mele

International Technologist & Innovator excited about all the places my interests will take me.