English version | Русская версия  
 
Кветка логотип
Кветка

Программа для анализа шахматных партий
 
 

Описание формата баз партий от Chessbase.

Весь этот текст --- плод многочасовых усилий в попытке понять, как же работает Chessbase-овский формат файлов CBH и связанных с ним. Поэтому описание формата местами будет неполной. Некоторые файлы (например, архивный CBV файл) здесь вообще не освещаются. Текст актуален для Chessbase 9.0, в будущих версиях формат может измениться.

Все целочисленные данные, если не оговорено обратное, записаны в формате big-endian (от старшего байта к младшему).

База партий от Chessbase состоит из следующих файлов:

  • CBH --- содержит список партий базы, а также их связи с данными из остальных файлов;
  • CBG --- непосредственно информация о партиях (последовательность ходов);
  • CBA --- комментарии к партии;
  • CBP --- информация об игроках;
  • CBT --- информация о турнирах;
  • CBC --- информация о комментаторах;
  • CBS --- информация об источниках партий;
  • CBE --- информация о командах;
  • CBM --- ?
  • CBJ --- Помимо всего прочего содержит связи между партиями и командами;
  • CBB --- ?

CBH файл

Это основной файл базы партий. Он содержит общую информацию о базе, а также связывает всю информацию о каждой партии (или сопроводительном тексте) из остальных файлов воедино.

Состоит из:

  • заголовка (46 б);
  • последовательности блоков (по 46 б каждый).
Каждый блок содержит информацию ровно об одной партии или сопроводительном тексте.

Формат заголовка:

  • Смещение 0, длина 6 б --- сигнатура. Может принимать значения 00 00 2C 00 2E 01, если база создана с помощью ChessBase 9, или 00 00 24 00 2E 01, если создана с помощью CBlight.
  • Смещение 6, длина 4 б --- число партий в базе + 1.
  • Смещение 12, длина 4 б --- ??, может быть равным 2.
  • Смещение 16, длина 4 б --- ??, может быть равным 3.
  • Смещение 20, длина 4 б --- ??, может быть равным 3.
  • Смещение 40, длина 4 б --- либо число партий в базе +1 (?), либо 0 (?).
Остальные байты равны нулю (?).

Формат блока:

  • Смещение 0, длина 1 б --- набор флагов, описывающих блок:
    • биты 0,1: (?) указывают на тип блока. Возможные значения:
      • 1: записана партия;
      • 3: записан сопроводительный текст.
      В оригинальном тексте утверждалось, что бит 0 указывает на партию, а бит 1 --- на текст, однако тогда неясно, чему должно соответствовать значение 3.
    • Бит 7: равен 1, если блок помечен как удалённый.
  • Смещение 1, длина 4 б --- позиция в файле CBG, откуда начинается описание партии (или сопроводительного текста).

Далее формат блока зависит от его типа.

Для описания партии:

  • Смещение 5, длина 4 б --- позиция в файле CBA, откуда начинается описание комментариев к партии.
  • Смещение 9, длина 3 б --- номер блока в файле CBP для игрока белыми.
  • Смещение 12, длина 3 б --- номер блока в файле CBP для игрока чёрными.
  • Смещение 15, длина 3 б --- номер турнира в файле CBT.
  • Смещение 18, длина 3 б --- номер комментатора в файле CBC.
  • Смещение 21, длина 3 б --- номер источника в файле CBS.
  • Смещение 24, длина 3 б --- дата проведения партии:
    • биты 0 -- 4: день (0 --- день не задан);
    • биты 5 -- 8: месяц (0 --- месяц не задан);
    • биты 9 -- 20: год (0 --- год не задан).
  • Смещение 27, длина 1 б, биты 0 - 2 --- результат партии:
    • 0: 0-1 (чёрные выиграли);
    • 1: 1/2-1/2 (ничья);
    • 2: 1-0 (белые выиграли);
    • 3: оценивается линия в партии. Сама оценка будет приведена в следующем байте.
    • 4: -:+ (не знаю, что значит);
    • 5: =:= (не знаю, что значит);
    • 6: +:- (не знаю, что значит);
    • 7: 0-0 (проигрыш засчитан обоим сторонам?).
  • Смещение 28, длина 1 б --- оценка линии в партии (устанавливается только если предыдущий байт равен 3):
    • 0x00: оценка не задана;
    • 0x0B: позиция равная (=);
    • 0x0D: позиция неясная;
    • 0x0E: у белых небольшое преимущество (+/=);
    • 0x0F: у чёрных небольшое преимущество (+/=);
    • 0x10: у белых явное преимущество (+/-);
    • 0x11: у чёрных явное преимущество (-/+);
    • 0x12: белые выигрывают (+-);
    • 0x13: чёрные выигрывают (-+);
    • 0x20: развитие превосходства;
    • 0x24: с инициативой;
    • 0x28: с атакой;
    • 0x2C: с компенсацией материала;
    • 0x84: с контригрой;
    • 0x8A: цейтнот;
    • 0x92: новинка.
  • Смещение 29, длина 1 б --- раунд (0 --- раунд не задан).
  • Смещение 30, длина 1 б --- подраунд (0 --- подраунд не задан).
  • Смещение 31, длина 2 б --- Elo рейтинг белых (0 --- рейтинг не задан).
  • Смещение 33, длина 2 б --- Elo рейтинг чёрных (0 --- рейтинг не задан).
  • Смещение 35, длина 2 б --- описание дебюта в формате ECO. Подробнее:
    • Биты 7 -- 15: основное описание дебюта (0 --- не задан, 1 --- A00, ... , 100 --- A99, ... , 500 --- E99).
    • Биты 0 -- 6: номер варианта дебюта (от 00 до 99,).
  • Смещение 37, длина 2 б --- флаги медалей.
    • бит 0: лучшая партия;
    • бит 1: избранный турнир (decided tournament);
    • бит 2: модельная партия (дебютный план);
    • бит 3: новизна;
    • бит 4: пешечная структура;
    • бит 5: стратегия;
    • бит 6: тактика;
    • бит 7: с атакой;
    • бит 8: жертва;
    • бит 9: защита;
    • бит 10: материал;
    • бит 11: игра фигур;
    • бит 12: эндшпиль;
    • бит 13: тактическая ошибка;
    • бит 14: стратегическая ошибка;
    • бит 15: пользовательская медаль.
  • Смещение 39, длина 1 б --- флаги:
    • бит 0: партия содержит критическую позицию;
    • бит 1: партия содержит заголовок для переписки (correspondence header).
  • Смещение 40, длина 1 б --- флаги:
    • бит 0: партия содержит встроенное аудио;
    • бит 1: содержит встроенную картинку;
    • бит 2: содержит встроенное видео;
    • бит 3: содержит ссылку на другую партию;
    • бит 4: содержит структуру путей (path structure);
    • бит 5: содержит путь фигуры (piece path);
  • Смещение 41, длина 1 б, бит 1 --- значение 1 означает, что партия содержит упражнения.
  • Смещение 42, длина 1 б --- флаги:
    • бит 0: P (партия начинается с нестандартной позиции);
    • бит 1: v (содержит ответвления);
    • бит 2: с (содержит комментарии);
    • бит 3: s (содержит символы);
    • бит 4: партия откомментирована с использованием цветных клеток;
    • бит 5: партия откомментирована с использованием стрелок;
    • бит 7: партия содержит уведомления о времени (?, time notifications)
  • Смещение 43, длина 1 б --- ?
  • Смещение 44, длина 1 б --- флаги:
    • биты 0 -- 1: ранжируют число ходов в ответвлениях (должен быть задан бит 1 по смещению 42):
      • 0 --- v (от 1 до 50 ходов);
      • 1 --- V (от 51 до 300 ходов);
      • 2 --- r (от 301 до 1000 ходов);
      • 3 --- R (более 1000 ходов).
    • бит 2: C (содержит много комментариев, должен быть задан бит 2 по смещению 42).
    • бит 3: S (много символов, должен быть задан бит 3 по смещению 42).
    • бит 4: партия откомментирована с использованием цветных клеток как минимум в десяти позициях.
    • бит 5: партия откомментирована с использованием стрелок как минимум в десяти позициях.
  • Смещение 45, длина 1 б --- число ходов в основном варианте. Если оно равно 255, то корректное число должно вычисляться непосредственно из данных партии.

