|
Описание формата баз партий от SCID.
Шахматные базы программы SCID могут содержать в себе множество шахматных партий, для каждой из которых, помимо непосредственно набора ходов, могут храниться ответвления, комментарии, метки, а также различная сопутствующая игнформация (имена игроков, название турнира, дата проведения и т.п.) Партии в этом формате занимают существенно меньше пространства на диске, чем в стаднартном формате PGN.
Как и в формате PGN, информация о партии разделяется на непосредственно описание партии и набор тегов к ней. В описание партии входит последовательность ходов вместе с комментариями и метками, а также информация об ответвлениях от основной линии. Под метками понимается информация, характеризующая ход или позицию после хода (сильный, слабый, сомнительный ход и т.п.).
Каждый тег состоит из двух частей: название тега и его значение. Каждый из них даёт некоторую информацию о партии в целом. Названия и значения тегов полностью совпадают с соответствующими названиями и значениями из формата PGN. Имеется семь обязательных тегов, которые должны присутствовать в каждой партии. Информация о них хранится в файле индексов. Все дополнительые теги (описания наиболее стандартных из них можно найти здесь) хранятся в основном файле партий.
SCID - программа с открытым кодом. Поэтому все её исходные коды, включая и отвечающие за работу с базами партий, доступны. Их можно скачать вместе с самой программой по адресу scid.sourceforge.net/download.html.
База партий от SCID состоит из следующих файлов:
- sg4 - описания всех партий;
- si4 - индексы всех партий (для связывания номера партии и её описания);
- sn4 - хранит имена всех игроков, турниров, мест проведения и раундов, присутствующих в базе партий.
Формат файла sg4
В этом файле содержатся непосредственно описания всех партий. Обычно они записываются с нулевого байта и идут одна за другой без разделителей (хотя теоретически это правило может и не выполняться).
Формат партии
Каждая партия состоит из следующих записей, идущих одна за другой без разделителей:
- Описание всех тегов, кроме основных семи.
- 1 байт флагов:
- бит 0 (младший): У партии нестандартное начало.
- бит 1: Если есть хотя бы одно продвижение пешки.
- бит 2: Если есть продвижение пешки во что-то, кроме ферзя.
- Если начало нестандартное, то пишется FEN позиция в C-строке. Информация о том, что начало нестандартное, содержится во флагах индекса партии.
- Последовательность ходов.
- Комментарии.
Формат записи неосновных тегов.
Все теги записываются друг за другом без разделителей. Теги никак не упорядочиваются. Сразу за последним тегом записывается нулевой байт, символизирующий окончание описания тегов.
В описании каждого тега сначала записывается название тега, а затем его значение.
Если в списке идёт один из стандартных тегов, то его название кодируется одним байтом с номером этого тега. Номера стандартных тегов:
- 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 б):
- 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 б):
- 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.
|