BUILD YOUR OWN GAME

Have you ever wondered if you could build your own chess game and play it with an AI engine on the browser? If you do, then you might...

BUILD YOUR OWN GAME
Written by TechnoLynx Published on 30 Jan 2023

It is no wonder that chess is the most popular intellectual game in the world. We can trace this game to the 6th century, which has stuck because of its complex and challenging nature until these days.

The first “chess machine” was invented by the Hungarian Wolfgang Von Kempelen (Kempelen Farkas) in 1770, known as the Mechanical Turk. The inventor claimed that the machine was fully automatic. Moreover, its elaborate mechanism and the fact that it had defeated even chess masters convinced many people. But did a successful chess machine already exist in the late 18th century? The answer is no. The truth was that Wolfgang von Kempelen had hired several chess masters and hid them inside the machine. The hidden players then controlled the mechanical arms of the Turk manually. As a result, the chess machine has traveled worldwide, impressed people everywhere, and inspired them to create their own.

In the last century, the concern became creating a machine with human-like intelligence. The mathematician and computer scientist Alan Turing was amongst the first to start laying down the principles of chess AI algorithms. Many are familiar with his name thanks to the recent movie “The Imitation Game,” about how he helped crack the German ciphers encoded with the Enigma machine [4]. However, his work on artificial intelligence led him toward chess, specifically the theory of using computers to play chess.

Around 1948, he and his colleague David Gawen Champerowne wrote the first computer chess program, called Turochamp, using the following basic principles that each piece on the board was assigned a value: pawn = 1, knight = 3, bishop = 3.5, rook = 5, queen = 10, and king = 1000. The algorithm foresaw two moves to calculate every possible combination of moves and then chose the most rewarding one. He tested his algorithm by challenging one of his friends, Alick Glennie. Since computers at the time were not up to heavy computing calculations, Turing calculated the moves on paper by hand (which took him more than 30 minutes on the average per move). Unfortunately, Turing and his algorithm lost the match. Nevertheless, he constructed the earliest known computer chess program.

So now, what about you? Are you ready to build your chessboard on a webpage?

Building the chessboard

In this section, we will teach you how to build a simple chessboard using html and javascript (no css styling needed). The method used may not be the best, yet it is easy to understand.

Let us break it into simple steps and statements:

a) Creating the canvas: to draw the chessboard, we brought a white canvas element in html with a specific height and width to stick the pieces on it later. The code in html is as simple as:





<canvas width=”512” height=”512” id=”canvas”></canvas>




b) Drawing the squares:

Since we have a white canvas, we chose to draw the squares and pieces using functions in JavaScript. The squares are created by slicing the canvas into 64 identical squares alternating between black and white. The code for this is as follows:

Note: dimension = 8 is the number of files/ ranks in the chessboard and the context.globalAlpha is set to 1 to make the canvas rendering fully opaque.



function draw_board()
{
    let square_colors = ["LightGray", "DarkGray"];
    context.globalAlpha = 1;

    for (let r = 0; r < dimension; ++r)
    {
        for (let c = 0; c < dimension; ++c)
        {
            context.fillStyle = square_colors[(r + c) % 2];
            context.fillRect(
                c * square_width,
                r * square_height,
                square_width,
                square_height);
        }
    }
}


c) Drawing the pieces:

The pieces are of a complex shape; therefore, images of them are easier to insert and use. You may get the images from any source and import them into your js code. Then we can organize them into a list to put them in a loop. You can see here that we used the instance game_state to place each piece in its correct initial position. Nevertheless, it is better explained later in the article.



function draw_pieces()
{
    context.globalAlpha = 1;

    for (let r = 0; r < dimension; ++r)
    {
        for (let c = 0; c < dimension; ++c)
        {
            let piece = game_state.board[r][c];
            let piece_image = images[piece];

            if (piece != "--")
            {
                context.drawImage(
                    piece_image, c * square_width, r * square_height);
            }
        }
    }
}


Now that we have all the drawing elements, how do we link them all together?

We link the html body with an initiating function that defines the canvas elements and events.

So in html, we add the following in the body tag:



body onload="window.index.init()"


Then in the js code:



export function init()
{
    canvas = document.getElementById("canvas");
    context = canvas.getContext("2d");
    square_width = canvas.width / 8;
    square_height = canvas.height / 8;
    for (let [name, image] of Object.entries(image_map))
    {
        images[name] = new Image(64, 64);
        images[name].onload = draw_pieces;
        images[name].src = image;
    }

    draw_board();
}


