Chapter 3

Engine Structure

Before looking at how ABC plays chess, it is useful to understand how the code itself is organized. The engine is intentionally split into a small number of simple files, with each file responsible for a particular part of the program.

At the center of the project is a single header file called abc.h. This file contains the definitions that are shared across the entire engine: enums, constants, structures, external variables, and function declarations.

The purpose of keeping these definitions in one place is simple. Every source file in the engine can include abc.h and immediately have access to the common language of the program. A piece type, a move structure, a board representation, or a function declared in the header can be used wherever it is needed without having to duplicate its definition.

The Common Header

The abc.h file can be thought of as the interface between the different parts of the engine. It tells each source file what types, variables, and functions exist, without containing the implementation of those functions.

This keeps the individual source files relatively independent. Move generation does not need to contain the definitions of the search structures, and the evaluation code does not need to redefine the board representation. They simply include the common header and use the definitions provided by it.

Shared Variables

ABC also has a file called defs.c. Its purpose is to contain the actual initialization of the variables that are shared throughout the engine.

This is closely related to the extern declarations in abc.h. The header tells the compiler that a variable exists somewhere, while defs.c provides the actual storage for that variable.

For example, a variable can be declared in the header with extern and then defined once in defs.c. Every other source file can include abc.h and access the same variable.

This gives ABC a single shared state while keeping the declarations and definitions separate. It also prevents every source file from creating its own separate copy of the same global variable.

One File, One Responsibility

After the common definitions and shared variables are taken care of, the rest of the engine is divided by functionality. Each source file contains the functions responsible for a particular part of the chess engine.

For example, one file can contain board-related functions, another can handle move generation, another can contain the evaluation code, and another can implement the search algorithm.

The exact division is not intended to introduce a complicated software architecture. Quite the opposite. The goal is to make it easy to find the code responsible for a particular task.

Keeping the Structure Simple

There are many ways to organize a larger C project, and a production engine might use a much more elaborate structure. ABC deliberately avoids unnecessary complexity.

The basic organization is therefore straightforward: abc.h contains the shared definitions and declarations, defs.c contains the shared variable definitions and initialization, and the remaining source files contain the actual implementations of the different engine components.

This structure also fits the educational purpose of ABC. There is little abstraction between the source code and the concepts being implemented. When we introduce a new part of the engine, there should be a clear place where its implementation lives.

As the engine grows, this separation will become increasingly useful. Chess engines contain many different systems that have to work together, but understanding them one at a time is much easier than trying to understand the entire program as a single piece of code.

ABC therefore starts with a simple principle: shared definitions belong together, shared state is defined in one place, and each engine component gets its own implementation.