Для сопроводительного текста:

  • Смещение 5, длина 2 б --- ?
  • Смещение 7, длина 3 б --- номер турнира в файле CBT.
  • Смещение 10, длина 3 б --- номер источника в файле CBS.
  • Смещение 13, длина 3 б --- номер комментатора в файле CBC.
  • Смещение 16, длина 1 б --- раунд (0 --- раунд не задан).
  • Смещение 17, длина 1 б --- ? (всегда равен 0?).
  • Смещение 18, длина 1 б, бит 2 --- значение 1 означает, что в тексте содержится видео поток wmv.
  • Смещение 19, длина 1 б --- флаги:
    • бит 0: текст содержит ссылку на аудио;
    • бит 1: текст содержит ссылку на изображение;
    • бит 2: текст содержит ссылку на видео.

CBG файл

Хранит информацию непосредственно о партиях (последовательность ходов) и сопроводительных текстах. Состоит из:
  • заголовка (10 б);
  • последовательности блоков.

В оригинальном тексте написано, что размер заголовка 26 б, так что, возможно, для различных версий формата его размер различается.

Каждый блок описывает одну партию либо сопроводительный текст. Длина блоков не фиксирована, между двумя соседними блоками могут следовать мусорные байты. Информация о расположении блока для заданной партии или текста хранится в CBH файле.

Формат заголовка

  • Смещение 0, длина 2 б --- позиция первой записанной партии (?).
  • Смещение 2, длина 4 б --- указывает на конец CBG файла (совпадает с длиной файла).
  • Смещение 6, длина 4 б --- суммарное значение изменённых байтов по всем партиям (?).

Формат данных, кодирующих сопроводительный текст

Смещение здесь будет вычисляться относительно позиции начала данных о тексте, указанной в CBH файле.
  • Смещение 0, длина 4 б --- битовая карта:
    • биты 0 -- 29: размер блока данных о сопроводительном тексте в байтах, включая данное поле.
    • бит 30: партия начинается с нестандартной позиции.
    • бит 31: данные партии не закодированы (только для сопроводительного текста?).
  • Смещение 4, длина 2 б --- ? (256 ?).
  • Смещение 6, длина 2 б (little-endian) --- количество заголовков текста (может равняться нулю).
  • Смещение 8 --- перечисляются все заголовки.

Формат заголовка:

Смещение здесь указывается относительно начала заголовка.
  • Смещение 0, длина 2 б (little-endian) --- язык заголовка. Возможные значения:
    • 0: английский;
    • 1: немецкий;
    • 2: французский;
    • 3: испанский;
    • 4: итальянский;
    • 5: голландский.
    • Возможно, есть и другие языки.
  • Смещение 2, длина 2 б (little-endian) --- длина заголовка в байтах.
  • Смещение 4 (строка) --- заголовок.

Дальнейшее описание сопроводительного текста покрыто мраком.

Формат данных партии

Здесь смещение вычисляется относительно позиции начала данных о партии, указанной в CBH файле.
  • Смещение 0, длина 4 б --- битовая карта:
    • биты 0 -- 29: размер блока данных о партии в байтах, включая данное поле.
    • бит 30: партия начинается с нестандартной позиции.
    • бит 31: данные партии не закодированы (только для сопроводительного текста?).
  • Смещение 4 --- если партия начинается с нестандартной позиции, то начинается её описание.
  • Далее следует описание партии (последовательность ходов, см. далее)

Описание нестандартной позиции

Здесь смещение указывается относительно начала описания.
  • Смещение 0, длина 1 б --- всегда 1 (?).
  • Смещение 1, длина 1 б --- битовая карта:
    • биты 0 -- 3 отвечают за продвижение пешки. Значение 0 означает, что никакой пешки не продвинулось. Значения от 1 до 8 означают, что продвинулась пешка в столбце от a до h соответственно.
    • бит 4: равен 0, если ходят белые. В противном случае равен 1.
  • Смещение 2, длина 1 б --- флаги, отвечающие за возможные рокировки:
    • бит 0: возможна рокировка O-O-O белыми.
    • бит 1: возможна рокировка O-O белыми.
    • бит 2: возможна рокировка O-O-O чёрными.
    • бит 3: возможна рокировка O-O чёрными.
    Примечание: рокировка необязательно должна быть доступна следующим ходом из начальной позиции. Каждый бит указывает на потенциальную возможность сделать рокировку в будущем. Другими словами, он установлен в 1, если соответствующая ладья и король не сдвигались с места.

  • Смещение 3, длина 1 б --- номер первого хода в партии.
  • Смещение 4, длина 24 б --- перечисление всех фигур на доске в виде потока бит. Для фигур используются следующие коды:
    • 0: пустая клетка;
    • 10001: белый король;
    • 10010: белый ферзь;
    • 10011: белый конь;
    • 10100: белый слон;
    • 10101: белая ладья;
    • 10110: белая пешка;
    • 11001: чёрный король;
    • 11010: чёрный ферзь;
    • 11011: чёрный конь;
    • 11100: чёрный слон;
    • 11101: чёрная ладья;
    • 11110: чёрная пешка.
    Фигуры перечисляются в следующем порядке: a1, ..., a8, b1, ..., b8, ..., h8.