The view of our chessboard on the page after building the html
The view of our chessboard on the page after building the html

Basic functionality of a chess game

To create a real chess game, we must move the piece and keep track of their positions at all times. However, this is not as simple as it sounds in programming. Let’s say we want to create a class that defines the game and let’s call it game_state. It needs to state the initial board position and the offset of each piece and move it accordingly while logging the new board position. For example, this snippet code shows the board representation and then the knight offset.



export class Game_state
{
    constructor()
    {
        this.board =
        [
            ["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"],
            ["bP", "bP", "bP", "bP", "bP", "bP", "bP", "bP"],
            ["--", "--", "--", "--", "--", "--", "--", "--"],
            ["--", "--", "--", "--", "--", "--", "--", "--"],
            ["--", "--", "--", "--", "--", "--", "--", "--"],
            ["--", "--", "--", "--", "--", "--", "--", "--"],
            ["wP", "wP", "wP", "wP", "wP", "wP", "wP", "wP"],
            ["wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"]
        ];
        this.knight_offsets =
        [
            [ 2,  1],
            [ 2, -1],
            [ 1,  2],
            [ 1, -2],
            [-1,  2],
            [-1, -2],
            [-2, -1],
            [-2,  1]
        ];
    }
}


Moving the pieces: There are different types of moves in chess. Any move could be a start, end, board move, capturing a piece, promotion move, en-passant move, or castle move. Each of them should be defined. For example, an en-passant move can be made with:



if (move.en_passant_move)
        {
            const direction = this.white_to_move ? 1 : -1;

            this.board[move.end[0] + direction][move.end[1]] = "--";
        }


By now, the piece could move, but what if the move was illegal?

Each move needs to be validated. If the move is illegal, then the piece should be retracted automatically. Yet, suppose you want to make it easier for the player to commit legal moves only. In that case, you can define all the valid moves of a piece and highlight them when the player touches (clicks on) any piece to move. For example, you may check all the possible moves of a piece with a code similar to this:



get_all_possible_moves()
    {
        let moves = [];

        for (let row = 0; row < this.board.length; ++row)
        {
            for (let column = 0; column < this.board[row].length; ++column)
            {
                let player = this.board[row][column][0];
                let current_color = this.white_to_move ? "w" : "b";

                if (player == current_color)
                {
                    let piece = this.board[row][column][1];

                    this.move_methods[piece].call(this, row, column, moves);
                }
            }
        }

        return moves;
    }


Did you make a move and regret it or make a mistake? Then you need to introduce the undo button to your game.

It is easily implemented in HTML by adding the following:

<div>
	<button onclick="window.index.undo_click()">Undo</button>
</div>

In js code, you may create the undo function as a method of the game_state, which allows you to edit other attributes in game-tracking, such as making a move and game-over status. Check it below:



export function undo_click()
{
    game_state.undo_move();
    made_move = true;
    game_over = false;

    refresh_state();
}


In concept, the undo method is purely popping the last move out of the log. Nevertheless, what if the move was a promotion or en-passant? Then we need to define more conditions that cover all possibilities. Let’s look at the code snippet below. It checks the move type as promotion and takes multiple actions to revoke it, including the return of the captured piece during the move.



if (last_move.promotion_move)
        {
            const color = this.white_to_move ? "b" : "w";

            this.board[last_move.end[0]][last_move.end[1]] =
                last_move.piece_captured;
            this.board[last_move.start[0]][last_move.start[1]] = color + 'P';
        }
		

Now we have all bases covered to start playing.

But do you want to play alone? Absolutely not. Let’s create an AI opponent.

The first thing that you need to build an AI opponent is data. Let’s put it as you feed the model some inputs to teach it how to digest them and generate the specific output. For chess, these data are recorded games between real players. These recorded games are formed as Portable Game Notation (PGN) files. Fortunately, many PGN databases are available online for free, and you may use any. Yet keep in your mind that these notation files need to be parsed. Our recommendation is to use chess.pgn in Python.

So let’s consider that you already have parsed the database and are ready to use it; thus, it’s time to build our AI model. We can create a sequential model out of multiple layers using TensorFlow and Keras. As you may see below, the model consists of 2 layers of 2D Convolutional Neural Networks (CNN), Flatten, 2 layers of Dense Neural Networks (DNN), and a softmax layer. You can notice that we used the Adam optimizer and binary loss entropy function to optimize the training process.



