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

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

Описание формата баз партий от Chess Assistant

Этот текст описывает формат баз партий от Chess Assistant. База состоит из нескольких файлов, у каждого из них своё предназначение. Все вместе они содержат как сами партии, так и сопутствующую информацию (имена игроков, названия турниров, результат и т.п.). Поскольку сам формат закрыт, назначение некоторых полей остаётся неясным. Однако данное описание позволит прочитать все партии вместе с большей частью данных о них. В будущих версиях Chess Assistant формат может измениться.

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

База партий от Chess Assistant состоит из файлов со следующими расширениями:

  • CDP --- общая информация для всей базы
  • EMB --- информация об игроках, названиях турниров и т.п.
  • D00 --- заголовки партий
  • A02 --- указатели на адреса партий в файле D02
  • D02 --- непосредственно сами партии (последовательность ходов, комментарии и т.п.)
  • A01 --- указатели на пользовательские папки в файле D01(?);
  • D01 --- пользовательские папки (?)
  • AXX --- ?
  • DXX --- ?
  • BO0 --- ?
  • ST0 --- ?

CDP файл

Это основной файл базы. Он содержит общую информацию о ней. Формат большей части файла неясен, однако можно выделить следующие поля:
  • Смещение 0, длина 50 б --- сигнатура. В частности, показывает, какой программой создавалась база данных. Например, может содержать строку: "Chess Assistant 3.0 database." Лишние символы заполняются нулями.
  • Смещение 50, длина 50 б --- Строка, описывающая версию формата базы данных. В изученных базах она была такой: "\nChess Data Pro format. Version 1.3". Лишние символы заполняются нулями.
  • Смещение 104, длина 4 б --- число партий в базе данных
  • Смещение 108, длина 4 б --- length, длина строки с комментарием ко всей базе партий
  • Смещение 112, длина length б --- строка, содержащая комментарий к базе партий.

EMB файл

В этом файле содержатся списки всех игроков, чьи партии хранятся в базе, а также названия турниров, мест их проведения и источников. В целом, EMB файл представляет собой минифайловую систему, внутри которой хранятся другие файлы, а именно:
  • Players.cdp,   Players.iii,   Players.axx,   Players.dxx,   Players.d00,   Players.a01,   Players.d01
  • Events.cdp,   Events.iii,   Events.axx,   Events.dxx,   Events.d00,   Events.a01,   Events.d01
  • Places.cdp,   Places.iii,   Places.axx,   Places.dxx,   Places.d00,   Places.a01,   Places.d01
  • Sources.cdp,   Sources.iii,   Sources.axx,   Sources.dxx,   Sources.d00,   Sources.a01,   Sources.d01
Всего должно быть 28 файлов.

Файлы <name>.cdp дают общее описание всех остальных файлов <name>. Точнее ничего про них сказать не могу.

Файлы <name>.axx и <name>.dxx содержат некие битовые маски: по одному биту на элемент файла <name>.d01. Их назначение не ясно.

Файл <name>.iii содержит индексы для отсортированного списка элементов из <name>.d01.

Файл <name>.a01 содержит адреса для каждого элемента из <name>.d01.

Файл <name>.d01 содержит непосредственно записи из списка для <name>. А именно, Players.d01 содержит список игроков из базы, Events.d01 - названия турниров, Places.d01 - места проведения и Sources.d01 - источники.

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

Общий формат EMB файла

Начинается EMB файл следующими данными:
  • Сигнатура (64 б) - Такая же, как и в CDP файле. В изученных автором партиях содержала строку: "Chess Assistant 3.0 database." Лишние символы заполняются нулями.
  • Строка с версией формата, в котором записан файл (64 б). В изученных базах она была такой: "\nData Pro Volume format. Version 1.1". Лишние символы заполняются нулями.
  • Нули (8 б).
  • folder_length (4 б) - размер корневого каталога в байтах.
  • folder_offset (4 б) - с какого места внутри файла начинается описание корневого каталога.