Описание ходов

В CBG файле все ходы представлены потоком байт. Большинство ходов кодируются одним байтом, описывающим относительное перемещение фигуры. Для удобства все фигуры кроме короля нумеруются. Так, в начальной позиции номера белых фигур распределены так:
пешка 1 | пешка 2 | пешка 3 | пешка 4 | пешка 5 | пешка 6 | пешка 7 | пешка 8
--------+---------+---------+---------+---------+---------+---------+--------
ладья 1 | конь 1  | слон 1  | ферзь 1 | король  | слон 2  | конь 2  | ладья 2
Номера чёрных фигур определены симметрично относительно средней горизонтали доски.

Если в результате продвижения пешки появляется новая фигура, то ей присваивается следующий свободный номер (для коня, слона и ладьи это будет 3, а для ферзя --- 2). Следующей за ней появившейся фигуре того же достоинства снова присваивается свободный номер (теперь это будет 4 или 3).

Если происходит взятие фигуры 1 (любой, кроме пешки), то фигура 2 становится новой фигурой 1, фигура 3 становится новой фигурой 2. Фигуры с большими номерами свой номер не меняют. Для пешек приведенное преобразование не работает. Указанное здесь преобразование с пешками не производится. Они сохраняют свой первоначальный номер на протяжении всей партии.

Ходы могут кодироваться несколькими (двумя) байтами. В этом случае ход задаётся координатами начальной и конечной клеток доски, а также, в случае продвижения пешки, появившейся фигурой. Конкретнее формат такого хода будет представлен позже. Несколькими байтами можно задать любой ход, однако обычно кодируются только те ходы, которые не могут быть представлены одним байтом.

Декодирование потока байт

Поток байт, задающих ходы, хранится в закодированном виде. Для описания процесса декодирования нам понадобится параметр move_num. Он равен числу уже обработанных ходов. Перед началом декодирования он устанавливается в ноль. Далее, после обработки очередного хода, значение move_num увеличивается на 1. Специальные коды, такие как начало и конец ответвления, не изменяют move_num. Ход, состоящий из нескольких байт, увеличивает move_num только на единицу.

При прочтении очередного байта необходимо сначала вычесть из него move_num. Уменьшаемое и вычитаемое при этом должны быть беззнаковыми байтами.

На следующем шаге полученный байт преобразовывается с использованием следующего массива:

const Cbh_Decode : array [0..255] of byte = (
	162,149,67,245,193,61,74,108,83,131,204,124,255,174,104,173,
	209,146,139,141,53,129,94,116,38,142,171,202,253,154,243,160,
	165,21,252,177,30,237,48,234,34,235,167,205,78,111,46,36,
	50,148,65,140,110,88,130,80,187,2,138,216,250,96,222,82,
	186,70,172,41,157,215,223,8,33,1,102,163,241,25,39,181,
	145,213,66,14,180,76,217,24,95,188,37,166,150,4,86,106,
	170,51,28,43,115,240,221,164,55,211,197,16,191,90,35,52,
	117,91,184,85,210,107,9,58,87,18,179,119,72,133,155,15,
	158,199,200,161,127,122,192,189,49,109,246,62,195,17,113,206,
	125,218,168,84,144,151,31,68,64,22,201,227,44,203,132,236,
	159,63,92,230,118,11,60,32,183,54,0,220,231,249,79,247,
	175,6,7,224,26,10,169,75,12,214,99,135,137,29,19,27,
	228,112,5,71,103,123,47,238,226,232,152,13,239,207,196,244,
	251,176,23,153,100,242,212,42,3,77,120,198,254,101,134,136,
	121,69,59,229,73,143,45,185,190,98,147,20,233,208,56,156,
	178,194,89,93,182,114,81,248,40,126,97,57,225,219,105,128);
"Обратный" к Cbh_Decode массив можно найти в файле Cbase9.exe, начиная с позиции 0x7AE4A8, либо в файле CBase10.exe, начиная с позиции 0x9D6530 (массив начинается с байт 0xAA, 0x49, 0x39, 0xD8, 0x5D, 0xC2, 0xB1, 0xB2).

После этих преобразований можно приступать непосредственно к чтению ходов. Кроме них в полученном потоке могут встречаться различные служебные метки.

Одна из меток (код 0xFE) символизирует о том, что для текущей позиции в партии есть альтернативное продолжение. Как только она встречается, информация о ней вместе с текущей позицией должна записываться в стек.

Другая метка (код 0xFF) символизирует о том, что текущая последовательность ходов завершена. Как только такое происходит, из стека извлекается очередная позиция, на неё необходимо перейти. Дальнейший поток байт будет описывать альтернативное продолжение из это позиции. Если оказалось, что стек пуст, то описание партии завершается.

Схематичный алгоритм декодирования потока байт, задающих ходы

Схематично введём тип TVariation для хранения метки об альтернативном продолжении и TVariationStack для стека из таких меток. Их внутренняя реализация нас интересовать не будет.
var i : byte;
    move_num : byte;
    metka : TVariation;
    metka_stack : TVariationStack;
begin
 move_num := 0;
 while true do;
  begin
   i := ReadNextByte(); //читаем и декодируем очередной байт из потока
   i := Cbh_Decode[ i - move_num ];
   
   AnalyseMove( i ); //Дальнейшее распознавание хода
   
   case i of
    $ED : ; //Пропустить этот ход. См. детальное описание ходов далее
    $FE : PushMetka( metka_stack ); //Добавление метки с информацией о текущей позиции в стек
    $FF : if not IsStackEmpty( metka_stack ) then //Проверка, пуст ли стек
     begin
      metka := PopMetka( metka_stack );
      GotoPosition( metka ); //Переходим к позиции, для которой будем далее читать альтернативное продолжение
     end else exit; //Окончание чтения потока байт
    else inc( move_num );
   end;
  end;
end;

Коды ходов

Каждый ход кодируется одним байтом. Он содержит в себе информацию о фигуре, её номере и её относительном перемещении.

Относительное перемещение будет записываться двумя координатами. Они означают, на сколько клеток вправо и вверх перемещается фигура. При этом у доски верхняя и нижняя, а также правая и левая границы "склеены". То есть, перемещение фигуры на 7 клеток вправо означает то же самое, что и перемещение на одну клетку влево.