model = models.Sequential()
model.add(layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same',
                        activation='relu', input_shape=(8, 8, 12)))
model.add(layers.Conv2D(filters=32, kernel_size=(5, 5), strides=(1, 1),
                        padding='valid', activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(2))
model.add(tf.keras.layers.Softmax())
model.summary()
model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])
			  

Note: after building the model and training it in Python, you can convert it into Javascript code.

After training the model, you need a function that will enable the AI engine to move a piece based on predicting the best valid move possible at a specific game state. In other words, you need to link the AI prediction with the chess functions provided earlier in the Javascript code. For example, selecting the best move will be as the following:



export function find_model_best_move(game_state, valid_moves)
{   let max_score = 0;
    let next_move = null;
    if (!model)
    {
        return next_move;
    }
    for (const move of valid_moves)
    {
        let scores;
        let score;
        // Make a valid move
        game_state.make_move(move);
        // Expand current position to 4D b/c model input requirement
        const input = tf.tensor([ game_state.get_position() ]);
        // Model predicts score (shape:(1,2)) of current position
        scores = model.predict(input).arraySync();
        console.assert(scores[0][0] + scores[0][1] >= 0.99);
        score = scores[0][game_state.white_to_move ? 0 : 1];
        if (score > max_score)
        {
            max_score = score;
            next_move = move;
        }
    }
    return next_move;
}


Don’t forget to add the button and link it with a function to enable the AI feature.

Are you wondering how to link all the files together? Well, module bundling is the solution to that.

Here we reach the end of this story. We provided tutorial-like instructions and discussion to build your own chess game on a webpage, define your desired rules, and program your ultimate opponent. Nevertheless, our description was brief in some points, but we hope our article encouraged you to go and search further.

What is your next move?

For the full code to build your own game, please check our repository on GitHub.

If you are interested in playing against our AI engine, please visit the page under Demos.

Cover image: by Felix Mittermeier on Unsplash

Multi-Agent Architecture for AI Systems: When Coordination Adds Value

Multi-Agent Architecture for AI Systems: When Coordination Adds Value

8/05/2026

Multi-agent AI architectures coordinate multiple LLM agents for complex tasks. When they add value, common coordination patterns, and where they break.

Multi-Agent Systems: Design Principles and Production Reliability

Multi-Agent Systems: Design Principles and Production Reliability

8/05/2026

Multi-agent systems decompose complex tasks across specialized agents. Design principles, failure modes, and when multi-agent adds value vs complexity.

LLM Types: Decoder-Only, Encoder-Decoder, and Encoder-Only Models

LLM Types: Decoder-Only, Encoder-Decoder, and Encoder-Only Models

8/05/2026

LLM architecture type—decoder-only, encoder-decoder, encoder-only—determines what tasks each model handles well and what deployment constraints it carries.

LLM Orchestration Frameworks: LangChain, LlamaIndex, LangGraph Compared

LLM Orchestration Frameworks: LangChain, LlamaIndex, LangGraph Compared

8/05/2026

LangChain, LlamaIndex, and LangGraph solve different problems. Choosing the wrong framework adds abstraction without value. A practical decision framework.

Generative AI Architecture Patterns: Transformer, Diffusion, and When Each Applies

Generative AI Architecture Patterns: Transformer, Diffusion, and When Each Applies

8/05/2026

Transformer vs diffusion architecture determines deployment constraints. Memory footprint, latency profile, and controllability differ substantially.

Diffusion Models in ML Beyond Images: Audio, Protein, and Tabular Applications

Diffusion Models in ML Beyond Images: Audio, Protein, and Tabular Applications

7/05/2026

Diffusion extends beyond images to audio, protein structure, molecules, and tabular data. What each domain gains and loses from the diffusion approach.

Diffusion Models Explained: The Forward and Reverse Process

Diffusion Models Explained: The Forward and Reverse Process

7/05/2026

Diffusion models learn to reverse a noise process. The forward (adding noise) and reverse (denoising) processes, score matching, and why this produces.

Diffusion Models Beat GANs on Image Synthesis: What Changed and What Remains

Diffusion Models Beat GANs on Image Synthesis: What Changed and What Remains

7/05/2026