Величины folder_length и folder_offset нужны, чтобы прочитать содержимое корневого каталога.

Как собрать файл из минифайловой системы EMB

Чтобы получить содержимое файла из минифайловой системы EMB, необходимо знать два параметра: размер файла length и адрес начала файла внутри файла EMB offset.

Каждый файл разбит на фрагменты не очень большого размера (как правило, меньше одного килобайта). Чтобы получить весь файл, их надо склеить все вместе, один за другим.

Начиная с адреса offset в EMB файле записаны несколько блоков следующего содержания:

  • length_i (4 б) - размер очередного фрагмента файла в байтах
  • offset_i (4 б) - адрес очередного фрагмента внутри файла CDP.
Эти блоки следует читать до тех пор, пока length_1 + length_2 + ... + length_n не станет равной length.

Теперь, чтобы получить содержимое файла целиком, надо сначала прочитать фрагмент из length_1 байт, начиная с адреса offset_1. Затем добавить к нему фрагмент из length_2 байт, начиная с адреса offset_2 и т.д. Процедура повторяется до тех пор, пока длина склеенных фрагментов не достигнет общей длины файла length.

Схематически алгоритм получения содержимого всего файла можно записать так:

function GetFile (EMBfile, length, offset): string;
 var sum_len, tek_pos, length_i, offset_i: integer;
 begin
  result := '';
  sum_len := 0;
  EMBfile.Seek (offset);
  while sum_len<length do
  begin
   length_i := EMBfile.ReadInteger;
   sum_len := sum_len + length_i;
   offset_i := EMBfile.ReadInteger;
   tek_pos := EMBfile.CurrentPosition;
   EMBfile.Seek(offset_i);
   result := result + EMBfile.ReadnBytes (length_i);
   EMBfile.Seek(tek_pos);
  end;
 end

Структура корневого каталога

Каталог состоит из следующих друг за другом блоков данных длиной 256 байт. Каждый блок описывает один из файлов внутри каталога и имеет следующую структуру:
  • Смещение 0, длина 4 б --- всегда ноль
  • Смещение 4, длина 4 б --- всегда два
  • Смещение 8, длина 4 б --- file_length, размер файла в байтах.
  • Смещение 12, длина 4 б --- file_offset, адрес начала файла внутри EMB файла. Этот параметр вместе с file_length нужен, чтобы получить все данные из файла. Как это делать, приведено здесь.
  • Смещение 28 --- C-строка с именем файла. Признаком её конца является символ 0. Учитывая, что размер блока равен 256, длина имени не может превышать 227 символов. В реальности же все файлы имеют гораздо более короткие имена. Их названия перечислены здесь.

В текущей версии формата в корневом каталоге всегда присутствует ровно 28 файлов и записаны они именно в том порядке, в котором приведены здесь. Однако сам формат допускает и другие файлы внутри каталога.

Структура файла Players.d01

Файл Players.d01 содержит набор блоков, каждый из которых описывает одного игрока. Блоки не обязаны следовать друг за другом, между ними могут присутствовать неиспользуемые фрагменты файла. Адреса начал всех блоков содержатся в файле Players.a01.

Каждый блок имеет следующую структуру:

  • name_length (1 б) - длина строки с именем игрока.
  • title_length (1 б) - длина строки с титулом игрока.
  • name (name_length б) - строка с именем игрока.
  • title (title_length б) - строка с титулом игрока.

Структура файлов Players.a01, Events.a01, Places.a01 и Sources.a01

Каждый файл с расширением a01 внутри EMB файла содержит массив a01 из знаковых 4-хбайтовых целых чисел, из которых можно узнать адрес начала записи в соответствующем d01 файле. Для примера рассмотрим файлы Players.a01 и Players.d01. В этом случае на вход мы получаем идентификатор игрока playersID. Сначала мы читаем элемент массива a01[playersID]. Если он положительный, то он и равен координате начала записи об игроке в файле Players.d01. В противном случае, необходимо произвести замену
playersID := -a01[playersID]
и повторить попытку. Повторять нужно до тех пор, пока значение из массива не станет положительным.

