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

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

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

Шахматные базы программы SCID могут содержать в себе множество шахматных партий, для каждой из которых, помимо непосредственно набора ходов, могут храниться ответвления, комментарии, метки, а также различная сопутствующая игнформация (имена игроков, название турнира, дата проведения и т.п.) Партии в этом формате занимают существенно меньше пространства на диске, чем в стаднартном формате PGN.

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

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

SCID - программа с открытым кодом. Поэтому все её исходные коды, включая и отвечающие за работу с базами партий, доступны. Их можно скачать вместе с самой программой по адресу scid.sourceforge.net/download.html.

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

  • sg4 - описания всех партий;
  • si4 - индексы всех партий (для связывания номера партии и её описания);
  • sn4 - хранит имена всех игроков, турниров, мест проведения и раундов, присутствующих в базе партий.

Формат файла sg4

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

Формат партии

Каждая партия состоит из следующих записей, идущих одна за другой без разделителей:

Формат записи неосновных тегов.

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

В описании каждого тега сначала записывается название тега, а затем его значение.

Если в списке идёт один из стандартных тегов, то его название кодируется одним байтом с номером этого тега. Номера стандартных тегов:

  • 241 - WhiteCountry
  • 242 - BlackCountry
  • 243 - Annotator
  • 244 - PlyCount
  • 245 - EventDate
  • 246 - Opening
  • 247 - Variation
  • 248 - Setup
  • 249 - Source
  • 250 - SetUp
  • 251-254 - зарезервированы
  • 255 - EventDate. В этом случае значение этого тега записывается в последующих трёх байтах в формате даты.
Любой тег, не входящий в этот список, а также не являющийся одним из семи основных тегов, кодируется Pascal-строкой.

Примечание: длина названия тега не должна превышать 240 байт.

Значение тега всегда (кроме случая, когда номер тега равен 255) записывается в виде Pascal-строки.

Запись ходов

Здесь хранится последовательность закодированных ходов, а также маркеры, которые сообщают о том, что в данном конкретном месте партии должна быть помещена какая-то дополнительная информация.

Маркеры кодируются байтами с номерами от 11 до 15. То есть, если при чтении последовательности ходов встречается байт с таким номером, то это маркер. В противном случае это закодированный ход. Значения маркеров:

  • 11 - Описывается метка NAG
    После этого маркера следует один байт, описывающий метку (коды меток идентичны кодам в формате pgn)
  • 12 - Указывает на то, что на этом месте в описании партии должен быть комментарий (комментарии берутся позже из области комментариев)
  • 13 - Начало ответвления
  • 14 - Конец ответвления
  • 15 - Конец партии

Шахматный ход обычно кодируется одним байтом. Некоторые ходы ферзя кодируются двумя байтами. Формат хода определяется так:

Тип хода зависит от фигуры, которая ходит.
  • Пешка
    • 0 - взятие влево
    • 1 - вперёд на одну клетку
    • 2 - взятие вправо
    • 3, 4, 5 - аналогично 0, 1, 2, но с продвижением в ферзя
    • 6, 7, 8 - аналогично 0, 1, 2, но с продвижением в ладью
    • 9, 10, 11 - аналогично 0, 1, 2, но с продвижением в слона
    • 12, 13, 14 - аналогично 0, 1, 2, но с продвижением в коня
    • 15 - вперёд на две клетки
  • Конь
    • 1 - ход (-1, -2) (одна клетка влево, две клетки вниз)
    • 2 - ход (1,-2)
    • 3 - ход (-2,-1)
    • 4 - ход (2,-1)
    • 5 - ход (-2,1)
    • 6 - ход (2,1)
    • 7 - ход (-1,2)
    • 8 - ход (1,2)
    • Остальные номера не используются
  • Слон
    • биты 0 - 2: координата столбца клетки, куда идёт слон. 0 соответствует столбцу a; 7 - столбцу h
    • бит 3:
      • 0: слон движется по диагонали влево-вниз --- вправо-вверх
      • 1: слон движется по диагонали влево-вверх --- вправо-вниз
  • Ладья
    • 0 - 7: горизонтальный ход на клетку с координатой столбца a (соответствует нулю) - h (соответствует семи)
    • 8 - 15: вертикальный ход на клетку с координатой строки 1 - 8 (из указанного кода необходимо вычесть 7)
  • Ферзь
    Горизонтальный и вертикальный ходы хранятся в одном байте, а ходы по диагонали - в двух байтах.
    Значения первого байта:
    • 0 - 7: горизонтальный ход на клетку с координатой столбца a (соответствует нулю) - h (соответствует семи)
    • 8 - 15: вертикальный ход на клетку с координатой строки 1 - 8 (из указанного кода необходимо вычесть 7)
    Если ход диагональный, то в первом байте кодируется горизонтальный ход на клетку, на которой уже находится ферзь. Это делает ход нелегальным. Нелегальность является признаком диагонального хода. Следующий байт в этом случае указывает на номер клетки, куда пойдёт ферзь, плюс 64 (a1 = 64,..., a8 = 71,..., h8 = 127).
  • Король
    • 0 - пустой ход. Означает, что игрок не сделал никакого хода, а просто передал ход сопернику. Формально такой ход нелегален, однако иногда бывает полезен при описании партии.
    • 1 - ход (-1, -1) (одна клетка влево и вниз)
    • 2 - ход (0,-1)
    • 3 - ход (1,-1)
    • 4 - ход (-1,0)
    • 5 - ход (1,0)
    • 6 - ход (-1,1)
    • 7 - ход (0,1)
    • 8 - ход (1,1)
    • 9 - длинная рокировка
    • 10 - короткая рокировка
    • Остальные номера не используются