Определение хода по байту производится с помощью следующей таблицы:

  • 0x00: пустой ход
  • 0x01: король, y+1
  • 0x02: король, x+1, y+1
  • 0x03: король, x+1
  • 0x04: король, x+1, y+7
  • 0x05: король, y+7
  • 0x06: король, x+7, y+7
  • 0x07: король, x+7
  • 0x08: король, x+7, y+1
  • 0x09: король, O-O
  • 0x0A: король, O-O-O
  • 0x0B: ферзь 1, y+1
  • 0x0C: ферзь 1, y+2
  • 0x0D: ферзь 1, y+3
  • 0x0E: ферзь 1, y+4
  • 0x0F: ферзь 1, y+5
  • 0x10: ферзь 1, y+6
  • 0x11: ферзь 1, y+7
  • 0x12: ферзь 1, x+1
  • 0x13: ферзь 1, x+2
  • 0x14: ферзь 1, x+3
  • 0x15: ферзь 1, x+4
  • 0x16: ферзь 1, x+5
  • 0x17: ферзь 1, x+6
  • 0x18: ферзь 1, x+7
  • 0x19: ферзь 1, x+1, y+1
  • 0x1A: ферзь 1, x+2, y+2
  • 0x1B: ферзь 1, x+3, y+3
  • 0x1C: ферзь 1, x+4, y+4
  • 0x1D: ферзь 1, x+5, y+5
  • 0x1E: ферзь 1, x+6, y+6
  • 0x1F: ферзь 1, x+7, y+7
  • 0x20: ферзь 1, x+1, y+7
  • 0x21: ферзь 1, x+2, y+6
  • 0x22: ферзь 1, x+3, y+5
  • 0x23: ферзь 1, x+4, y+4 (обычно не используется)
  • 0x24: ферзь 1, x+5, y+3
  • 0x25: ферзь 1, x+6, y+2
  • 0x26: ферзь 1, x+7, y+1
  • 0x27: ладья 1, y+1
  • 0x28: ладья 1, y+2
  • 0x29: ладья 1, y+3
  • 0x2A: ладья 1, y+4
  • 0x2B: ладья 1, y+5
  • 0x2C: ладья 1, y+6
  • 0x2D: ладья 1, y+7
  • 0x2E: ладья 1, x+1
  • 0x2F: ладья 1, x+2
  • 0x30: ладья 1, x+3
  • 0x31: ладья 1, x+4
  • 0x32: ладья 1, x+5
  • 0x33: ладья 1, x+6
  • 0x34: ладья 1, x+7
  • 0x35: ладья 2, y+1
  • 0x36: ладья 2, y+2
  • 0x37: ладья 2, y+3
  • 0x38: ладья 2, y+4
  • 0x39: ладья 2, y+5
  • 0x3A: ладья 2, y+6
  • 0x3B: ладья 2, y+7
  • 0x3C: ладья 2, x+1
  • 0x3D: ладья 2, x+2
  • 0x3E: ладья 2, x+3
  • 0x3F: ладья 2, x+4
  • 0x41: ладья 2, x+5
  • 0x42: ладья 2, x+6
  • 0x43: ладья 2, x+7
  • 0x44: слон 1, x+1, y+1
  • 0x45: слон 1, x+2, y+2
  • 0x46: слон 1, x+3, y+3
  • 0x47: слон 1, x+4, y+4
  • 0x48: слон 1, x+5, y+5
  • 0x49: слон 1, x+6, y+6
  • 0x4A: слон 1, x+7, y+7
  • 0x4B: слон 1, x+1, y+7
  • 0x4C: слон 1, x+2, y+6
  • 0x4D: слон 1, x+3, y+5
  • 0x4E: слон 1, x+4, y+4 (обычно не используется)
  • 0x4F: слон 1, x+5, y+3
  • 0x50: слон 1, x+6, y+2
  • 0x51: слон 1, x+7, y+1
  • 0x52: слон 2, x+1, y+1
  • 0x53: слон 2, x+2, y+2
  • 0x54: слон 2, x+3, y+3
  • 0x55: слон 2, x+4, y+4
  • 0x56: слон 2, x+5, y+5
  • 0x57: слон 2, x+6, y+6
  • 0x58: слон 2, x+7, y+7
  • 0x59: слон 2, x+1, y+7
  • 0x5A: слон 2, x+2, y+6
  • 0x5B: слон 2, x+3, y+5
  • 0x5C: слон 2, x+4, y+4 (обычно не используется)
  • 0x5D: слон 2, x+5, y+3
  • 0x5E: слон 2, x+6, y+2
  • 0x5F: слон 2, x+7, y+1
  • 0x60: конь 1, x+2, y+1
  • 0x61: конь 1, x+1, y+2
  • 0x62: конь 1, x+7, y+2
  • 0x63: конь 1, x+6, y+1
  • 0x64: конь 1, x+6, y+7
  • 0x65: конь 1, x+7, y+6
  • 0x66: конь 1, x+1, y+6
  • 0x67: конь 1, x+2, y+7
  • 0x68: конь 2, x+2, y+1
  • 0x69: конь 2, x+1, y+2
  • 0x6A: конь 2, x+7, y+2
  • 0x6B: конь 2, x+6, y+1
  • 0x6C: конь 2, x+6, y+7
  • 0x6D: конь 2, x+7, y+6
  • 0x6E: конь 2, x+1, y+6
  • 0x6F: конь 2, x+2, y+7
  • 0x70: пешка 1, одна клетка вперёд
  • 0x71: пешка 1, две клетки вперёд
  • 0x72: пешка 1, взятие фигуры справа (относительно ходящего игрока)
  • 0x73: пешка 1, взятие фигуры слева
  • 0x74: пешка 2, одна клетка вперёд
  • 0x75: пешка 2, две клетки вперёд
  • 0x76: пешка 2, взятие фигуры справа (относительно ходящего игрока)
  • 0x77: пешка 2, взятие фигуры слева
  • 0x78: пешка 3, одна клетка вперёд
  • 0x79: пешка 3, две клетки вперёд
  • 0x7A: пешка 3, взятие фигуры справа (относительно ходящего игрока)
  • 0x7B: пешка 3, взятие фигуры слева
  • 0x7C: пешка 4, одна клетка вперёд
  • 0x7D: пешка 4, две клетки вперёд
  • 0x7E: пешка 4, взятие фигуры справа (относительно ходящего игрока)
  • 0x7F: пешка 4, взятие фигуры слева
  • 0x80: пешка 5, одна клетка вперёд
  • 0x81: пешка 5, две клетки вперёд
  • 0x82: пешка 5, взятие фигуры справа (относительно ходящего игрока)
  • 0x83: пешка 5, взятие фигуры слева
  • 0x84: пешка 6, одна клетка вперёд
  • 0x85: пешка 6, две клетки вперёд
  • 0x86: пешка 6, взятие фигуры справа (относительно ходящего игрока)
  • 0x87: пешка 6, взятие фигуры слева
  • 0x88: пешка 7, одна клетка вперёд
  • 0x89: пешка 7, две клетки вперёд
  • 0x8A: пешка 7, взятие фигуры справа (относительно ходящего игрока)
  • 0x8B: пешка 7, взятие фигуры слева
  • 0x8C: пешка 8, одна клетка вперёд
  • 0x8D: пешка 8, две клетки вперёд
  • 0x8E: пешка 8, взятие фигуры справа (относительно ходящего игрока)
  • 0x8F: пешка 8, взятие фигуры слева
  • 0x90: ферзь 2, y+1
  • 0x91: ферзь 2, y+2
  • 0x92: ферзь 2, y+3
  • 0x93: ферзь 2, y+4
  • 0x94: ферзь 2, y+5
  • 0x95: ферзь 2, y+6
  • 0x96: ферзь 2, y+7
  • 0x97: ферзь 2, x+1
  • 0x98: ферзь 2, x+2
  • 0x99: ферзь 2, x+3
  • 0x9A: ферзь 2, x+4
  • 0x9B: ферзь 2, x+5
  • 0x9C: ферзь 2, x+6
  • 0x9D: ферзь 2, x+7
  • 0x9E: ферзь 2, x+1, y+1
  • 0x9F: ферзь 2, x+2, y+2
  • 0xA0: ферзь 2, x+3, y+3
  • 0xA1: ферзь 2, x+4, y+4
  • 0xA2: ферзь 2, x+5, y+5
  • 0xA3: ферзь 2, x+6, y+6
  • 0xA4: ферзь 2, x+7, y+7
  • 0xA5: ферзь 2, x+1, y+7
  • 0xA6: ферзь 2, x+2, y+6
  • 0xA7: ферзь 2, x+3, y+5
  • 0xA8: ферзь 2, x+4, y+4 (обычно не используется)
  • 0xA9: ферзь 2, x+5, y+3
  • 0xAA: ферзь 2, x+6, y+2
  • 0xAB: ферзь 2, x+7, y+1
  • 0xAC: ферзь 3, y+1
  • 0xAD: ферзь 3, y+2
  • 0xAE: ферзь 3, y+3
  • 0xAF: ферзь 3, y+4
  • 0xB0: ферзь 3, y+5
  • 0xB1: ферзь 3, y+6
  • 0xB2: ферзь 3, y+7
  • 0xB3: ферзь 3, x+1
  • 0xB4: ферзь 3, x+2
  • 0xB5: ферзь 3, x+3
  • 0xB6: ферзь 3, x+4
  • 0xB7: ферзь 3, x+5
  • 0xB8: ферзь 3, x+6
  • 0xB9: ферзь 3, x+7
  • 0xBA: ферзь 3, x+1, y+1
  • 0xBB: ферзь 3, x+2, y+2
  • 0xBC: ферзь 3, x+3, y+3
  • 0xBD: ферзь 3, x+4, y+4
  • 0xBE: ферзь 3, x+5, y+5
  • 0xBF: ферзь 3, x+6, y+6
  • 0xC0: ферзь 3, x+7, y+7
  • 0xC1: ферзь 3, x+1, y+7
  • 0xC2: ферзь 3, x+2, y+6
  • 0xC3: ферзь 3, x+3, y+5
  • 0xC4: ферзь 3, x+4, y+4 (обычно не используется)
  • 0xC5: ферзь 3, x+5, y+3
  • 0xC6: ферзь 3, x+6, y+2
  • 0xC7: ферзь 3, x+7, y+1
  • 0xC8: ладья 3, y+1
  • 0xC9: ладья 3, y+2
  • 0xCA: ладья 3, y+3
  • 0xCB: ладья 3, y+4
  • 0xCC: ладья 3, y+5
  • 0xCD: ладья 3, y+6
  • 0xCE: ладья 3, y+7
  • 0xCF: ладья 3, x+1
  • 0xD0: ладья 3, x+2
  • 0xD1: ладья 3, x+3
  • 0xD2: ладья 3, x+4
  • 0xD3: ладья 3, x+5
  • 0xD4: ладья 3, x+6
  • 0xD5: ладья 3, x+7
  • 0xD6: слон 3, x+1, y+1
  • 0xD7: слон 3, x+2, y+2
  • 0xD8: слон 3, x+3, y+3
  • 0xD9: слон 3, x+4, y+4
  • 0xDA: слон 3, x+5, y+5
  • 0xDB: слон 3, x+6, y+6
  • 0xDC: слон 3, x+7, y+7
  • 0xDD: слон 3, x+1, y+7
  • 0xDE: слон 3, x+2, y+6
  • 0xDF: слон 3, x+3, y+5
  • 0xE0: слон 3, x+4, y+4 (обычно не используется)
  • 0xE1: слон 3, x+5, y+3
  • 0xE2: слон 3, x+6, y+2
  • 0xE3: слон 3, x+7, y+1
  • 0xE4: конь 3, x+2, y+1
  • 0xE5: конь 3, x+1, y+2
  • 0xE6: конь 3, x+7, y+2
  • 0xE7: конь 3, x+6, y+1
  • 0xE8: конь 3, x+6, y+7
  • 0xE9: конь 3, x+7, y+6
  • 0xEA: конь 3, x+1, y+6
  • 0xEB: конь 3, x+2, y+7
  • 0xEC: указывает, что следующие два байта будут кодировать ход (формат).
  • 0xED: игнорировать этот байт и не менять move_num
  • 0xFE: начало ответвления
  • 0xFF: конец ответвления
