Previous parts: , Part 1 Part 2 I’m continuing my pet project, but before starting the next part I want to make some updates. Right now all imports in the project look something like this: or . But I prefer to use absolute imports: , . To achieve this we just need to add some lines to our file and create paths: import {Board} from ‘../../components/Board‘ import {BoardModel} from ‘../models/BoardModel‘ import {Board} from ‘components/Board‘ import {BoardModel} from ‘models/BoardModel‘ tsconfig.json "paths": { "components/*": ["./components/*"], "models/*": ["./models/*"], "utils/*": ["./utils/*"], "images/*": ["./images/*"] } Now we can import components, models, utils and images in any place of the application just using absolute paths. Let’s continue with development. As we already have a game board, we can try to create a figure and place it on the cell. To do this, firstly we need to create a base model class that will describe the figure. (I’ve spent some time choosing names for figures. In English-speaking countries and in non-English there are different common naming, so I decided to use for general figures and for Piece which became crowned). Figure names described in enum: Piece Dame FigureNames // src/models/FigureNames.ts export enum FigureNames { Piece = 'Piece', Dame = 'Dame', } // src/models/FigureModel.ts import { Labels } from 'models/Labels'; import { CellModel } from 'models/CellModel'; import pieceImgLight from 'images/light.png'; import pieceImgDark from 'images/brown.png'; import { FigureNames } from 'models/FigureNames'; class FigureModel { label: Labels; imageSrc: string; isDame: boolean; cell: CellModel; name: FigureNames; constructor(label: Labels, cell: CellModel) { this.label = label; this.cell = cell; this.cell.figure = this; this.isDame = false; this.name = FigureNames.Piece; this.imageSrc = label === Labels.Light ? pieceImgLight : pieceImgDark; } } export { FigureModel }; has next properties: FigureModel - our label label - this will be the source to figure image imageSrc - bool property for crowned and uncrowned pieces isDame - this is the on which figure is stay cell CellModel - figure name name In the constructor, we initialized these properties, and use the name by default for all pieces as they are uncrowned from the beginning. depends on the piece label. I’ve tried to find some good or icons for pieces, but this task is a little bit tricky, I’m still searching, so now I’ll use some temporary images. Maybe someone has any ideas where to find good and free icons for uncrowned and crowned pieces FigureNames.Piece imageSrc png svg svg We will use this class for all our pieces. And we will create a new figure in . So let’s add new methods to this class. First is a . It will return the cell from its coordinates. (As we remember our cells have x and y cords. On a game board, we have 8 rows and 8 cells in a row. For example x: 3, y: 1 will mean row number 2 and cell number 4 in this row). And method which will create the new figure. BoardModel getCell addFigure // src/models/BoardModel.ts getCell(x: number, y: number): CellModel { return this.cells[y][x]; } addFigure(label: Labels, x: number, y: number) { new FigureModel(label, this.getCell(x, y)); } takes label and cords as arguments and creates a new Figure instance. addFigure Full class: BoardModel import { CellModel } from './CellModel'; import { Labels } from './Labels'; import { FigureModel } from 'models/FigureModel'; class BoardModel { cells: CellModel[][] = []; cellsInRow = 8; createCells() { for (let i = 0; i < this.cellsInRow; i += 1) { const row: CellModel[] = []; for (let j = 0; j < this.cellsInRow; j += 1) { if ((i + j) % 2 !== 0) { row.push(new CellModel(i, j, Labels.Dark, this)); // black } else { row.push(new CellModel(i, j, Labels.Light, this)); // white } } this.cells.push(row); } } getCell(x: number, y: number): CellModel { return this.cells[y][x]; } addFigure(label: Labels, x: number, y: number) { new FigureModel(label, this.getCell(x, y)); } } export { BoardModel }; We also need to update and add figure property to it, so our cell will know about the figure that is staying on it: CellModel // src/models/CellModel.ts import { Labels } from './Labels'; import { BoardModel } from './BoardModel'; import { FigureModel } from 'models/FigureModel'; class CellModel { readonly x: number; readonly y: number; readonly label: Labels; figure: FigureModel | null; // our figure board: BoardModel; available: boolean; key: string; constructor(x: number, y: number, label: Labels, board: BoardModel) { this.x = x; // x coord this.y = y; // y coord this.label = label; this.board = board; this.available = false; // is it free for figure this.key = `${String(x)}${String(y)}`; this.figure = null; // null by default } } export { CellModel }; Cell components also need to be updated, to have the ability to render the image based on props: // src/components/Cell/Cell.tsx import React, { ReactElement } from 'react'; import './Cell.css'; import { mergeClasses } from 'utils/utils'; import { CellModel } from 'models/CellModel'; type CellProps = { cell: CellModel; }; export const Cell = ({ cell }: CellProps): ReactElement => { const { figure, label } = cell; return ( <div className={mergeClasses('cell', label)}> {figure?.imageSrc && <img className="icon" src={figure.imageSrc} alt={figure.name} />} </div> ); }; Component get prop which is a . We just destruct from it and check if exists, then we render the image - cell CellModel figure figure.imageSrc {figure?.imageSrc && <img className="icon" src={figure.imageSrc} alt={figure.name} />} In component styles we need to add new class .icon: // src/components/Cell/Cell.css .icon { width: 64px; height: 64px; } Everything is ready and let’s try to create some random figures. In in the restart function let’s call some : App.tsx addFigures // src/App.tsx const restart = () => { const newBoard = new BoardModel(); newBoard.createCells(); newBoard.addFigure(Labels.Dark, 1, 2); newBoard.addFigure(Labels.Dark, 3, 4); newBoard.addFigure(Labels.Light, 5, 6); newBoard.addFigure(Labels.Light, 7, 2); setBoard(newBoard); }; And we can see that 4 figures are added to our game board: In the next parts, we will continue our journey. Link to the repo