Формат записи комментариев.

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

Формат файла si4

В этом файле хранятся индексы всех партий. Под индексом здесь понимается краткое описание партии вместе с указателем на начало её полного описания в файле sg4.

Файл состоит из заголовка, после которого следует последовательность индексов для каждой партии. Размер заголовка всегда равен 182 б, размер каждого индекса - 47 б (в текущей версии). Таким образом, чтобы перейти к описанию партии с индексом n следует перейти к байту 182 + 47 * n.

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

  • Сигнатура (8 б). Для текущих версий формата она равна "Scid.si"#0.
  • Версия формата (2 б). представляет собой число. Формируется так: <мажорная версия> * 100 + <минорная версия>. Значение для текущей версии - 400. Однако формат, вероятно, будет поддерживать и версии 3.0.
  • Тип файла с партиями (4 б). Здесь можно указывать, что собой представляют партии из файла: партии турнира, теорию и т.п. Обычно он равен 0, и я не знаю, есть ли возможность установить его во что-нибудь другое. Скорее всего, поддержка этого поля пока не реализована.
  • Количетво партий в файле (3 б). Таким образом, максимальное число партий в базе может быть 16777215.
  • Номер партии, которая должна быть автоматически загружена при загрузке файла (3 б). Возможные значения:
    • 0 - первая партия;
    • 1 - партия не определена;
    • 2 - первая партия;
    • ................................................
    • n - (n-1)-я партия.
  • Строка с общим описанием базы партий (108 б). Символом окончания строки является нулевой байт. Все байты, следующие после него внутри данного поля, игнорируются.
    Длина этого поля, вероятно, может меняться от версии к версии.
  • 6 записей по 9 б: короткие описания для пользовательских флагов. Каждая из записей представляет собой строку. Символом окончания строки является нулевой байт. Все байты, следующие после него внутри каждой записи, игнорируются.

Формат индекса