Остальные значения байт не используются.

Формат хода из нескольких байт

Код 0xEC в декодированном потоке байт указывает на то, что в двух последующих байтах будет закодирован ход. Приведём алгоритм его распознавания.

Первым делом по аналогии с другими байтами потока два байта необходимо декодировать. То есть, сначала из каждого из них следует вычесть величину move_num, а затем произвести преобразование с помощью массива Cbh_Decode.

Рассмотрим двухбайтовое целое, составленное из полученных байт. Оно представляет из себя битовое поле.

  • Биты 0 -- 2 указывают на номер строки начальной клетки хода.
  • Биты 3 -- 5 указывают на номер столбца начальной клетки хода.
  • Биты 6 -- 8 указывают на номер строки конечной клетки хода.
  • Биты 9 -- 11 указывают на номер строки конечной клетки хода.
  • Биты 12 -- 13 указывают на появившуюся фигуру при продвижении пешки:
    • 0 -- ферзь;
    • 1 -- ладья;
    • 2 -- слон;
    • 3 -- конь.
    Если продвижения не было, эти биты игнорируются.

Алгоритм получения хода из нескольких байт

Определения move_num и Cbh_Decode, используемые в алгоритме, приведены здесь.

var i1, i2 : byte;
    w : word;
    nx, ny, kx, ky : byte; //Координаты начальной и конечной клетки хода
    Promotion_Figure : TFigure; //Фигура, появившаяся при продвижении пешки