Для других файлов a01 процедура получения адреса совершенно аналогична. Схематически её можно описать так:

function GetD01Address (a01, ID): integer;
 begin
  while a01[ID] < 0 do
   ID := -a01[ID];
  result := a01[ID];
 end;

Структура файлов Players.iii, Events.iii, Places.iii и Sources.iii

Эти файлы хранят массив iii из целых чисел, по 4 байта на каждый элемент. Он используется для быстрой сортировки списка партий по соответствующему полю (имя игрока, название турнира и т.п.). То есть, элемент iii[n] содержит идентификатор игрока, турнира, места проведения или источника соответственно, который в отсортированном списке будет идти под номером n. Далее, по этому идентификатору можно получить значение самого поля (см. описание a01 файлов).

Структура файла Players.d00

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

Структура блока:

  • Rating (2 б) - ELO рейтинг игрока.
  • FIDEID(?) (4 б) - идентификатор FIDE для игрока
  • Birthday (дата) - дата рождения.
  • Gender (1 б) - Пол игрока. Возможные значения:
    • 0 - информация отсутствует
    • 1 - мужской
    • 2 - женский
Блок под номером n содержит дополнительную информацию для игрока с идентификатором n. С помощью файла a01 по идентификатору можно получить имя игрока.

Структура файлов Events.d01, Places.d01 и Sources.d01

Файлы с расширением d01 содержат набор блоков, каждый из которых описывает одно название (турнир для Events.d01, место проведения для Places.d01 и источник для Sources.d01). Их структура очень похожа на структуру файла Players.d01 за тем исключением, что каждый игрок описывается двумя строками, а остальные названия - одной. Блоки не обязаны следовать друг за другом, между ними могут присутствовать неиспользуемые фрагменты. Адреса начал всех блоков содержатся в одноимённом файле с расширением a01.

Каждый блок имеет следующую структуру:

  • name_length (1 б) - длина строки с названием.
  • name (name_length б) - непосредственно строка названием.

D00 файл

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