Diffusion models surpassed GANs on FID for image synthesis. What metrics shifted, where GANs still win, and what it means for production image generation.

The Diffusion Forward Process: How Noise Schedules Shape Generation Quality

The Diffusion Forward Process: How Noise Schedules Shape Generation Quality

7/05/2026

The forward process in diffusion models adds noise on a schedule. How linear, cosine, and custom schedules affect image quality and training stability.

Autonomous AI in Software Engineering: What Agents Actually Do

Autonomous AI in Software Engineering: What Agents Actually Do

6/05/2026

What autonomous AI software engineering agents can actually do today: code generation quality, context limits, test generation, and where human oversight.

AI Agent Design Patterns: ReAct, Plan-and-Execute, and Reflection Loops

AI Agent Design Patterns: ReAct, Plan-and-Execute, and Reflection Loops

6/05/2026

AI agent patterns—ReAct, Plan-and-Execute, Reflection—solve different failure modes. Choosing the right pattern determines reliability more than model.

Agentic AI in 2025–2026: What Is Actually Shipping vs What Is Still Research

Agentic AI in 2025–2026: What Is Actually Shipping vs What Is Still Research

6/05/2026

Agentic AI is moving from demos to production. What's deployed today, what's still research, and how to evaluate claims about autonomous AI systems.

Agent-Based Modeling in AI: When to Use Simulation vs Reactive Agents

6/05/2026

Agent-based modeling simulates populations of interacting entities. When it's the right choice over LLM-based agents and how to combine both approaches.

AI Orchestration: How to Coordinate Multiple Agents and Models Without Chaos

5/05/2026

AI orchestration coordinates multiple models through defined handoff protocols. Without it, multi-agent systems produce compounding inconsistencies.

Building AI Agents: A Practical Guide from Single-Tool to Multi-Step Orchestration

5/05/2026

Production agent development follows a narrow-first pattern: single tool, single goal, deterministic fallback, then widen with observability.

Enterprise AI Search: Why Retrieval Architecture Matters More Than Model Choice

5/05/2026

Enterprise AI search quality depends on chunking and retrieval design more than on the LLM. Poor retrieval with a strong LLM yields confident wrong answers.

Choosing an AI Agent Development Partner: What to Evaluate Beyond Demo Quality

5/05/2026

Most AI agent demos work on curated inputs. Production viability requires error handling, fallback chains, and observability that demos never test.

LLM Agents Explained: What Makes an AI Agent More Than Just a Language Model

5/05/2026

An LLM agent adds tool use, memory, and planning loops to a base model. Agent reliability depends on orchestration more than model benchmark scores.

Best AI Agents in 2026: A Practitioner's Guide to What Each Actually Does Well

4/05/2026

No single AI agent excels at all task types. The best choice depends on whether your workflow is structured or unstructured.

Agent Framework Selection for Edge-Constrained Inference Targets

2/05/2026

Selecting an agent framework for partial on-device inference: four axes that decide whether a desktop-class framework survives the edge-target boundary.

What It Takes to Move a GenAI Prototype into Production

27/04/2026

A working GenAI prototype is not production-ready. It still needs evaluation pipelines, guardrails, cost controls, latency optimisation, and monitoring.

How to Choose an AI Agent Framework for Production

26/04/2026

Agent frameworks differ on observability, tool integration, error recovery, and readiness. LangGraph, AutoGen, and CrewAI target different needs.

How Multi-Agent Systems Coordinate — and Where They Break

25/04/2026

Multi-agent AI decomposes tasks across specialised agents. Conflicting plans, hallucinated handoffs, and unbounded loops are the production risks.

Agentic AI vs Generative AI: Architecture, Autonomy, and Deployment Differences

24/04/2026

Generative AI produces output on request. Agentic AI takes autonomous multi-step actions toward a goal. The core difference is execution autonomy.

GAN vs Diffusion Model: Architecture Differences That Matter for Deployment

23/04/2026

GANs produce sharp output in one pass but train unstably. Diffusion models train stably but cost more at inference. Choose based on deployment constraints.

What Types of Generative AI Models Exist Beyond LLMs

22/04/2026

LLMs dominate GenAI, but diffusion models, GANs, VAEs, and neural codecs handle image, audio, video, and 3D generation with different architectures.

Why Generative AI Projects Fail Before They Launch

21/04/2026

GenAI project failures cluster around scope inflation, evaluation gaps, and integration underestimation. The patterns are predictable and preventable.