begin
 i1 := ReadNextByte();//Читаем следующие два байта из потока и декодируем их
 i1 := Cbh_Decode[ i1 - move_num ];
 i2 := ReadNextByte();
 i2 := Cbh_Decode[ i2 - move_num ];
 w := (i1 shl 8) + i2; //В w получено число, составленное из двух раскодированных байт

 ny := (w and 7) + 1; //получаем координаты хода
 nx := ((w shr 3) and 7) + 1;
 ky := ((w shr 6) and 7) + 1;
 kx := ((w shr 9) and 7) + 1;

 case (w shr 12) and 3 of
  0 : Promotion_Figure := Queen;
  1 : Promotion_Figure := Rook;
  2 : Promotion_Figure := Bishop;
  3 : Promotion_Figure := Knight;
 end;
end;

CBA файл

Хранит информацию о комментариях к партии. Состоит из:
  • заголовка (10 б);
  • последовательности блоков.

В оригинальном тексте написано, что размер заголовка 26 б, так что, возможно, для различных версий формата его размер различается.

Каждый блок хранит комментарии к одной партии. Длина блоков не фиксирована, между двумя соседними блоками могут следовать мусорные байты. Информация о расположении блока для заданной партии или текста хранится в CBH файле.

Формат заголовка

  • Смещение 0, длина 2 б --- позиция первой записанной партии (?).
  • Смещение 2, длина 4 б --- указывает на конец CBA файла (совпадает с его длиной).
  • Смещение 6, длина 4 б --- суммарное значение изменённых байтов по всем партиям (?)

Формат блока данных о комментариях

Смещение здесь будет вычисляться относительно позиции начала данных о комментариях, указанной в CBH файле.
  • Смещение 0, длина 3 б --- идентификатор партии, для которой предназначены комментарии. Совпадает с порядковым номером блока CBH файла, описывающей партию (нумерация идёт с единицы).
  • Смещение 3, длина 7 б --- ?
  • Смещение 10, длина 4 б --- размер текущего блока, начиная со смещения 0.
  • Смещение 14 длина 3 б --- номер хода, для которого предназначен комментарий. Вычисляется так:
    • -1: комментарий касается партии в целом;
    • 0: к первому ходу партии.
    В общем случае он равен значению move_num. Комментарий предназначен тому ходу, перед декодированием которого move_num установится в заданное значение.
    Допускается несколько комментариев к одному и тому же ходу.
  • Смещение 17 длина 1 б --- тип комментария. Возможные типы:
    • 0x02 --- текст после хода;
    • 0x03 --- символ;
    • 0x05 --- стрелки на доске;
    • 0x09 --- упражнение (training annotation);
    • 0x10 --- звук;
    • 0x11 --- изображение;
    • 0x13 --- ссылка на другую партию;
    • 0x14 --- пешечная структура;
    • 0x15 --- пешечный путь;
    • 0x18 --- критическая позиция;
    • 0x19 --- correspondence move (не понял, что такое. Как-то связано с correspondence header);
    • 0x20 --- видео;
    • 0x22 --- медаль;
    • 0x23 --- цвет текста ответвления;
    • 0x61 --- correspondence header (не понял, что такое. Как-то связано с correspondence move);
    • 0x82 --- текст перед ходом.
    Возможны и другие типы, однако их значение неясно.
  • Смещение 18, длина 2 б --- число байт, занимаемых комментарием (начиная со смещения 14).
Дальнейший формат комментария зависит от его типа.

Для символов (код 0x03):

  • Смещение 20, длина 1 б --- метка, описывающая ход. Возможные значения:
    • 0: метка отсутствует;
    • 1: сильный ход ("!");
    • 2: слабый ход ("?");
    • 3: отличный ход ("!!");
    • 4: грубая ошибка ("??");
    • 5: интересный ход ("!?");
    • 6: сомнительный ход ("?!");
    • 8: единственный ход (нет разумных альтернатив);
    • 22: цугцванг.
  • Смещение 21, длина 1 б --- оценка позиции. Возможные значения такие же, как и в оценке линии в CBH файле (смещение 28 внутри блока).
  • Смещение 22, длина 1 б --- префикс. Возможные значения:
    • 0x00: префикс отсутствует;
    • 0x8C: с идеей;
    • 0x8D: направлено против;
    • 0x8E: лучше;
    • 0x8F: хуже;
    • 0x90: эквивалентно;
    • 0x91: комментарий редактора.
    Возможно, есть и другие значения.

Для текста (коды 0x02, 0x82):

  • Смещение 20, длина 1 б --- 0?
  • Смещение 21, длина 1 б --- язык. Возможные значения:
    • 0x00: все языки (конкретный язык не указан?);
    • 0x2A: английский;
    • 0x2B: испанский;
    • 0x31: французский;
    • 0x35: немецкий;
    • 0x46: итальянский;
    • 0x67: голландский;
    • 0x75: португальский;
    • в оригинальном тексте ещё есть 0x00: польский. Глюк?
  • Смещение 22 --- сам текст. Он занимает всю оставшуюся часть комментария. Его длину можно вычислить из числа байт, отведённых на комментарий, хранящихся по смещению 18.
    В тексте может присутствовать служебный байт 0x9E. Вместо него в комментарий будет вставляться диаграмма (отображается как "{#}").

Для критической позиции (код 0x18):

  • Смещение 20, длина 1 б --- возможные значения:
    • 1: критическая позиция в дебюте;
    • 2: критическая позиция в миттельшпиле;
    • 3: критическая позиция в эндшпиле.

Для медали (код 0x22):

  • Смещение 20, длина 4 б --- битовая карта. Значения битов 0 -- 15 совпадают с флагами медалей, описанными в CBH файле.

Для цвета текста ответвления (код 0x23):

  • Смещение 20, длина 1 б --- 0?
  • Смещение 21, длина 1 б --- голубая составляющая.
  • Смещение 22, длина 1 б --- зелёная составляющая.
  • Смещение 23, длина 1 б --- красная составляющая.

Для остальных типов комментариев формат неизвестен.

CBP файл

Хранит информацию об игроках. Состоит из:
  • заголовка (head_size байт. Обычно 28 б);
  • последовательности блоков (по 67 байт каждая).

Каждый блок содержит информацию об одном игроке.