В версиях формата до 3-ей размер каждой записи с индексом был 46 б. В последующих версиях он равен 47 б.
  • start_pos (4 б) - указатель на начало записи с партией в файле sg4.
  • low_len (2 б) - нижние 16 бит длины записи с партией в файле sg4.
  • битовое поле (1 б):
    • бит 7: high_len, 17-й бит длины записи с партией. Таким образом, длина записи с партией равна
      	high_len shl 16 + low_len
      Примечание: максимальная длина партии равна 217 - 1 байт.
    • бит 6: запасной. Ничего не делает.
    • биты 0 - 5: пользовательские флаги.
  • flags (2 б) - флаги:
    • бит 0: если равен 1, то у партии нестандартная стартовая позиция
    • бит 1: если равен 1, то в партии есть продвижение пешки
    • бит 2: если равен 1, то в партии есть продвижение пешки во что-то, кроме ферзя
    • бит 3: если равен 1, то партия помечена к удалению
    • бит 4: флаг для дебюта белых
    • бит 5: флаг для дебюта чёрных
    • бит 6: флаг для миттельшпиля
    • бит 7: флаг для эндшпиля
    • бит 8: флаг для новинки
    • бит 9: пешечная структура
    • бит 10: игра королевского фланга
    • бит 11: игра пешечного фланга
    • бит 12: отличная игра
    • бит 13: плохая игра
    • бит 14: задаётся пользователем
  • 1 б - старшие биты для идентификаторов игроков белыми и чёрными:
    • биты 0 - 3: high_black для идентификатора чёрных
    • биты 4 - 7: high_white для идентификатора белых
  • low_white (2 б) - младшие биты для идентификатора игрока белыми. Таким образом, идентификатор игрока белыми вычисляется как
    	high_white shl 16 + low_white
    Имя игрока по этому идентификатору определяется в файле sn4.
  • low_black (2 б) - младшие биты для идентификатора игрока чёрными. Таким образом, идентификатор игрока чёрными вычисляется как
    	high_black shl 16 + low_black
    Имя игрока по этому идентификатору определяется в файле sn4.
  • 1 б - старшие биты для идентификаторов турнира, места проведения и раунда:
    • биты 0, 1: high_round для идентификатора турнира
    • биты 2 - 4: high_site для идентификатора места проведения
    • биты 5 - 7: high_tourn для идентификатора турнира
  • low_tourn (2 б) - младшие биты для идентификатора турнира. Таким образом, идентификатор турнира вычисляется как
    	high_tourn shl 16 + low_tourn
    Название турнира по этому идентификатору определяется в файле sn4.
  • low_site (2 б) - младшие биты для идентификатора места проведения. Таким образом, идентификатор места проведения вычисляется как
    	high_site shl 16 + low_site
    Название места проведения по этому идентификатору определяется в файле sn4.
  • low_round (2 б) - младшие биты для идентификатора раунда. Таким образом, идентификатор раунда вычисляется как
    	high_round shl 16 + low_round
    Название раунда по этому идентификатору определяется в файле sn4.
  • битовое поле (2 б):
    • биты 0 - 3: кодируется число ответвлений
    • биты 4 - 7: кодируется число комментариев
    • биты 8 - 11: кодируется число меток
    • биты 13 - 16: результат партии. Возможные значения:
      • 0 - результат неизвестен или не определён (*)
      • 1 - выигрыш белых (1-0)
      • 2 - выигрыш чёрных (0-1)
      • 3 - ничья (1/2-1/2)
    Число комментариев/ответвлений/меток по закодированному значению cod вычисляется так:
    • cod между 0 и 9: число совпадает с cod;
    • cod = 10: число находится между 10 и 12;
    • cod = 11: число находится между 13 и 17;
    • cod = 12: число находится между 18 и 24;
    • cod = 13: число находится между 25 и 34;
    • cod = 14: число находится между 35 и 44;
    • cod = 15: число больше 44.
  • ECO_code (2 б) - ECO код дебюта. Определяется следующим образом:
    Если равен нулю, то код неизветен.
    В противном случае порядковый номер кода равен (ECO_code - 1) div 131. Значение (ECO_code - 1) mod 131 равно номеру расширения ECO кода.
    Коды ECO следуют в таком порядке: A00 - 0, A01 - 1, A02 - 2,..., A99 - 99, B00 - 100, B01 - 101,..., B99 - 199,..., E99 - 499.
    Расширения следуют в таком порядке: неизвестен - 0, a - 1, a1 - 2, a2 - 3, a3 - 4, a4 - 5, b - 6, b1 - 7,..., z4 - 130.
  • 4 б (сдвоенная дата) - дата проведения и дата турнира (EventDate)
  • рейтинг белых (2 б). Его формат:
    • биты 0 - 11: непосредственно значение рейтинга
    • биты 12 - 15: тип рейтинга. Возможные типы:
      • 0: ELO
      • 1: Просто рейтинг, что бы это ни значило
      • 2: Рапид
      • 3: ICCF
      • 4: USCF
      • 5: DWZ
      • 6: BCF
      • Остальные значения не используются
  • рейтинг чёрных (2 б). Формат этой записи совпадает с предыдущей.
  • StoredLineCode (1 б) - нечто, связанное с оценкой последней позиции в партии.
  • 3 б - информация о материале в последней позиции партии.
  • low_plyes (1 б) - нижние 8 бит от числа полуходов в партии (только в основной ветке).
  • битовое поле (1 б):
    • биты 0 - 5: начало 9-байтового массива для HomePawnData (не знаю точное его предназначение)
    • биты 6, 7: high_plies, старшие биты от числа полуходов в партии. Таким образом, число полуходов вычисляется как
      	high_plies shl 8 + low_plies
  • 8 б - остальные байты из массива HomePawnData.

Формат файла sn4

В этом файле хранятся имена всех игроков, названия всех турниров, мест проведения и раундов, присутствующих в базе партий. Для сокращения размера базы обращение к этим названиям в файле индексов идёт по их порядковым номерам из этого файла.

Названия каждого отдельного типа сохраняются в алфавитном порядке. Если первые n букв у некоторой записи совпадают с n буквами предыдущей записи, то в файле имён эти буквы будут опущены, а вместо них будет записано число n.