How to Evaluate GenAI Use Case Feasibility Before You Build

20/04/2026

Most GenAI use cases fail at feasibility, not implementation. Assess data, accuracy tolerance, and integration complexity before building.

Visual Computing in Life Sciences: Real-Time Insights

6/11/2025

Learn how visual computing transforms life sciences with real-time analysis, improving research, diagnostics, and decision-making for faster, accurate outcomes.

AI-Driven Aseptic Operations: Eliminating Contamination

21/10/2025

Learn how AI-driven aseptic operations help pharmaceutical manufacturers reduce contamination, improve risk assessment, and meet FDA standards for safe, sterile products.

AI Visual Quality Control: Assuring Safe Pharma Packaging

20/10/2025

See how AI-powered visual quality control ensures safe, compliant, and high-quality pharmaceutical packaging across a wide range of products.

AI for Reliable and Efficient Pharmaceutical Manufacturing

15/10/2025

See how AI and generative AI help pharmaceutical companies optimise manufacturing processes, improve product quality, and ensure safety and efficacy.

Barcodes in Pharma: From DSCSA to FMD in Practice

25/09/2025

What the 2‑D barcode and seal on your medicine mean, how pharmacists scan packs, and why these checks stop fake medicines reaching you.

Pharma’s EU AI Act Playbook: GxP‑Ready Steps

24/09/2025

A clear, GxP‑ready guide to the EU AI Act for pharma and medical devices: risk tiers, GPAI, codes of practice, governance, and audit‑ready execution.

Cell Painting: Fixing Batch Effects for Reliable HCS

23/09/2025

Reduce batch effects in Cell Painting. Standardise assays, adopt OME‑Zarr, and apply robust harmonisation to make high‑content screening reproducible.

Explainable Digital Pathology: QC that Scales

22/09/2025

Raise slide quality and trust in AI for digital pathology with robust WSI validation, automated QC, and explainable outputs that fit clinical workflows.

Validation‑Ready AI for GxP Operations in Pharma

19/09/2025

Make AI systems validation‑ready across GxP. GMP, GCP and GLP. Build secure, audit‑ready workflows for data integrity, manufacturing and clinical trials.

Edge Imaging for Reliable Cell and Gene Therapy

17/09/2025

Edge imaging transforms cell & gene therapy manufacturing with real‑time monitoring, risk‑based control and Annex 1 compliance for safer, faster production.

AI in Genetic Variant Interpretation: From Data to Meaning

15/09/2025

AI enhances genetic variant interpretation by analysing DNA sequences, de novo variants, and complex patterns in the human genome for clinical precision.

AI Visual Inspection for Sterile Injectables

11/09/2025

Improve quality and safety in sterile injectable manufacturing with AI‑driven visual inspection, real‑time control and cost‑effective compliance.

Predicting Clinical Trial Risks with AI in Real Time

5/09/2025

AI helps pharma teams predict clinical trial risks, side effects, and deviations in real time, improving decisions and protecting human subjects.

Generative AI in Pharma: Compliance and Innovation

1/09/2025

Generative AI transforms pharma by streamlining compliance, drug discovery, and documentation with AI models, GANs, and synthetic training data for safer innovation.

AI for Pharma Compliance: Smarter Quality, Safer Trials

27/08/2025

AI helps pharma teams improve compliance, reduce risk, and manage quality in clinical trials and manufacturing with real-time insights.

Markov Chains in Generative AI Explained

31/03/2025

Discover how Markov chains power Generative AI models, from text generation to computer vision and AR/VR/XR. Explore real-world applications!

Augmented Reality Entertainment: Real-Time Digital Fun

28/03/2025

See how augmented reality entertainment is changing film, gaming, and live events with digital elements, AR apps, and real-time interactive experiences.

Optimising LLMOps: Improvement Beyond Limits!

2/01/2025

LLMOps optimisation: profiling throughput and latency bottlenecks in LLM serving systems and the infrastructure decisions that determine sustainable performance under load.

Case Study: WebSDK Client-Side ML Inference Optimisation

20/11/2024

Browser-deployed face quality classifier rebuilt around a single multiclassifier, WebGL pixel capture, and explicit device-capability gating.

Why do we need GPU in AI?

16/07/2024

Discover why GPUs are essential in AI. Learn about their role in machine learning, neural networks, and deep learning projects.

Back See Blogs
arrow icon