Блоки структурированы в виде АВЛ-дерева, чтобы обеспечить быструю сортировку игроков по алфавиту. Другими словами, каждый блок представляется в виде вершины дерева и имеет ссылки на два поддерева: левое и правое. Все имена игроков из блоков левого поддерева в алфавитном порядке идут перед именем игрока из рассматриваемого блока. А все имена игроков из блоков правого поддерева следуют после имени игрока из рассматриваемого блока. Поддеревья могут быть пустыми, то есть не содержать ни одного блока.

Каждый блок определяется по его порядковому номеру. Нумерация начинается с нуля. Другими словами, блок №n расположен по смещению 67 * n + head_size.

Формат заголовка:

  • Смещение 0, длина 4 б (little-endian) --- число блоков в файле.
  • Смещение 4, длина 4 б (little-endian) --- номер блока, являющегося корнем АВЛ-дерева.
  • Смещение 8, длина 4 б (little-endian) --- число 1234567890 (зарезервировано для будущего использования?).
  • Смещение 12, длина 4 б (little-endian) --- размер блока (за вычетом 9 байт, задающих структуру дерева. Равно 58).
  • Смещение 16, длина 4 б (little-endian, знаковое) --- номер первого удалённого блока (равен -1, если ничего не удалялось).
  • Смещение 20, длина 4 б (little-endian) --- число существующих блоков (не удалённых).
  • Смещение 24, длина 4 б (little-endian) --- extra_space, количество дополнительных байт в заголовке. Таким образом размер заголовка вычисляется head_size = 28 + extra_space

Формат блока:

Смещение вычисляется относительно начала блока.
  • Смещение 0, длина 4 б (little-endian, знаковое) --- номер блока, являющегося корнем левого поддерева. Если оно пусто, то равен -1. Если блок удалён, то равен -999.
  • Смещение 4, длина 4 б (little-endian, знаковое) --- номер блока, являющегося корнем правого поддерева. Если оно пусто, то равен -1. Если блок удалён, то равен номеру следующего удалённого блока. Если же этот блок последний из удалённых, то равен -1.
  • Смещение 8, длина 1 б (знаковое) --- высота правого поддерева минус высота левого поддерева. Используется для балансировки АВЛ-дерева. Обычно она равна -1, 0 или 1. Однако временами может становиться равной -2 и 2. Если блок удалён, то байт равен нулю.
  • Смещение 9, длина 30 б (C-строка) --- фамилия игрока.
  • Смещение 39, длина 20 б (C-строка) --- имя игрока.
  • Смещение 59, длина 4 б (little-endian) --- число игр, сыгранных данным игроком (?).
  • Смещение 63, длина 4 б (little-endian) --- номер блока в CBH файле с первой партией, сыгранной данным игроком (?).
Вся другая информация об игроке извлекается из Энциклопедии Игроков (я так понимаю, из интернета).

CBT файл

Хранит информацию о турнирах. Состоит из:
  • заголовка (head_size байт. Обычно 28 б);
  • последовательности блоков (по 99 байт каждый).

Блоки структурированы в виде АВЛ-дерева, чтобы обеспечить их быструю сортировку по алфавиту.

Каждый блок определяется по его порядковому номеру. Нумерация начинается с нуля. Другими словами, блок №n расположен по смещению 99 * n + head_size. Формат заголовка полностью совпадает с форматом заголовка CBP файла.

Формат блока:

Первые 9 байт блока имеют то же значение, что и первые 9 байт блока CBP файла.
  • Смещение 9, длина 40 б (C-строка) --- название турнира.
  • Смещение 49, длина 30 б (C-строка) --- место проведения.
  • Смещение 79, длина 4 б (little-endian) --- дата проведения. Её формат:
    • биты 0 -- 4: день (0 --- день не задан);
    • биты 5 -- 8: месяц (0 --- не задан);
    • биты 9 -- 20: год (0 --- не задан).
  • Смещение 83, длина 1 б --- флаги:
    • биты 0 -- 4: тип игр турнира. Возможные значения:
      • 0: не задан;
      • 1: просто партия;
      • 2: матч;
      • 3: круговая система;
      • 4: швейцарская система;
      • 5: командный турнир (?, team);
      • 6: нокаут-система;
      • 7: сеанс одновременной игры;
      • 8: схевенингенская система.
    • бит 5: блиц;
    • бит 6: рапид;
    • бит 7: игра по переписке.
  • Смещение 85, длина 1 б --- страна проведения. Если страна не задана, то равен 0. В остальных случаях её инициалы берутся из следующего массива:
    
     const Nation_Abbrev : array [1..247] of string[3] = (
    	 'AFG', 'ALB', 'ALG', 'AND', 'ANG', 'ANT', 'ARG', 'ARM', 
    	 'AUS', 'AZE', 'BAH', 'BHN', 'BAN', 'BAR', 'BLR', 'BEL', 
    	 'BLZ', 'BER', 'BOL', 'BIH', 'BOT', 'BRA', 'IVB', 'BRU', 
    	 'BUL', 'BUR', 'CAN', 'CHI', 'CHN', 'COL', 'CRI', 'CRO', 
    	 'CUB', 'CYP', 'CZE', 'DEN', 'DJI', 'DOM', 'ECU', 'EGY', 
    	 'ESP', 'EST', 'ETH', 'FAI', 'FIJ', 'FIN', 'FRM', 'GAM', 
    	 'GEO', 'GHA', 'GRE', 'GUA', 'GCI', 'GUY', 'HAI', 'HON', 
    	 'HKG', 'HUN', 'ISL', 'IND', 'INA', 'IRI', 'IRQ', 'IRL', 
    	 'ITA', 'IVO', 'JAM', 'JPN', 'JCI', 'JOR', 'KAZ', 'KEN', 
    	 'KOR', 'KGZ', 'KUW', 'LAT', 'LBN', 'LBY', 'LIE', 'LTU', 
    	 'LUX', 'MAC', 'MAD', 'MAS', 'MLI', 'MLT', 'MAU', 'MRI', 
    	 'MEX', 'MDA', 'MNC', 'MGL', 'MAR', 'MOZ', 'MYA', 'NAM', 
    	 'NEP', 'AHO', 'NZL', 'NCA', 'NGR', 'NOR', 'PAK', 'PLE', 
    	 'PAN', 'PNG', 'PAR', 'PER', 'PHI', 'POL', 'POR', 'PUR', 
    	 'QAT', 'ROM', 'RUS', 'ESA', 'SMR', 'SCO', 'SEY', 'SIN', 
    	 'SVK', 'SLO', 'RSA', 'SRI', 'SUD', 'SUR', 'SWE', 'SUI', 
    	 'SYR', 'TJK', 'TAN', 'THA', 'TRI', 'TUN', 'TUR', 'TKM', 
    	 'UGA', 'UKR', 'UAE', 'URU', 'URS', 'UZB', 'VEN', 'VIE', 
    	 'ISV', 'WLS', 'YEM', 'YUG', 'ZAM', 'ZIM', 'ZRE', 'DDR', 
    	 'CSR', 'CHD', 'CAM', 'KAP', 'KBA', 'COM', 'CON', 'NKO', 
    	 'LAO', 'LES', 'MWI', 'MDV', 'MSH', 'OMN', 'NAU', 'MIC', 
    	 'NIG', 'SAU', 'TOG', 'TON', 'VAN', 'VAT', 'TUV', 'SWA', 
    	 'SIE', 'SLU', 'PAP', 'SVI', 'SKI', 'SAL', 'GE2', 'ZAR', 
    	 'RWA', 'LBR', 'NET', 'TWN', 'ASU', 'AGG', 'ARN', 'BNN', 
    	 'BTN', 'BRI', 'CMB', 'CAY', 'CAR', 'CIA', 'COA', 'CIN', 
    	 'ELG', 'ERI', 'FGB', 'FRG', 'FRP', 'GAB', 'GGB', 'GRA', 
    	 'GRL', 'FGA', 'GMA', 'GUI', 'GUB', 'IOM', 'JMY', 'MFR', 
    	 'MYF', 'MSG', 'NCF', 'NNN', 'NNA', 'NMI', 'OTM', 'PAL', 
    	 'PIG', 'RUF', 'SAO', 'SOM', 'SVN', 'HGB', 'PGB', 'TKI', 
    	 'TCI', 'WFR', 'NIR', 'ISS', 'GBR', 'SAA', 'MNT', 'SER', 
    	 'CAT', 'BAS', 'KOS', 'CRC', 'LBA', 'LEB', 'LIB' );
    
  • Смещение 86, длина 1 б --- ?
  • Смещение 87, длина 1 б --- категория. Изменяется от 0 до 99. Значение 0 означает, что категория не задана.
  • Смещение 88, длина 1 б --- флаги:
    • бит 0: ?? Почти всегда совпадает с битом 1.
    • бит 1: полный турнир (complete).
    • бит 2: очки за доску (board points).
  • Смещение 89, длина 1 б --- число раундов. Значение 0 означает, что число не задано.
  • Смещение 90, длина 1 б --- ?
  • Смещение 91, длина 4 б (little-endian) --- число партий в турнире (?).
  • Смещение 95, длина 4 б (little-endian) --- номер блока в CBH файле с первой партией из данного турнира (?).