Структура блока:

  • White_PlayerId (3 б) - идентификатор игрока белыми фигурами. Его имя и другая дополнительная информация содержатся в файле EMB.
  • Black_PlayerId (3 б) - идентификатор игрока чёрными фигурами.
  • White_ELO (2 б) - Рейтинг игрока белыми фигурами.
  • Black_ELO (2 б) - Рейтинг игрока чёрными фигурами.
  • Outcome (1 б) - Результат партии. Может принимать следующие значения:
    • 1 - ничья
    • 2 - белые выиграли
    • 3 - чёрные выиграли
    • 4 - Результат неизвестен, либо партия ещё не завершена
    • 5 - +/-
    • 6 - -/+
    • 7 - +/=
    • 8 - =/+
    • 9 - +-
    • 10 - -+
    • 11 - =
    • 12 - Inf
    • 13 - =/Inf
    • 14 - ->
    • 15 - ^
    • 16 - ->/<-
  • Date (дата) - дата проведения партии
  • EventID (3 б) - идентификатор турнира. С его помощью можно получить название турнира из файла EMB.
  • SiteID (3 б) - идентификатор места проведения партии.
  • Game_Type (4 б) - тип партии. Возможные типы:
    • 1 - пользовательская партия (my own games)
    • 2 - историческая партия (historic games)
    • 3 - показательная партия (model games)
    • 4 - партия с комментариями из книги (annotated games from books)
    • 5 - компьютерная партия (computer games)
    • 6 - дебют (opening theory/plans)
    • 7 - миттельшпиль (middlegames)
    • 8 - эндшпиль (endgames)
    • 9 - стратегия (strategy)
    • 10 - тактика (tactics)
    • 11 - тест (tests)
    • 12 - глупая ошибка (blunders)
    • 13 - атака со стороны короля (kingside attack)
    • 14 - атака со стороны ферзя (queenside attack)
    • 15 - контратака (counter attack)
    • 16 - типичная пешечная структура (typical pawn structure)
    • 17 - игра фигур (piece play)
    • 18 - позиционная жертва (positional sacrifice)
    • 19 - материальное неравенство (material imbalance)
    • 20 - переход к эндшпилю (endgame transition)
    • 21 - разнопольные слоны (opposite coloured bishops)
    • 22 - пространство (space)
    • 23 - защита (defence)
    • 24 - профилактика (prophylaxis)
    • 25 - метод для получения ничьи (drawing methods)
    • 26 - пользовательский анализ (my analysis)
    • 27 - компьютерный анализ (computer analysis)
    • 28 - анализ с помощью шахматных баз (tablebase analysis)
    • 29 - психологический приём (psychology)
    • 30 - остальное (miscellaneous)
  • GameID (4 б) - идентификатор партии. По нему можно найти записи партии с помощью файла A02.
  • Неизвестный байт (1 б)
  • Round * 2 (1 б) - номер раунда в турнире, умноженный на 2.
  • ECO (2 б) - код дебюта в формате ECO. Формат его такой: ECO / 100 - буквенный код дебюта, а ECO mod 100 - его двузначный номер. Возможные буквенные коды:
    • 0 - A
    • 1 - B
    • 2 - C
    • 3 - D
    • 4 - E
  • AnnotatorID (3 б) - идентификатор комментатора. Сама информация о комментаторе хранится вместе с именами игроков. То есть его можно найти с помощью файла Players.a01 внутри файла EMB.
  • SourceID (3 б) - идентификатор источника. Его название можно найти в файле EMB.

A02 файл

В файле A02 содержится массив a02 из знаковых 4-хбайтовых целых чисел, из которых можно узнать адрес начала записи партии в d02 файле. На входе мы получаем идентификатор партии GameID, каждый идентификатор хранится в заголовках партий из файла D00. Чтобы получить адрес записи партии, сначала мы читаем элемент массива a02[GameID]. Если он положительный, то он и равен координате начала записи партии в файле D02. В противном случае, необходимо произвести замену
GameID := -a02[GameID]
и повторить попытку. Повторять нужно до тех пор, пока значение из массива не станет положительным.

D02 файл

Этот файл содержит непосредственно записи каждой из партий. Адрес каждой записи и её длина не фиксированы, между соседними записями теоретически могут находиться мусорные байты. Адреса начала каждой записи хранятся в файле A02. Запись партии связана с заголовком партии из файла D00 с помощью идентификатора GameID.

Для описания ходов все фигуры нумеруются (нумерация белых и чёрных идёт отдельно). Обычно каждый ход записывается в виде: "фигура номер n переместилась с одной позиции на другую". Фигуры нумеруются следующим образом:

  • 0 - 7: номера пешек. Пешка с номером 0 в начале партии стояла на вертикали a, с номером 1 - на вертикали b и т.д.
  • 8 - ферзевый конь
  • 9 - королевский конь
  • 10 - ферзевый слон
  • 11 - королевский слон
  • 12 - ферзевая ладья
  • 13 - королевская ладья
  • 14 - ферзь
  • 15 - король
  • 16 - дополнительная фигура, которая могла возникнуть в результате продвижения пешки
  • 17 - ещё одна дополнительная фигура.
Все номера, кроме 16 и 17, жёстко закреплены за определённым типом фигуры. Фигуры с номерами 16 и 17 могут быть любыми кроме пешки и короля.