Файл состоит из заголовка, сразу после которого идут массивы названий в следующем порядке: имена игроков, турниры, места проведения и раунды. Массивы не разделяются никакими разделителями.

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

  • сигнатура (8 б). Для текущей версии формата она равна "Scid.sn"#0.
  • TimeStamp (4 б). Не знаю, что такое. В файлах, которые встречались мне, он равен нулю.
  • число записей игроков (3 б).
  • число записей турниров (3 б).
  • число записей мест проведения (3 б).
  • число записей раундов (3 б).
  • максимальное число использований одной и той же записи игрока (3 б).
  • максимальное число использований одной и той же записи турнира (3 б).
  • максимальное число использований одной и той же записи места проведения (3 б).
  • максимальное число использований одной и той же записи раунда (3 б).

Описание массива названий.

Структура всех массивов одинакова. Их формат:
  • идентификатор записи (2 или 3 б). Если всего названий больше, чем 65535 (число названий берётся из соответствующей записи в заголовке файла), то он займёт 3 байта, иначе - 2.
  • сколько раз встречалось название (1, 2 или 3 б). Если максимальное число раз использований названий этого типа больше 65535, то он займёт 3 байта. Если оно между 256 и 65535, то 2 байта. Иначе - 1 байт. (Максимальная число раз использований названий берётся из соответствующего поля в заголовке).
  • name_length (1 б) - число символов в названии.
  • если это не первая запись в массиве, то name_n (1 б) - число первых байт записи, совпадающих с первыми байтами предыдущей записи. Для первой записи name_n устанавливается в 0.
  • строка с названием записи. Её длина равна name_length - name_n байт. В ней опускаются первые name_n символов, которые совпадают с первыми символами предыдущей записи.

Нумерация фигур на доске.

В формате SCID каждая фигура задаётся её порядковым номером. Номера фигурам присваиваются на стартовой позиции партии и далее на протяжении партии они могут меняться. Белые и чёрные фигуры нумеруются отдельно.

Инициализация

Если начальная позиция не задаётся в формате fen (то есть начальная позиция стандартна), то номера фигур распределяются следующим образом:

  • 1 : ладья на a
  • 2 : конь на b
  • 3 : слон на c
  • 4 : ферзь
  • 5 : слон на f
  • 6 : конь на g
  • 7 : ладья на h
  • 8 - 15 : пешки на a + 7

Если начальная позиция задаётся строкой fen, то алгоритм расстановки номеров фигурам следующий. Нумерация фигур начинается с нуля. Строка fen читается слева направо. Когда в ней встречается описание фигуры, то

  • если это не король, то фигуре присваивается минимальный незанятый номер для фигур соответствующего цвета.
  • если это король, то ему присваивается номер ноль. Если ноль при этом уже занят другой фигурой, то её номер меняется на минимальный незанятый номер для фигур соответствующего цвета.

Пример: для позиции, заданной строкой rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 (начальная позиция) нумерация фигур будет такой:

Изменение нумерации на протяжении партии

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

При продвижении пешки номер появившейся фигуры будет совпадать с номером пропавшей пешки.

Пример. Рассмотрим короткую партию, начинающуюся с позиции 1n1k4/6Q1/5Kp1/5P2/8/6b1/1p6/8 w - - 0 1

ХодПозицияНумерация
 
1. fxg6
1... b1=Q

Используемые типы данных

C-строка

Эта строка переменной длины. Признаком окончания строки является нулевой байт. Любой другой байт задаёт один символ строки.

Pascal-строка

Состоит из двух полей:
  • len (1 б) - длина строки.
  • сама строка (len б).

Дата

Занимает ровно 3 байта, представляющих собой битовое поле:
  • биты 0 - 4: число. Если равно нулю, то число не известно.
  • биты 5 - 8: месяц. Если равен нулю, то месяц не известен.
  • биты 9 - 19: год. Если равен нулю, то год не известен.

Сдвоенная дата

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

Сдвоенная дата представляет собой битовое поле:

  • биты 0 - 4: число из первой даты. Если равно нулю, то число не известно.
  • биты 5 - 8: месяц из первой даты. Если равен нулю, то месяц не известен.
  • биты 9 - 19: год из первой даты. Если равен нулю, то год не известен.
  • Если год второй даты отличается от года первой даты более, чем на три, то все последующие биты устанавливаются в ноль (в этом случае вторая дата не известна).
    В противном случае мы имеем:
  • биты 20-24: число из второй даты. Если равно нулю, то число не известно.
  • биты 25-28: месяц из второй даты. Если равен нулю, то месяц не известен.
  • биты 29-31: <год из второй даты> - <год из первой даты> + 4.

      Бодягин Дмитрий (c) 2013
      Если у вас есть замечания по тексту, либо пожелания, какую ещё информацию следует добавить в дебютную книгу, - пишите на info@kvetka.org.