CBC файл

Хранит информацию о комментаторе. Состоит из:
  • заголовка (head_size байт. Обычно 28 б);
  • последовательности блоков (по 62 байт каждый).

Блоки структурированы в виде АВЛ-дерева, чтобы обеспечить быструю сортировку комментаторов по алфавиту.

Каждый блок определяется по его порядковому номеру. Нумерация начинается с нуля. Другими словами, блок №n расположен по смещению 62 * n + head_size. Формат заголовка полностью совпадает с форматом заголовка CBP файла.

Формат блока:

Первые 9 байт блока имеют то же значение, что и первые 9 байт блока CBP файла.
  • Смещение 9, длина 45 б (C-строка) --- имя комментатора.
  • Смещение 54, длина 4 б (little-endian) --- число партий, прокомментированных этим комментатором (?).
  • Смещение 58, длина 4 б (little-endian) --- номер блока в CBH файле с первой партией, прокомментированной этим комментатором (?).

CBS файл

Хранит информацию об источниках партий. Состоит из:
  • заголовка (head_size байт. Обычно 28 б);
  • последовательности блоков (по 68 байт каждый).

Блоки структурированы в виде АВЛ-дерева, чтобы обеспечить быструю сортировку источников по алфавиту.

Каждый блок определяется по его порядковому номеру. Нумерация начинается с нуля. Другими словами, блок №n расположен по смещению 68 * n + head_size. Формат заголовка полностью совпадает с форматом заголовка CBP файла.

Формат блока:

Первые 9 байт блока имеют то же значение, что и первые 9 байт блока CBP файла.
  • Смещение 9, длина 25 б (C-строка) --- название источника.
  • Смещение 34, длина 16 б (C-строка) --- автор публикации.
  • Смещение 50, длина 4 б (little-endian) --- публикация (не знаю, что это?)
  • Смещение 54, длина 4 б (little-endian) --- дата публикации. Формат см в описании даты CBT файла.
  • Смещение 58, длина 1 б --- номер версии.
  • Смещение 59, длина 1 б --- качество. Возможные значения:
    • 0: качество не задано. Chessbase в этом случае предполагает, что качество низкое.
    • 1: высокое качество;
    • 2: среднее качество;
    • 3: низкое качество.
  • Смещение 60, длина 4 б (little-endian) --- число партий из этого источника (?).
  • Смещение 64, длина 4 б (little-endian) --- номер блока в CBH файле с первой партией из этого источника (?).

CBE файл

Хранит информацию о командах. Впервые появился в Chessbase 9. Состоит из:
  • заголовка (head_size байт. Обычно 28 б);
  • последовательности блоков (по 72 байт каждый).

Блоки структурированы в виде АВЛ-дерева, чтобы обеспечить быструю сортировку команд по алфавиту.

Каждый блок определяется по его порядковому номеру. Нумерация начинается с нуля. Другими словами, блок №n расположен по смещению 72 * n + head_size. Формат заголовка полностью совпадает с форматом заголовка CBP файла.

Формат блока:

Первые 9 байт блока имеют то же значение, что и первые 9 байт блока CBP файла.
  • Смещение 9, длина 45 б (C-строка) --- название команды.
  • Смещение 54, длина 2 б (little-endian) --- номер команды. Если он слишком большой, то Chessbase вылетает с ошибкой. Значение 5000 ещё работает, а 9999 уже нет.
  • Смещение 56, длина 2 б --- ?
  • Смещение 58, длина 1 б, бит 0 --- если установлен в 1, то команда играла в сезоне < год > / < год > + 1. В противном случае устанавливается только год, когда существовала команда.
  • Смещение 59, длина 4 б (little-endian) --- год, когда играла команда. См. также предыдущую запись.
  • Смещение 63, длина 1 б --- национальность команды. Возможные значения см. здесь.
  • Смещение 64, длина 4 б (little-endian) --- число партий, сыгранных командой (?).
  • Смещение 68, длина 4 б (little-endian) --- номер блока в CBH файле с первой партией, сыгранной командой (?).

Текст написан на основе описания формата CBH.
Автор перевода --- Бодягин Дмитрий