Формат записи партии:

  • length (1 или 2 б) - длина записи в байтах. Если она меньше 128 байт, то поле length занимает 1 байт. В противном случае оно занимает 2 байта, и длина вычисляется по формуле:
    (byte1 and 127) + (byte2 * 128).
    Само поле length в длину записи не включается.
  • Следом идёт последовательность кодов, которые нужно читать до тех пор, пока размер прочитанных данных не превзойдёт length. После некоторых кодов следуют дополнительные данные.

    Возможные коды:

    • 236 - длинная строка-комментарий. Следом за кодом записывается сам комментарий. Его формат следующий:
      • comment_length (4 б) - длина комментария в байтах. Само поле comment_length в длину не включается.
      • comment (строка-комментарий, comment_length б) - непосредственно комментарий.
    • 235 - короткая строка-комментарий. Следом за кодом записывается сам комментарий в следующем формате:
      • comment_length (1 б) - длина последующего комментария. Само поле comment_length в длину не включается. То есть, максимальная длина комментария в этом случае (вместе со вспомогательной информацией) не превосходит 255.
      • comment (строка-комментарий, comment_length б) - непосредственно комментарий.
    • 234 - символ-комментарий. Чаще всего используется для добавления знаков "!", "?" и т.п. после хода. После кода идёт строка-комментарий, длина которой предполагается равной 2.
    • 231 - начало ответвления в партии.
      Ответвление записывается перед тем ходом, альтернатива которому в нём представлена.
    • 232 - окончание ответвления.
    • 233 - назначение не ясно. После этого поля следует пропустить один байт (значение которого также не ясно).
    • 230 - начинается описание начальной позиции. Этот код не может идти после того, как был сделан хотя бы один ход. После него сразу идёт описание позиции. Формат описания:
      • 36 байт - массив из 18 элементов, описывающих положение белых фигур с номерами от 0 до 17, по два байта на фигуру. Первый байт координата фигуры, а второй - её тип. Возможные типы:
        • 1 - пешка
        • 2 - конь
        • 3 - слон
        • 4 - ладья
        • 5 - ферзь
        • 6 - король
        Если фигура с данным номером отсутствует, то для неё записываются два байта: 8, 0.

        Примечание Типы фигур с номерами от 0 до 15 жёстко фиксированы (см. нумерацию фигур). Тип фигуры может варьироваться только для номеров 16 и 17.

      • 36 байт - массив из 18 элементов, описывающих положение чёрных фигур с номерами от 0 до 17, по два байта на фигуру. Формат элементов такой же, как и для белых фигур
      • 2 байта - число полуходов до позиции. Если равно 0, то это стартовая позиция, если 1 - то белые сделали один ход и т.п. Соответственно, если значение чётное, то следующий ход за белыми, в противном случае - за чёрными.
      • 1 байт - битовая маска, указывающая, какие из рокировок в партии потенциально возможны:
        • бит 8 - короткая рокировка белыми
        • бит 4 - длинная рокировка белыми
        • бит 2 - короткая рокировка чёрными
        • бит 1 - длинная рокировка чёрными
      • 1 байт - координата клетки, на которую может пойти пешка, осуществляющая взятие на проходе. Горизонталь 5 означает, что ходить будут белые, горизонталь 2 - ходить будут чёрные. Если взятие на проходе невозможно, то в этом поле записывается 0 (?).
      Примечание: в записи партии не обязательно присутствует описание начальной позиции. Если его нет, то предполагается, что партия начинается со стандартной стартовой позиции.

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

      фигура <n>, <y><x>
      Это будет означать, что фигура с номером n переместилась на x позиций влево и y позиций вверх. Координаты позиции при этом будут вычисляться по модулю 8 (остатки при делении на 8).
    • 0 - пешка 0, 10 для белой пешки или 70 для чёрной
    • 1 - пешка 0, 17 для белой пешки или 77 для чёрной
    • 2 - пешка 0, 11 для белой пешки или 71 для чёрной
    • 3 - пешка 0, 20 для белой пешки или 60 для чёрной
    • 4 - пешка 1, 10 для белой пешки или 70 для чёрной
    • 5 - пешка 1, 17 для белой пешки или 77 для чёрной
    • 6 - пешка 1, 11 для белой пешки или 71 для чёрной
    • 7 - пешка 1, 20 для белой пешки или 60 для чёрной
    • 8 - пешка 2, 10 для белой пешки или 70 для чёрной
    • 9 - пешка 2, 17 для белой пешки или 77 для чёрной
    • 10 - пешка 2, 11 для белой пешки или 71 для чёрной
    • 11 - пешка 2, 20 для белой пешки или 60 для чёрной
    • 12 - пешка 3, 10 для белой пешки или 70 для чёрной
    • 13 - пешка 3, 17 для белой пешки или 77 для чёрной
    • 14 - пешка 3, 11 для белой пешки или 71 для чёрной
    • 15 - пешка 3, 20 для белой пешки или 60 для чёрной
    • 16 - пешка 4, 10 для белой пешки или 70 для чёрной
    • 17 - пешка 4, 17 для белой пешки или 77 для чёрной
    • 18 - пешка 4, 11 для белой пешки или 71 для чёрной
    • 19 - пешка 4, 20 для белой пешки или 60 для чёрной
    • 20 - пешка 5, 10 для белой пешки или 70 для чёрной
    • 21 - пешка 5, 17 для белой пешки или 77 для чёрной
    • 22 - пешка 5, 11 для белой пешки или 71 для чёрной
    • 23 - пешка 5, 20 для белой пешки или 60 для чёрной
    • 24 - пешка 6, 10 для белой пешки или 70 для чёрной
    • 25 - пешка 6, 17 для белой пешки или 77 для чёрной
    • 26 - пешка 6, 11 для белой пешки или 71 для чёрной
    • 27 - пешка 6, 20 для белой пешки или 60 для чёрной
    • 28 - пешка 7, 10 для белой пешки или 70 для чёрной
    • 29 - пешка 7, 17 для белой пешки или 77 для чёрной
    • 30 - пешка 7, 11 для белой пешки или 71 для чёрной
    • 31 - пешка 7, 20 для белой пешки или 60 для чёрной
    • 32 - конь 8, 67
    • 33 - конь 8, 76
    • 34 - конь 8, 16
    • 35 - конь 8, 27
    • 36 - конь 8, 21
    • 37 - конь 8, 12
    • 38 - конь 8, 72
    • 39 - конь 8, 61
    • 40 - конь 9, 67
    • 41 - конь 9, 76
    • 42 - конь 9, 16
    • 43 - конь 9, 27
    • 44 - конь 9, 21
    • 45 - конь 9, 12
    • 46 - конь 9, 72
    • 47 - конь 9, 61
    • 48 - слон 10, 11
    • 49 - слон 10, 22
    • 50 - слон 10, 33
    • 51 - слон 10, 44
    • 52 - слон 10, 55
    • 53 - слон 10, 66
    • 54 - слон 10, 77
    • 55 - слон 10, 17
    • 56 - слон 10, 26
    • 57 - слон 10, 35
    • 58 - слон 10, 53
    • 59 - слон 10, 62
    • 60 - слон 10, 71
    • 61 - слон 11, 11
    • 62 - слон 11, 22
    • 63 - слон 11, 33
    • 64 - слон 11, 44
    • 65 - слон 11, 55
    • 66 - слон 11, 66
    • 67 - слон 11, 77
    • 68 - слон 11, 17
    • 69 - слон 11, 26
    • 70 - слон 11, 35
    • 71 - слон 11, 53
    • 72 - слон 11, 62
    • 73 - слон 11, 71
    • 74 - ладья 12, 07
    • 75 - ладья 12, 06
    • 76 - ладья 12, 05
    • 77 - ладья 12, 04
    • 78 - ладья 12, 03
    • 79 - ладья 12, 02
    • 80 - ладья 12, 01
    • 81 - ладья 12, 70
    • 82 - ладья 12, 60
    • 83 - ладья 12, 50
    • 84 - ладья 12, 40
    • 85 - ладья 12, 30
    • 86 - ладья 12, 20
    • 87 - ладья 12, 10
    • 88 - ладья 13, 07
    • 89 - ладья 13, 06
    • 90 - ладья 13, 05
    • 91 - ладья 13, 04
    • 92 - ладья 13, 03
    • 93 - ладья 13, 02
    • 94 - ладья 13, 01
    • 95 - ладья 13, 70
    • 96 - ладья 13, 60
    • 97 - ладья 13, 50
    • 98 - ладья 13, 40
    • 99 - ладья 13, 30
    • 100 - ладья 13, 20
    • 101 - ладья 13, 10
    • 102 - ферзь 14, 11
    • 103 - ферзь 14, 22
    • 104 - ферзь 14, 33
    • 105 - ферзь 14, 44
    • 106 - ферзь 14, 55
    • 107 - ферзь 14, 66
    • 108 - ферзь 14, 77
    • 109 - ферзь 14, 17
    • 110 - ферзь 14, 26
    • 111 - ферзь 14, 35
    • 112 - ферзь 14, 53
    • 113 - ферзь 14, 62
    • 114 - ферзь 14, 71
    • 115 - ферзь 14, 07
    • 116 - ферзь 14, 06
    • 117 - ферзь 14, 05
    • 118 - ферзь 14, 04
    • 119 - ферзь 14, 03
    • 120 - ферзь 14, 02
    • 121 - ферзь 14, 01
    • 122 - ферзь 14, 70
    • 123 - ферзь 14, 60
    • 124 - ферзь 14, 50
    • 125 - ферзь 14, 40
    • 126 - ферзь 14, 30
    • 127 - ферзь 14, 20
    • 128 - ферзь 14, 10
    • 129 - король 15, 11
    • 130 - король 15, 77
    • 131 - король 15, 17
    • 132 - король 15, 71
    • 133 - король 15, 07
    • 134 - король 15, 01
    • 135 - король 15, 70
    • 136 - король 15, 10
    • 137 - фигура 16, 11
    • 138 - фигура 16, 22
    • 139 - фигура 16, 33
    • 140 - фигура 16, 44
    • 141 - фигура 16, 55
    • 142 - фигура 16, 66
    • 143 - фигура 16, 77
    • 144 - фигура 16, 17
    • 145 - фигура 16, 26
    • 146 - фигура 16, 35
    • 147 - фигура 16, 53
    • 148 - фигура 16, 62
    • 149 - фигура 16, 71
    • 150 - фигура 16, 07
    • 151 - фигура 16, 06
    • 152 - фигура 16, 05
    • 153 - фигура 16, 04
    • 154 - фигура 16, 03
    • 155 - фигура 16, 02
    • 156 - фигура 16, 01
    • 157 - фигура 16, 70
    • 158 - фигура 16, 60
    • 159 - фигура 16, 50
    • 160 - фигура 16, 40
    • 161 - фигура 16, 30
    • 162 - фигура 16, 20
    • 163 - фигура 16, 10
    • 164 - фигура 16, 67
    • 165 - фигура 16, 76
    • 166 - фигура 16, 16
    • 167 - фигура 16, 27
    • 168 - фигура 16, 21
    • 169 - фигура 16, 12
    • 170 - фигура 16, 72
    • 171 - фигура 16, 61
    • 172 - 206 - ходы фигуры 17. Последовательность ходов такая же, как и для фигуры 16.
    • 207 - длинная рокировка
    • 208 - короткая рокировка
    • 209 - продвижение пешки. После кода обязательно следуют следующие поля:
      • 1 байт - в старших шести битах хранится номер продвинувшейся пешки. В младших двух битах хранится тип хода:
        • 0 - ход 10 для белой пешки или 70 для чёрной
        • 0 - ход 17 для белой пешки или 77 для чёрной
        • 0 - ход 11 для белой пешки или 71 для чёрной
        • 0 - ход 20 для белой пешки или 60 для чёрной (в принципе, в корректной партии его не должно быть)
      • 1 байт - в старших трёх битах хранится тип фигуры, на которую заменяется пешка. В младших пяти битах хранится номер фигуры, которая появится вместо пешки. Возможные типы фигур:
        • 2 - конь
        • 3 - слон
        • 4 - ладья
        • 5 - ферзь
        Внимание: тип фигур с номерами от 0 до 16 жёстко зафиксирован. Поэтому нельзя, например, ферзю выдать номер 9, так как тот зафиксирован за конём. В крайне редких случаях, когда номеров от 0 до 17 на фигуры не хватает, для записи ходов продвинувшейся фигуры придётся использовать расширенную запись хода.
    • 210 - индикатор того, что следующий ход будет взятием на проходе. После этого кода обязательно должен идти код, описывающий ход пешкой (?).
    • 211 - пустой ход (?)
    • 212 - 219 - запись хода в расширенном формате. Код 212 значит, что двигаться будет фигура, заменившая пешку с вертикали a; код 213 - с вертикали b и т.п.
      После этого кода следует один байт, задающий ход фигуры. Его старшие 4 бита указывают, на сколько клеток фигура сместится вверх, а младшие 4 бита - на сколько она сместится вправо. Новые координаты фигуры берутся по модулю 8 (то есть берутся остатки при делении на 8).

    Формат координат фигуры

    Координата фигуры на шахматной доске записывается одним байтом. Старшие 4 бита задают номер горизонтали, а младшие 4 бита - номер вертикали. В обоих случаях нумерация начинается с нуля. Нумерация идёт снизу вверх и слева направо.

    Формат строки-комментария

    Для чтения строки-комментария необходим параметр comment_length, равный длине записи с комментарием.

    Комментарий состоит из полей:

    • 1 байт - тип комментария. Возможные типы:
      • 2 - символьная оценка текущей позиции или хода в партии (полученной после прочтения последнего хода до этого комментария). Ставится после хода.
      • 3 - символьная оценка текущей позиции или хода в партии. Ставится перед ходом.
      • 4 - текстовый комментарий после хода
      • 5 - текстовый комментарий перед ходом
      • 6 - оценка текущей позиции. Дополнительно указывается, кто дал такую оценку.
      • 7 - пользовательские папки (?)
      • 8 - диаграмма после хода
      • 9 - диаграмма до хода
      • 21 - пользовательские папки (?)
      • 29 - компьютерная оценка позиции. Параметр comment_length в этом случае чаще всего равен 5, однако может быть равен 8. В этом случае следующие поля комментария будут такими:
        • 2 байта - знаковое целое, представляющее собой оценку позиции, измеренную в сотых долях пешки. То есть, значение 100 будет означать, что, по мнению компьютера, преимущество у белых в одну пешку. Отрицательное число означает, что преимущество у чёрных.
        • 2 байта - символы с кодами 255 и 0.
        • 3 байта - если длина комментария равна 8, то символы "CAP".
    • (comment_length - 1) байт - непосредственно строка с комментарием.

    Формат даты

    Информация о дате записывается трёхбайтовым целым числом DateID. День, месяц и год получаются по этому числу следующим образом:
    • Day := DateID mod 32; - для дня;
    • Month := (DateID/32) mod 13; - Для месяца;
    • Year := DateID/ (32 * 13); - Для года
    Если какое-то из значений Day, Month или Year равно нулю, это значит, что соответствующее значение не известно.

    Текст написан на основе данных, присланных Александром Никулиным.
    Автор текста --- Бодягин Дмитрий