Напишите алгоритм или программу, которая может кодировать и декодировать шахматную доску. Цель состоит в том, чтобы сделать наименьшее представление шахматной доски, которую можно было бы использовать (после декодирования), чтобы определить все возможности перемещения для игрока на этом ходу.
Кодировка должна быть в состоянии показать:
- Чья это очередь?
- Может ли игрок замок на каждой стороне.
- Может ли игрок выполнить эн-пасса, и если да, то какая из его пешек?
- Позиции всех фигур.
Важное примечание о рокировке: если белые перемещают своего короля на один ход, а затем перемещают его назад на следующий, должно быть ясно, что после этого они не смогут захватить замок с обеих сторон. То же самое произошло бы, если бы они переместили левую или правую ладью. Несмотря на то, что доска визуально находится в том же состоянии, что и два хода назад, игровое состояние изменилось. Более подробная информация здесь: http://en.wikipedia.org/wiki/Chess#Castling
Важное примечание о проходе: это также ход, чувствительный к повороту. Прочитайте правила для получения дополнительной информации. http://en.wikipedia.org/wiki/Chess#En_passant
Определите вход и выход при необходимости. Основные реквизиты для тех, кто может сжать его больше всего!
Ваша оценка определяется наихудшим сценарием - максимально возможным размером в битах. Убедитесь, что вы показываете, как вы рассчитали это число и что вы учли. Стреляй в самый маленький наихудший случай!
источник
Ответы:
Мин: 12 бит
Макс:
Ср.
Прошлой ночью я думал, что смогу сделать его еще меньше.
В результате впечатляющий размер 12 бит !
Так что насчет К +1 другого типа фигуры?
Есть 2 возможных расположения поддерева.
Оба дают одинаковые размеры для всех кусков. Так что не имеет значения, что мы используем, я выберу первый.
Так что на короле +2 других типов штук
Есть 5 возможных поддеревьев (я буду использовать 1 и 2, чтобы указать, какие из частей.)
Поэтому нам потребуется 3 бита, чтобы закодировать, какое поддерево использовать.
Все еще делаю анализ для большего количества частей
+3 Другое
+4 Другое
+5 Другое
Макс: 208?
Можно ли закодировать все эти поддеревья в 9 бит?
Если мы суммируем все возможные поддеревья, мы получим 392 возможных поддеревья.
Использование Freq ID
С 164603 уникальных штук частот .
(+000) (+00) Рокировка
Макс .: = 204 бит
ред 3
Мин .: 82 Макс .: 199 Средний: 160
Наконец-то удалось немного проанализировать, чтобы найти максимальный размер бита. С оптимальным кодированием Хаффмана для каждой из уникальных частот .
Обратите внимание, что это наихудший возможный размер, который бит столбца En-Passant, если количество пешек больше единицы. Независимо от цвета и положения этих пешек, некоторые доски могут быть на 3 бита меньше.
Также есть всего 144 разных размера (в худшем случае) для размера платы.
75 - 216 бит (v2) v1 Минимальный размер 98 бит (12,25 байт), только два короля на плате.
Максимальный размер составляет всего 216 бит (27 байт.).
В среднем размер будет около 157 бит (19,625 байт).
Частей
Для кодирования платы я использую схему кодирования двоичного дерева. Пустой квадрат чаще всего встречается в любом месте между 32 и 62 появлениями. Далее идут пешки, затем грачи, рыцари, епископы, а наименее часто встречаются королева и король.
Начальная плата может быть закодирована в 166 битах (20,75 байта)
Чтобы указать, чей ход, требуется всего один бит
Рокировка может быть закодирована в 4 бита.
Поэтому я использую 171 бит (21,375 байт)
En-Passe может быть закодирован в 16 бит (2 байта)
Таким образом, в общей сложности это 187 бит (23,375 байт).
раскладка
Еще не написано ни одного кода.
Обратите внимание, что 3 из битов не используются. Таким образом, максимум составляет 213 бит .
Возможные улучшения
1) Уменьшена форма блока заголовка с 24 до 8 бит (с предложением @Peter Taylor)
2) заголовок переменной длины
Небольшой 4-битный фиксированный заголовок
Следующий блок дополнительных битов (если рокировка все еще возможна)
Следующий блок дополнительных битов (если присутствуют пешки)
Так что теперь у меня есть заголовок переменной длины 4 - 11 бит
3) Используйте другую схему кодирования в зависимости от того, какие части остались на плате.
Путем изменения дерева кодирования в зависимости от того, какие фигуры есть на плате и есть ли частота.
Одно возможное кодирование для состояния завершения игры (без пешек)
Что составляет ~ 4 бита за штуку.
Какие фигуры присутствуют на доске?
Перестановка переменной длины 0-5 бит. Если остался только один тип произведения, не включайте его.
Какую перестановку этих кусочков использовать для дерева? Это факториал количества штук в приведенном выше примере, это 5 штук, поэтому 120 возможных перестановок могут быть закодированы.
Помните, что есть дополнительные биты для пустых квадратов и цвета.
Примеры
Давайте приведем пример только QK осталось
Всего 81 бит
Давайте приведем и пример только королей осталось
Положить все вместе
Поэтому я рассчитываю наименьшую кодировку для платы на 75 бит (9 бит 3 бит)
Еще предстоит рассчитать, как эта схема кодирования влияет на максимальный размер.
Улучшение 4
Уменьшите количество бит для рокировки до 2 бит. Просто рокировка для игрока, чья очередь.
Подумав об этом, может быть, лучше просто включить 2 бита в блок заголовка.
источник
1111
для «невозможного прохода» или для столбца в виде двоичного числа в противном случае).192 бита (наихудший случай)
Вот очень простая схема хранения, которая должна справляться с произвольным продвижением пешки и никогда не требует больше, чем 64 + 4 × 32 = 192 бита:
Первые 64 бита хранят битборд, который сообщает, где находятся фрагменты (но не то, что они есть). То есть мы храним один бит для каждого квадрата шахматной доски (начиная с квадрата a1, затем b1, c1 и т. Д. До квадрата h8), так что свободный квадрат представлен 0, а занятый квадрат - 1.
Далее, для каждого из квадратов, помеченных как занятые на битовой доске, мы сохраняем 4-битный полубайт, кодирующий фрагмент на этом квадрате. Первый из четырех битов кодирует цвет куска (0 = белый, 1 = черный), а остальные три бита кодируют тип куска:
Обратите внимание на две кодировки для короля, которые используются для определения хода игрока. (Фактически, поскольку на плате всегда есть два короля, допускающие четыре комбинации кодов 5 и 6, мы могли бы довольно легко закодировать здесь второй бит информации.)
Чтобы закодировать дополнительную информацию, необходимую для правил en passant и castling, мы вводим один дополнительный тип фигуры, который обозначает пешку или ладью в зависимости от строки, на которой он появляется:
Собираем все вместе:
Таким образом, общее количество битов, необходимых для кодирования состояния платы, составляет 64 + 4 × # штук на плате. Поскольку на плате никогда не может быть больше 32 элементов, максимальная длина этого кодирования составляет 192 бита.
Например, используя описанную выше кодировку, начальное состояние платы будет закодировано как (пробел вставлен для удобства чтения):
или в шестнадцатеричном виде:
источник
160 бит в худшем случае
После публикации моего предыдущего ответа 22 байта я начал задаваться вопросом, можем ли мы сократить до 21 байта. Однако когда я увидел удивительные 166 байтов Питера Тейлора, я подумал: «Погоди, похоже, что пять 32-битных слов могут быть возможны!»
Поэтому, после долгих размышлений, я придумал следующее: 159,91936391 байт (довольно плотное прилегание!). Для этого уровня сжатия потребуется довольно сложная программа, но я подумал о том, как заставить ее работать в разумные сроки.
Это будет длинный пост, поэтому, пожалуйста, потерпите меня, я опубликую все, что смогу сегодня, и скоро добавлю несколько кусочков кода.
Итак, вот как это сделать:
En Passant и рокировка, закодированные недопустимыми позициями (0 битов)
Мимоходом
Как упоминалось в других ответах, существует максимум 5 возможных квадратов, на которых может стоять пешка, уязвимая для проходящего. Это квадраты рядом с пешками игрока, чей ход.
Чтобы закодировать это, пешка, уязвимая для прохода, заменяется тем, что находится на одном из квадратов в первом или последнем ряду. Это может быть либо человек, либо пустой квадрат. Это создает недопустимую позицию, так как пешки не могут быть в этих рядах. Декодер должен вернуть пешку в правильное положение, извлекая всю проходящую информацию.
Чтобы это не мешало кодированию рокировки, важно, чтобы квадраты, на которых стоят короли в начале игры, не нарушались, и чтобы процедура кодирования en passant не помещала королей рядом друг с другом, что было бы незаконным положением короля. Чтобы удовлетворить вторую из этих точек, у кодера есть два выбора, на какую клетку он обменивает проходную пешку. Первый квадрат выбора для каждой из до 5 пешек - A8, B8, C8, G8, H8. Второй выбор: A1, B1, C1, G1, H1.
Рокировка
Король, которому разрешено замок, по определению все еще находится на своей первоначальной площади. С белым королем на его начальном поле есть в общей сложности 63 квадрата, в которых может стоять черный король, 58 из которых являются законными (ему не разрешается двигаться рядом с белым королем, потому что он поставит себя под контроль). Если белый король имеет право на замок, ему разрешают либо замок с левой ладьей, правой ладьей, или оба. Таким образом, существует 3x58 = 174 возможностей, где белый король может блокировать, еще 174, где черный король может блокировать, и еще 3x3 = 9, где оба могут блокировать, в общей сложности 357.
Есть 420 незаконных расположений двух королей, где они находятся на соседних клетках: 3x4 = 12, когда белый король находится в углу, 5x24 = 120, когда он на краю, и 8x36 = 288, когда он находится на другой клетке. Поэтому нелегких позиций достаточно, чтобы закодировать все возможные возможности рокировки.
Если хотя бы одному королю разрешено блокировать, кодировщик просматривает данные о замки и позиционные данные тех королей, которым не разрешено блокировать в таблице (или, альтернативно, использовать алгоритм, который я здесь не буду указывать) и выдает недопустимый Положение двух королей. Затем он обменял королей на то, что случилось на этих площадях.
Важно, чтобы это кодировалось после и декодировалось перед пользователем, в противном случае есть некоторые потенциальные помехи.
сравнение
Итак, пока я не использовал биты! Глядя на ответ Питера, я все еще могу закодировать следующее:
Это для наихудшего случая из 29 человек (см. Ответ Питера). Ниже я покажу, как добиться незначительного улучшения (по крайней мере, в случае с 29 мужчинами) по обоим пунктам, отмеченным в **.
Какие квадраты заняты / чья очередь?
Простой способ кодировать, какие квадраты заняты, с помощью 64-битной сетки. Это также говорит нам, сколько квадратов занято. Однако это несколько расточительно, потому что не может быть занято более 32 квадратов. Мое решение состоит в том, чтобы использовать 1 для кодирования занятых квадратов, когда настала очередь белых, и 0 для кодирования занятых квадратов, когда настала очередь черных. Теперь все комбинации используются и нет отходов.
Таким образом, мы экономим на хранении хода: менее 32 1, это ход белых, более 32 1, это ход черных. Единственный неоднозначный случай - это когда все мужчины находятся на доске, и есть 32 1 и 32 0. Поэтому дополнительный бит необходим только для этого случая. Поскольку не может быть никаких повышений до тех пор, пока не произойдет захват, этот дополнительный бит не влияет на наихудший случай в целом (что происходит при захвате 3 мужчин и оставшихся 29).
Цвет мужчин, занимающих квадраты
Из вышесказанного мы знаем, сколько людей. Следующий фрагмент треугольника Паскаля показывает, сколько существует возможностей для различных распределений черного и белого. Например, для 3 мужчин возможны следующие варианты: 3 черных мужчины (1 перестановка) 2 черных, 1 белый (3 перестановки), 1 черный, 2 белых (3 перестановки), 3 белых (1 перестановка). Всего 2 3 = 8. В общем, для меньшего числа мужчин есть 2 n возможностей. Тем не менее, все черные и все белые возможности недопустимы (по крайней мере, король каждой стороны должен быть на доске), поэтому фактическое число допустимых перестановок составляет 2 n -2 (игнорируйте 1 в треугольнике Паскаля).
Для более чем 16 человек всего существует дополнительное ограничение в том, что на доске может быть не более 16 человек каждого цвета. Поэтому, когда на доске присутствуют все 32 человека, их должно быть по 16, а общее число возможных вариантов составляет 601080390, что немного меньше, чем 2 32 .
Количество возможностей можно найти, суммируя «строки» этого фрагмента треугольника Паскаля (под этим я подразумеваю диагонали NE-SW таблицы, потому что я повернул треугольник на 45 градусов против часовой стрелки для удобного представления. Число необходимых битов). поэтому кодировать ход, занятые квадраты и цвет мужчин следующим образом:
До 25 мужчин: чуть менее 64+ (количество мужчин)
Для более 25 мужчин:
Для двух цветов, какие мужчины и в каком порядке?
Как и в предыдущих ответах, никакие пешки не могут быть повышены до тех пор, пока не произойдет захват, потому что каждая пешка блокируется пешкой противоположного цвета в том же столбце. В ответе Питера считалось (как верхняя граница), что каждый захват может привести к одному продвижению за захваченную сторону и двум за захват стороны. Однако мы можем разделить это на несколько случаев:
Черная пешка захватывает белую пешку: теперь пешка захвата может свободно продвигаться, поскольку теперь она находится в другой колонне. Его коллега по этой же колонке тоже может продвинуться. Черная пешка на оригинальной колонне белой пешки также может продвигаться. Это единственный случай, когда разрешено 3 промоушена.
Черная пешка проходит мимо белой пешки в соседнем столбце, а затем захватывает белую фигуру (кроме пешки) позади. Это позволяет сделать пешку захвата и белую пешку, находившуюся в исходном столбце. Одна акция для каждой стороны.
Белая пешка захватывается поштучно (кроме пешки). Это обычно разрешает одно повышение только для черных. Единственное исключение - когда он освобождает блокированную пешечную группу, которая уже была вызвана несколькими захватами, перемещающими пешек в одну и ту же колонну.
Таким образом, в качестве базового случая мы можем считать, что каждый захват позволяет по одному продвижению для обеих сторон. В случае, если захваченный человек является пешкой, может быть дополнительное продвижение для стороны захвата.
Я написал программу, похожую на программу Питера. Это несколько грубее, но у него есть важное дополнение: он может рассчитать количество возможных перестановок, когда игрок начинает с нормальными 8 пешками. Вот некоторые данные, полученные программой:
Мы можем видеть, что для случая, такого как 8 пешек, 15 мужчин, 0 повышений, число перестановок лишь немного меньше, чем для 8 пешек 16 мужчин, 0 повышений. Однако, если мы рассмотрим такой случай, как 7 пешек, 15 мужчин, 0 повышений (что аналогично предположению, что захваченный человек определенно является пешкой), мы получим примерно половину числа перестановок.
Итак, для случая, когда у черных 16 мужчин, а у белых 15 мужчин, мы можем рассмотреть верхнюю границу для 2 промоций для черных и одного промоушена для белых:
Однако мы можем добиться большего успеха, если будем действовать следующим образом.
A. Рассмотрим одну акцию для черно-белых, предполагая, что человек, которого потеряли белые, может быть любого типа:
Б. Рассмотрите дополнительные возможности для черных, если у них есть два продвижения, помноженные только на те возможности для белых, в которых он потерял пешку.
Сложив эти два значения вместе, мы получим 2.25072E + 18, что меньше, чем 3.55766E + 18. Все возможности до 3 захватов (осталось 29 человек) перечислены ниже.
Так что для наихудшего случая с одной стороной с 15 мужчинами и другой с 14 мужчинами нам нужно 67.804 бит.
Добавляя это к 92,116 битам, необходимым для указания того, какие квадраты и какой цвет, мы получаем в сумме 67,804 + 92,116 = 159,92 бита.
источник
177 бит в худшем случае
Этот алгоритм, хотя и не простой, дает 177-битный худший случай (184b = 23B на практике), 13b (16b = 2B) лучший вариант, когда осталось только 2 короля.
источник
sum_{i=0}^{15} sum_{j=0}^{15} 62! / (i! j! (62-i-j)!) < 2^87.45
,166 бит
1
немного: чья это очередь?2
биты: какие варианты рокировки открыты? (NB при внимательном прочтении вопроса, необходимо записать параметры рокировки только для игрока, чей это ход).lg 6 ~= 2.585
биты: какие варианты en passant открыты? (См. Мой другой ответ)lg sum_{i=1}^{16} sum_{j=1}^{16} 64! / (i! j! (64-i-j)! = lg 3629590441720924477681996172 ~= 91.552
биты: какие квадраты заняты людьми какого цвета?lg 451366131803622235200 ~= 68.613
чтобы указать, какие люди и в каком порядке (см. Ниже)Используя арифметическое кодирование (поскольку на каждом этапе мы применяем равномерное распределение), мы можем получить
ceil(3 + 2.585 + 91.552 + 68.613) = 166
биты.Кодировка для мужчин: учитывая, что мы знаем, сколько мужчин данного цвета, мы можем легко перечислить все возможные распределения / мультимножества мужчин (например, с 5 мужчинами у нас может быть один король, одна королева, две грачи и Пешка) и тогда мы можем рассмотреть все возможные перестановки каждого распределения.
Тем не менее, мы можем сделать еще лучше, принимая во внимание взаимозависимости. Я делаю это только на самом базовом уровне: сколько возможных рекламных акций? Пешка может стать «пройденной» и способна продвигаться только тремя способами: она захватывает и перемещается в другой столбец; или его противоположная пешка захватывает и поэтому перемещается в другую колонну; или его противоположная пешка захвачена. Таким образом, захват белых потенциально создает две пройденные пешки для белых и одну для черных.
Мы можем составить частичную таблицу верхних границ для рекламных акций:
Мы также можем рассчитать количество перестановок, учитывая, что у игрока есть
N
мужчины и не более чемP
продвинутые пешки:Комбинируя их, мы можем получить количество бит, необходимое для указания обеих перестановок, учитывая количество людей с обеих сторон:
Если этого нет в этом разделе таблицы, мы можем просто предположить, что у обеих сторон есть до 8 промо-акций, и мы все еще лучше, чем в худшем случае, который составляет 68,613 бит, когда у одного 14 мужчин, а у другого 15 мужчин.
Обратите внимание, что до идеального представления еще далеко, потому что он допускает много нелегальных позиций.
Код для расчета таблицы перестановок:
источник
<
скорее, чем<=
в цикле вывода моей программы. Спасибо за указание на это. Я все еще мог восстановить предыдущий счет, используя специальный корпус для всех 32 человек, находящихся на доске, но сейчас я не буду этого делать.178 бит (174 в крайнем случае!) В худшем случае
Привет, просто возвращаюсь к кодированию, чего я не делал со времен колледжа. Я видел этот сайт и думал, что это выглядит интересно. Я провел небольшую теоретическую проверку, и оказалось, что для идеального алгоритма необходимо по крайней мере 146 бит, возможно, еще несколько (я объясню в комментариях, когда у меня будет время).
Во всяком случае, так я структурирую данные. Основная концепция представлена в 178 битах, но с некоторыми покерными играми она может быть уменьшена до 174 (это 21 3/4 байта). 175 немного легче программировать, он более читабелен и все еще в пределах 22 байтов.
А) Положение обоих королей: 6 бит каждый для белого и черного 12
Б) Из оставшихся 62 квадратов, которые заняты? Матрица 62 БИТОВ
В) чья это очередь?1 бит
ВСЕГО ТАК ДАЛЬШЕ: 75 БИТОВ
D) En Passant.Если очередь за ходом у белых, то до 5 черных пешек могут выглядеть так, будто они могут быть захвачены в Пассанте. Черная пешка должна быть в ряду 5 (снизу вверх, начиная с нуля), и рядом с ней должна быть белая пешка. Одна ситуация с максимальным количеством возможных захватов выглядит следующим образом:
BWBBWBBW
Если бы в ряду 5 было 6 черных пешек, у белых было бы только 2 квадрата, и они могли бы угрожать только 4 черным пешкам, поэтому невозможно одновременно иметь более 5 черных пешек, очевидно находящихся под угрозой со стороны Эн Пассанта. Таким образом, нам нужно число от 1 до 5, указывающее, какая из (до 5) пешек в ряду 5, у которой рядом есть враждебная (в данном случае белая) пешка, была продвинута на 2 клетки в последний ход ( или ноль, если пешка отсутствует) в этой ситуации был перемещен таким образом на последнем повороте.)
E) Из 30 занимаемых площадей (не считая королей), что они содержат?
Есть 10 возможностей, каждая из которых представлена десятичным числом.
Наименее значимый бит представляет цвет.
Следовательно, четные числа - белые, нечетные - черные.
Белый черный
Пешка 0/1 (или Ладья, которой разрешен замок)
Рыцарь 2/3
Епископ 4/5
Ладья 6/7
Королева 8/9
* Ладья, которой разрешено блокировать (и, следовательно, никогда не перемещалась из первого или последнего ряда), представлена 0 или 1 вместо 6 или 7. Ее нельзя спутать с пешкой, поскольку пешки не могут быть найдены на первой или последний ряд.
Это дает десятичное число до 30 цифр, которое мы можем умножить на 6 и затем добавить код для En passant. Полученное число поместится в 103 бита, которые при добавлении к 75, упомянутым выше, составят 103 + 75 = 178 бит . На самом деле, если мы просто умножим на 10 вместо 6, это не будет иметь никакого значения для количества используемых битов, и декодирование будет проще.
Это всего на 2 бита больше, чем 22 байта. Однако мы можем уменьшить его до 174 бит, как описано ниже.
Если ни одна фигура не была захвачена, то пешка не может быть повышена .
Доказательство состоит в следующем. Представьте, что белые одержимы продвижением своей пешки в (например) столбце E с самого начала игры. Против этой пешки находится черная пешка. Поэтому для продвижения этой пешки должно произойти одно из следующих действий:
1) Черная пешка захвачена.
2) Черная пешка захватывает другую фигуру и, следовательно, уходит с дороги.
3) белая пешка захватывает пешку на соседнем столбце, таком как столбец D.
4) белая пешка проходит (или проходит мимо) черную пешку в соседнем столбце, а затем захватывает фигуру в том же соседнем столбце, заставляя белую пешку менять столбец.
Случай 4 является наиболее интересным, потому что не только белая пешка, которая началась в столбце E, теперь имеет четкий путь к продвижению. Черная пешка на столбце, который остается на столбце E, также может продвигаться. Поэтому один захват может расчистить путь для продвижения одной пешки каждого цвета.
В любом случае, тот факт, что никакая пешка не может продвигаться до тех пор, пока фигура не будет захвачена, означает, что нам не нужно хранить 30-ю фигуру. Мы можем решить это путем исключения (или вычитания, потому что полный набор кодов фигур в начале игры всегда складывается в одну и ту же сумму = 80). Одним из незначительных моментов является то, что мы должны убедиться, что квадраты, где лежат ладьи стоять в начале игры среди первых отсканированных (потому что, если бы они были последними, мы не знали бы, может ли ладья заблокировать или нет.) Это легко сделать, отсканировав строку 0, а затем строки с 7 по 1: Для r = От 8 до 1 строки сканирования [r mod 8].
Итак, матрица битов в (B) скажет нам, сколько штук есть (кроме королей). Если есть целые 30, игнорируйте последний кусочек при кодировании, декодер отработает то, что было. Теперь у нас есть до 29-значное десятичное число, которое мы умножаем на 6 и добавляем в код En Passant. Результирующее число просто сжимается в 99 бит, что дает в итоге 99 + 75 = 174 бита.
В качестве примера Вот фактическая позиция. Белые только что сделали свой первый ход (продвинутая королевская пешка), и настала очередь черных.
A) Положение королей (восьмеричное / черное в белом, 12 бит ): 03 73 = 000011 111011
Б) Какие квадраты заняты? Начните с нулевого ряда (нижний ряд), затем всех остальных рядов сверху вниз, пропуская королей:
C) ход черных: бит поворота = 1
D) En Passant. Рядом с черной пешкой рядом нет белой пешки, поэтому нет пешки, которую можно взять пассивно (даже если эта пешка опередила последний ход), поэтому D = 0.Если вместо того, чтобы рассматривать только пешек, у которых есть враждебная пешка, мы рассмотрим все пешки, у которых с обеих сторон нет дружественных фигур, то D будет равно 1, поскольку в этой ситуации есть одна такая пешка, и эта пешка действительно была сдвинута в последнюю очередь.
E) Опять же, сначала нижний ряд, затем все остальные ряды сверху вниз, пропуская королей, и с четырьмя необжитыми ладьями, именуемыми 0 или 1 (числа, обычно зарезервированные для пешек).
30-ю цифру (в скобках) можно отбросить.
Хотя здесь это не очень очевидно, пешка, которую выдвинули белые, на самом деле находится на одном конце списка пешек, потому что мы сканируем строку за строкой.
Наши данные теперь выглядят так: 29 кодов для содержимого квадратов плюс код En Passant:
Лучше всего сканировать справа налево при декодировании и слева направо (в обратном порядке) при кодировании. Это означает, что при меньшем количестве фигур у нас будет меньшее число при сохранении максимальной согласованности (т.е. мы хотим, чтобы пустое пространство / нули были ведущими, а не конечными, чтобы разрешить сжатие редко занятых досок.) Когда у нас только 2 короля на плате у нас будет 75 битов, упомянутых выше, плюс 3 бита для хранения пассивных данных = 78 бит в лучшем случае. Каждая дополнительная часть имеет длину чуть менее 3,5 бит (2 части могут быть сохранены в 7 битах, потому что 100 <128.)
Существует практическая проблема в том, что 99-битное целое число слишком велико, чтобы поместиться в 64-битную целочисленную переменную, что означает, что многие языки программирования не обеспечивают ее поддержку (вы не можете просто преобразовать строковое представление из 29-30 цифр). число в целое число.) В качестве простого способа кодирования для 22 байтов мы можем разбить число из 30 цифр (коды 29 частей + код en passant) на два числа из 15 цифр, каждое из которых будет умещаться в 50 битах каждое (всего 100 битов) плюс 75, упомянутых выше, составляет 175 бит в худшем случае.)
Для максимального сжатия, как указывалось выше, 29 десятичных цифр плюс код En Passant (6 возможных значений) будут примерно соответствовать 99 битам (всего 174 бит), но без поддержки языка для целых чисел этого размера это сложный для программирования. Может быть проще отделить 29 цветовых битов и работать с кусочными кодами (5 возможностей) и En passant code (6 возможностей) отдельно от цветов (70 битов, почти вписывается в 64-битную переменную).
источник
Вот полное решение, на самом деле худший случай 181 бит
Основное внимание здесь уделяется простой программе, которую вы можете легко понять
Ввод FEN, здесь позиция открытия, в ней шесть полей (5 и 6 игнорируются):
Первое поле (размещение элемента) анализируется
Производить:
Поле первое: закодировать местоположение королей (12 битов):
Поле два: кодировать фрагменты (до 5 бит на фрагмент):
Поле три: активный цвет (1 бит)
Поле четвертое: наличие рокировки (4 бита)
Поле пять: en passant (ноль или 3 бита)
Наивный худший случай 200 бит
QRRBBNN QQQQQQQQ
- 75 битqrrbbnn qqqqqqqq
- 75 битНа самом деле худший случай
Каждый игрок не может продвигать все пешки, не захватив другие фигуры . Вот энтропийный эффект захвата фигуры:
PpR
(3 + 3 + 5 = 11 бит) =>Qq_
(5 + 5 + 1 = 11 бит)PPpp
(3 + 3 + 3 + 3 = 12 бит) =>QQq_
(5 + 5 + 5 + 1 = 16 бит)Так что на самом деле наихудший случай:
QRRBBNN QQQQQQQQ
- 75 битqrrbbnn qqqq
- 55 битНаихудший случай - продвигать все фигуры, а не оставлять пешку для en passant.
ВСЕГО АКТУАЛЬНОГО ХОРОШЕГО ДЕЛА С ПОКАЗАННЫМ КОДОМ 12 + 75 + 55 + 34 + 1 + 4 = 181 бит
FIQ показывает два улучшения этой простой схемы, но их сложнее кодировать:
Единственный оставшийся код, не показанный в этом ответе (для краткости): разбивка входного FEN в полях (
split /\s/
) и присвоение переменной.источник
PPpp
=>QQq_
Всего данных нужно 33 байта
(Спасибо кому-то в комментариях, я понял, что это не работает для продвижения пешки. Обновлю, когда смогу решить)
для первого байта мы используем пять битов:
следующие 32 байта используются для представления каждой шахматной фигуры в предопределенном порядке
противном случае обозначают, был ли он захвачен. 0 = не захвачено
(если оно может быть проходным, то оно определенно не захвачено)
Некоторый C-код для представления этой идеи (которая на самом деле не работает)
источник
256242 битВот базовый алгоритм сжатия, который, вероятно, можно улучшить, поскольку он не исключает некоторые недопустимые позиции из представленных.
Доска начинается с 5 бит информации заголовка, как показано ниже:
Затем строка из 12 битов, представляющая позиции королей.
Затем огромное 64-значное число в базе 11, которое затем умножается на 9, чтобы добавить еще одну цифру в конце, представляющую состояние en-passant. Каждая цифра в основании 11 представляет квадрат на доске со следующими возможными значениями:
И цифры в базе 9:
11 64 × 9 составляет около 2 224,57 , что требует 225 бит для кодирования. Плюс 17 битов заголовка вверху, всего 242 бита.
Спасибо Угорену за улучшения.
источник
13^64 * 9
239,99, сохраняя 11 бит. Экономьте больше, кодируя позиции короля отдельно.? биты
(≥ 217 наихудших случаев, 17 лучших случаев, 179 для начальной платы)
Описание кодировки
Дополнительные метаданные состоят из чьего хода (один бит) и рокировки (четыре бита, т. Е. Могут ли белые замки на стороне королей, на стороне королев и аналогично для черных).
Для самой позиции платы мы кодируем ее как набор активных фигур. Ну, на самом деле, мы обязательно перечисляем фрагменты в определенном порядке по причинам, которые я объясню чуть позже. Для каждого куска мы сохраняем его цвет (один бит), его вид (три бита, чтобы охватить 6 видов, плюс один дополнительный вид для «пешки, которую может взять en passant»), а также ее позицию.
Вот интересная часть: чтобы закодировать положение фигуры, вместо того, чтобы сохранять ее как координату, мы сохраняем ее относительное расстояние от последней фигуры, когда перечисляем фигуры в порядке слева направо, сверху вниз (т.е. A8 , B8, ..., G1, H1). Кроме того, мы сохраняем расстояние как число переменной длины, используя
1
для обозначения того, что этот кусок находится рядом с предыдущим,0xx
для пропуска 1-3 частей,000xxx
для пропуска 4-10 частей,000000xxxx
для 11-25,0000000000xxxxx
для 26-56 и наконец000000000000000xxx
за 57-62.Примеры
Я сделал суть некоторых позиций , кодируемых с этим кодированием, и аннотированный один для начальной позиции с некоторыми комментариями.
Я не знаю, как анализировать размер битов в худшем случае, но, следуя примерам, приведенным в сущности, я считаю, что алгоритм должен быть, по крайней мере, несколько эффективным.
Реализация декодера
Ниже приведен быстрый и грязный декодер для этого кодирования (принимая в качестве входных данных двоичные данные, закодированные в тексте, как в приведенном выше аннотированном примере, и пропуская вещи, которые не равны «0» или «1»). Производит юникодную шахматную доску на стандартный вывод.
источник
Макс .: 184 бита, Мин: 75 бит
Я был вдохновлен кодированием Хаффмана @ AdamSpeight для кусочков, чтобы попытаться создать свою собственную схему. Я сомневаюсь, что это победит, но у него есть расчетные пределы.
Эта схема рассматривает шахматные фигуры так, как будто существует 11 различных типов фигур. Я приблизительно следовал алгоритму кодирования Хаффмана, чтобы сгруппировать эти классы по их частотам и реальным типам для генерации следующих кодировок:
Коду каждой фигуры могут предшествовать два бита, чтобы показать, к какой команде она принадлежит (
10
для белых,11
для черных).0
может быть использован для кодирования пустых мест. Эти идеи позволяют нам строить кодирование квадрата за квадратом для всей платы, используя любую процедуру, которую мы хотим. Я приму порядок итерацийa1, b1, c1, ... f8, g8, h8
. Это означает, что просто перечисление этих кодов, как показано выше, кодирует всю информацию, кроме чьей очереди. Очень простой шахматный движок может использовать «классы» для пешек, грачей и королей, чтобы определить, законны ли рокировка и пассив. Кроме того, эта схема легко справляется с пешечными промоушенами. Если игрок выдвигает пешку для ладьи, то можно использовать коды короля или стороны ферзя, если выбран вариант «перемещен».За исключением патологических позиций, которые, я не думаю, могли бы когда-либо произойти, наихудший сценарий для этой кодировки - когда все фигуры все еще находятся на доске, а предыдущий игрок сдвинул пешку вперед на два пробела. В качестве примера, плата ниже кодирует
1. e4
:Это означает, что кодирование в наихудшем случае имеет 184 бита: 1 для обозначения игрока, 32 для пустых мест, 45 для неперемещенных пешек, 6 для пешки с двумя прыжками в пространстве, 24 для коней, 24 для слонов, 28 для грачей, 12 для королев и 12 для королей.
По мере перемещения и захвата фрагментов размер кодировки будет уменьшаться. В лучшем случае на доске представлены только два короля: 1 бит для обозначения игрока + 62 бита для указания пустых квадратов + 12 бит для указания королей дает минимальную длину 75 битов.
Я вернусь и отредактирую этот ответ с помощью некоторого кода, который демонстрирует эту кодировку в действии позже сегодня или завтра. На данный момент мне любопытно посмотреть, что другие люди думают об этой кодировке.
источник
11001
означаетB'S MOVE
W CAN KSC
W CANT QSC
B CANT KSC
B CAN QSC
). Это 4 бита вместо 5 бит на сторону в вашей кодировке, или 3 бита на сторону, если вы уберете боковой маркер на ладьях. (KSC
= Замок со стороны короля.QSC
= Замок со стороны королевы)184 бита = 23 байта в худшем случае, и не слишком сложный:
A. Какие квадраты занимают: 64 бита = 8 байтов B. Какие цвета для <= 32 занятых квадратов: 32 бита = 4 байта И теперь, используя только <= 30 квадратов, занятых не королями: B. используйте PNBRQ, закодированный в radix 5, для 5 ^ 30 возможностей; и 32 * 31 * 2 * 4 * 4 * 9 для позиций короля, цвета ходов, белых и черных прав на рокировку, квадрат прохода (из 8 вариантов плюс ни одного, девятый); это число 5 ^ 30 * 32 * 31 * 2 * 4 * 4 * 9 = 266075134277343750000000000 = 2 ^ 87,782 вписывается в 88 битов в общей сложности 64 + 32 + 88 = 184 бит для всего кодирования.
Это можно уменьшить, например, 32 * 31 * 2 * 4 * 4 * 9 = 285696, можно уменьшить до 2 * (32 * 31 + 31 * 3 + 31 * 3 + 3 * 3) * 6 = 14244, используя факт не более 6 в пассивных кандидатах-жертвах (включая ни одного), и кодирование прав на замок и позиции короля внутри одного и того же набора с использованием прав на захват фактов имеет значение, только когда король находится на исходном поле. Это экономит 4 бита.
У меня есть основания полагать, что невозможно достичь 18 байтов, то есть общее количество легальных шахматных позиций превышает 2 ^ 144.
Ваша 160-битная схема очень изобретательна, но я думаю, что ее нужно представить как программы кодирования / декодирования, прежде чем я буду полностью уверен в этом.
источник
171 бит в худшем случае:
Я объединил пару идей, а также некоторые свои мысли.
Мы собираемся начать с 64-битной платы. Каждый бит представляет собой занятое место на доске. Они заполняют ряды. Итак, начало выглядит так:
1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111
Теперь каждый кусок будет представлен 4 битами. 1-й бит: цвет (
0=white, 1=black
) 2-й-4-й биты: один из 8 типов.В конце мы включим немного обозначение поворота.
0=white, 1=black
,4 бит * 32 штуки = 128 бит, и у меня уже есть 64 + 1 от терна и доски. Это дает в общей сложности 128 + 64 + 1 = 193, которые я даже не начал с en passant или рокировкой. Хорошо за мой предел ни с чем - даже не поворачивается. Вот где начинаются трюки.
Хорошо, вы видите эти типы выше? Епископ0 и Епископ1? Pawn0 и pawn1? Эти типы обозначены так, потому что они говорят нам немного вставить после этой части. Таким образом, Bishop0 означает, что после него будет 0, т. Е. Следующий кусок будет белым. Епископ1 говорит нам, что следующий кусок чёрный, а пешка0 и пешка1 работают одинаково. (Если этот кусок является последним из перечисленных, то он говорит нам о следующем ходу).
Мой худший случай включает в себя все фигуры на доске, поэтому с 16 пешками и 4 слонами это экономит мне 20 битов. Я до 173.
Хорошо. Для другого бита в моем худшем случае - когда есть 16 из кодированных цветов, мы прекращаем кодировать цвет - как мы знаем, это продвигается вперед. Мой худший случай теперь включает в себя белую фигуру, которая добирается до дальнего угла без захвата. Там я сохраняю только один бит. 172.
Теперь я собираюсь изменить порядок, в котором я называю кусочки. Мы будем называть их вдоль столбцов, начинающихся с внешней стороны. Доска, названная в начале, останется прежней, но когда я размещу на ней фигуры, я начинаю с белых справа внизу и поднимаюсь по этому столбцу. Затем я прыгаю в черный нижний правый угол и поднимаюсь по этой колонке. Я прыгаю в нижнюю правую неизвестную ячейку белого и так далее - это означает, что мой худший случай - снова начало Моя причина связана с моим пассивным трюком, следующими двумя потерянными битами и рокировкой.
Теперь, чтобы пешка была продвинута (как уже обсуждалось), часть должна быть захвачена. Таким образом, когда мы знаем, что есть 32 части, нам нужно только обозначить 31 из них. Последний кусок уникально идентифицирован. Как оказалось, для меня это экономит только 2 бита - потому что мой последний кусок мог бы быть пешкой / слоном (который обычно стоит мне 3 бита, потому что я сохраняю один на следующем фрагменте), цвет которого уже определен и был только 2 бита Я до 170 бит.
Когда пешки получают повышение, они просто меняют свой тип. Для каждой фигуры, которая уходит с доски, я избавляю себя (минимум) от 3 битов, а два пешечных промоушена стоят мне 2 бита, поэтому я медленно (медленно) сокращаюсь в акциях.
Рокировка.Чтобы произошла рокировка, ни король, ни соответствующая ладья не могли сдвинуться. Таким образом, когда ладья способна рокировать, она и король окажутся на своих местах. Таким образом, грачи, способные к рокировке, будут перечислены в том же месте, что и короли этого цвета. Поскольку это недопустимо (два короля или три короля одного цвета на доске) и может происходить только в трех возможных настройках для каждого цвета (слева, справа, оба ладьи указаны как короли) - дешифрирование совершенно возможно. Итак, без битов мы закодировали рокировку.
En Passant Здесь мы также будем использовать нелегальные позиции. Только одна пешка может быть в опасности за один раз. Должно быть в четвертом ряду. Уязвимая пешка будет «перевернута» обратно к своему домашнему ряду и переключена с тем, что там есть. Поскольку эта пешка находится в своем собственном первом ряду - недопустимая позиция, ситуация будет очевидна для декодера - она поменяет позиции и пометит пешку как уязвимую для прохода.
Нам нужно было разобраться с заказом, потому что последний кусок должен быть «однозначно идентифицирован». В стандартном порядке мы не смогли бы определить, может ли ладья в заднем углу замкнуться - это неизвестно. Когда мы работаем извне, мы гарантируем, что где бы «ладья» не была «внесена в список», будь то в ее собственном углу или в середине доски, поскольку она была переключена с помощью уязвимой пешки en passant, будет фигура, перечисленная после это - так нам говорят тип ладьи. Мы знаем, что после него будет фигура, потому что пешка должна быть уязвимой, так как внутри нее должна быть пешка (что будет решительно закодировано позже в соответствии с инструкциями выше).
Да, и чтобы убедиться в том, что в худшем случае все фигуры на доске имеют меньше чем 32 фигуры, мы можем использовать 64-битную доску для определения поворота, а также занятых позиций, используя 0 для представления фигур, когда их белые поворот и 1, когда это черные.
Так что мы получили пассив и рокировку бесплатно. Мы взяли последний кусок бесплатно, хотя для того, чтобы сделать эту игру более приятной с правилами en passant и правилами рокировки, потребовалось некоторое время. Мы отбросили 20 бит на стандартные части. Я полагаю, что наихудший случай здесь заключается в том, что белая пешка среднего размера продвигается вперед и черная фигура находится между ней и ее королевой, пока все фигуры находятся на доске. Быстрая двойная проверка: первая фигура захвачена - назовите ее пешкой, 3 бита с доски в пешке, 3 бита на доске в форме последнего фишка, один бит в маркере хода исчезает. Продвиньте две пешки 2 бита обратно на доску. Ах, блин, я в 171.
РЕДАКТИРОВАТЬ Я добавил код для (работающий?) Декодер - в R - ниже. В качестве входных данных используются векторы с логическими значениями - (извините - я не способен хорошо кодировать что-либо, что позволило бы мне на самом деле использовать биты) Я также включил начальную позицию.
Этот код строит 4 функции. Тот, который выполняет некоторое базовое разделение фигур и структуры доски, а также выясняет тип фигур и любые «неявные» части. Следующая функция заполняет структуру доски этими фигурами в несколько странном (и отличается от моего исходного алгоритма) порядке [объяснено в комментариях к коду]. Следующая функция берет заполненную доску и обнаруживает любые недопустимые позиции - затем она исправляет их и переименовывает пешек, которые уязвимы для en passant "x pawn-e" и любых ладей, которые могут замкнуть "x rook-c". Последняя функция - это обертка, которая выполняет эти функции по порядку и выдает на выходе как текущую доску, так и ход.
Я также включил кодирование начальной позиции (хотя, чтобы увидеть его, вам нужно будет вызвать
c(startboard,newpieces)
код, который вызывает функцию-оболочку для этой позиции.источник
229/226 бит
Это оказывается не очень успешным, но может спасти других людей, идущих по тому же пути.
Простая версия:
1
немного за чью очередь4
биты для четырех возможностей рокировки3
биты для en passant возможностей. Это имеет большую глубину, что я сначала понял. Пасс должен быть сделан пешкой, которая движется с того же ранга (ряда), что и захваченная пешка. Анализ случаев показывает, что, как только мы узнаем, сколько пешек цвета, который последний раз перешел, продвинулись ровно на два квадрата, будет не более 6 в пассивных случаях (включая случай, когда нет пешки, уязвимой для en passant ). В худшем случае это 5 пешек (потенциально все уязвимы: например,PpPPpPPp
имеет пять уязвимыхP
). При 6 пешках максимум 2 вражеские пешки одного ранга, каждая из которых может угрожать максимум 2 пешкам в пассиве . Поэтому нам нужныceil(lg 6) = 3
биты здесь.Тогда доска. На плате 64 квадрата, поэтому индекс квадрата может быть закодирован в 6 битах. Мы перечисляем людей по рангу, чередуя цвета, начиная с короля.
6
биты: позиция белого короля. (Гарантированно быть на доске).6
биты: позиция черного короля. (Гарантированное присутствие на доске. В худшем случае, когда белый король находится в углу, у него может быть 60 возможных мест; в лучшем случае, если у белых нет края, есть 55).6
биты: позиция белой королевы. Если белой королевы нет, повторить позицию белого короля в качестве сигнала.1
бит, за которым следуют 6 битов для позиции.0
Бит.0
бит.Это стоит определенных
12
битов для королей и2*7*5-1 = 69
битов для других людей. В худшем случае, когда на доске присутствуют все 32 человека, это стоит7
битов для каждого человека, кроме королей, в общей сложности12 + 7*30 - 1 = 221 bits
. Итак, с начальными8
битами для глобального состояния у нас есть 229 бит .Продвинутая версия:
Используя арифметическое кодирование, мы можем оперировать,
lg num_possibilities
а неceil(lg num_possibilities)
просто братьceil
в конце.1
немного за чью очередь4
биты для четырех возможностей рокировкиlg 6
биты для en passant возможностей.6
биты для белого короляlg 60
биты (наихудший случай) для черного короляlg 63
биты (потому что я не хочу усложнять это до уровня проверки чеков) для белой королевы, используя позицию белого короля, если ее нет1
немного сопровождаемойlg 62
,lg 61
и т.д. биты для ее положения.0
Бит.lg 63
битов (или меньше, если бы были белые королевы) для черной королевы.У n-го человека, который на самом деле присутствует, есть
66-n
возможные ценности. Если для цвета отсутствует тип, мы потратили66-#men so far
биты на его запись (плюс один бит для разделителя). Крайние случаи:5+lg 6
на глобальное состояние,6+lg 60
на королей,29
на биты разделителя иSUM_{n=32}^{63} lg n
биты на позициях. Общая сумма:ceil(225.82)
биты. Неутешительный.5+lg 6
на глобальное состояние,6+lg 60
на королей,29
на биты-разделители,8*lg 63
говоря, что других фигур нет, иSUM_{n=48}^{63} lg n
на позиции пешек. Итого:ceil(188.94)
биты. Лучше - сохранив второго ладью, рыцаря и слона для каждой стороны, мы немного оторвались.Таким образом, наихудший случай, по-видимому, составляет 226 битов , что приводит к незначительной экономии 3.
Мы определенно можем добиться большего успеха в среднем случае, кодируя пешки перед фигурами, поскольку они ограничены 48 квадратами, а не целыми 64. Однако, в худшем случае, когда все люди на доске и все пешки были повышены, я думаю, в итоге это будет стоить на 2 бита больше, потому что нам понадобится флаг «без пешек» вместо того, чтобы подсчитывать людей.
источник
Это тема обсуждения в шахматных кругах.
Вот одно очень простое доказательство с 164 битами https://groups.google.com/forum/#!topic/rec.games.chess.computer/vmvI0ePH2kI 155 показано здесь http://homepages.cwi.nl/~tromp /chess/chess.html
За упрощенную стратегию:
источник
Мин: 0 бит
Максимум:
1734243 бита (4,3354,401 бит / доска амортизируется)Ожидаемое:
351177 бит (4,3764,430 бит / плата амортизируется)Так как я могу определить вход и выход, как мне хочется, я решил продолжить с кодирования истории игры до этого момента. Одним из преимуществ является то, что дополнительная информация о том, кто в свою очередь, энсант, и у кого есть возможность блокировки, может быть получена, а не закодирована.
Попытка 1:
Наивно я думал, что могу кодировать каждый ход в 12 битах, 4 триплета в форме (начало x, начало y, конец x, конец y), где каждый равен 3 битам.
Мы бы заняли исходную позицию и отодвинули фигуры оттуда первыми белыми. Доска расположена так, что (0, 0) - левый нижний угол белых.
Например, игра:
Будет закодировано как:
Это приводит к кодированию битов длиной 12 м, где m - количество выполненных ходов.
С одной стороны, это может стать очень большим, с другой стороны, вы можете считать каждый ход своей игрой, поэтому каждое кодирование действительно кодирует m «шахматных досок». Если вы амортизируете это, вы получите, что каждая «шахматная доска» составляет 12 бит. Но я чувствую, что это немного обманывает ...
Попытка 2:
Я понял, что каждый ход в предыдущей попытке кодирует много незаконных ходов. Поэтому я решил кодировать только легальные ходы. Перечислим возможные ходы следующим образом: нумеруем каждый квадрат так, чтобы (0, 0) → 0, (1, 0) → 1, (x, y) → x + 8 y. Перебирайте плитки и проверяйте, есть ли фигура и может ли она двигаться. Если это так, добавьте позиции, к которым можно перейти в список. Выберите индекс списка, который вы хотите сделать. Добавьте это число к итоговой сумме ходов, взвешенной на 1, плюс количество возможных ходов.
Пример, как указано выше: из начальной позиции первая фигура, которая может двигаться, это конь на клетке 1, она может переместиться на клетку 16 или 18, поэтому добавьте ее в список
[(1,16),(1,18)]
. Далее идет рыцарь на квадрате 6, добавьте его ходы. В целом мы получаем:[(1,16),(1,18),(6,21),(6,23),(8,16),(8,24),(9,17),(9,25),(10,18),(10,26),(11,19),(11,27),(12,20),(12,28),(13,21),(13,29),(14,22),(14,30),(15,23),(15,31)]
Поскольку нам нужен ход (12, 28), мы закодируем его как 13 в базе 20, поскольку существует 20 возможных ходов.
Итак, теперь мы получаем номер игры g 0 = 13
Далее мы делаем то же самое для черных, за исключением того, что нумеруем плитки в обратном порядке (чтобы было проще, не требуется), чтобы получить список ходов:
[(1,16),(1,18),(6,21),(6,23),(8,16),(8,24),(9,17),(9,25),(10,18),(10,26),(11,19),(11,27),(12,20),(12,28),(13,21),(13,29),(14,22),(14,30),(15,23),(15,31)]
Поскольку нам нужен ход (11, 27), мы закодируем его как 11 в базе 20, поскольку существует 20 возможных ходов.
Итак, теперь мы получаем номер игры g 1 = (11 ⋅ 20) + 13 = 233
Далее мы получаем следующий список ходов для белых:
[(1,16),(1,18),(3,12),(3,21),(3,30),(3,39),(4,12),(5,12),(5,19),(5,26),(5,33),(5,40),(6,12),(6,21),(6,23),(8,16),(8,24),(9,17),(9,25),(10,18),(10,26),(11,19),(11,27)(13,21),(13,29),(14,22),(14,30),(15,23),(15,31)]
Поскольку нам нужен ход (6, 21), мы закодируем его как 13 в базе 29, поскольку существует 29 возможных ходов.
Итак, теперь мы получаем номер игры g 2 = ((13 ⋅ 20) + 11) 20 + 13 = 5433
Далее мы получаем следующий список ходов для черных:
[(1,11),(1,16),(1,18),(2,11),(2,20),(2,29),(2,38),(2,47),(3,11),(4,11),(4,18),(4,25),(4,32),(6,21),(6,23),(8,16),(8,24),(9,17),(9,25),(10,18),(10,26),(12,20),(12,28),(13,21),(13,29),(14,22),(14,30),(15,23),(15,31)]
Так как мы хотим переместить $ (10, 18) $ (10, 18)
Итак, теперь мы получаем номер игры g 3 = (((19 ⋅ 29 + 13) 20) + 11) 20 + 13 = 225833
И продолжайте этот процесс для всех оставшихся ходов. Вы можете думать о g как о функции g (x, y, z) = x y + z. Таким образом, g 0 = g (1, 1, 13), g 1 = g (g (1, 1, 11), 20, 13), g 2 = g (g (g (1, 1, 13), 20, 11), 20, 13), g 3 = g (g (g (g (1, 1, 19), 29, 13), 20, 11), 20, 13)
Чтобы декодировать игровой номер g 0 , мы начинаем с начальной позиции и перечисляем все возможные ходы. Затем мы вычисляем g 1 = g 0 // l , m 0 = g 0 % l , где l - количество возможных ходов, «//» - оператор целочисленного деления, а «%» - оператор модуля. Следует считать, что g 0 = g 1 + m 0 . Далее мы делаем ход m 0 и повторяем.
Из приведенного выше примера, если g 0 = 225833, то g 1 = 225833 // 20 = 11291 и m 0 = 225833% 20 = 13. Далее g 2 = 11291 // 20 = 564 и m 1 = 11291% 20 = 11. Тогда g 3 = 11291 // 20 = 564 и m 2 = 11291% 20 = 11. Поэтому g 4 = 564 // 29 = 19 and_m_ 3 = 564% 29 = 13. Наконец, g 5 = 19 // 29 = 0 и m 4 = 19% 29 = 19.
Так сколько битов используется для кодирования игры таким образом?
Для простоты, скажем, всегда есть 20 ходов за ход, а для наихудшего сценария мы всегда выбираем самый большой, 19. Полученное нами число составляет 19 m 20 м.
+ 19 ⋅ 20 м-1 + 19 ⋅ 20 м-2 + ⋯ + 19 ⋅ 20 + 19 = 20 м + 1 - 1, где _m - количество ходов. Для кодирования 20 m + 1 - 1 нам нужно около log 2 (20 m + 1 ) битов, что составляет около (m + 1) * log 2 (20) = 4,3219 * (m + 1)
В среднем m = 80 (40 ходов на игрока), поэтому для кодирования потребуется 351 бит. Если бы мы записывали много игр, нам понадобилась бы универсальная кодировка, поскольку мы не знаем, сколько бит понадобится каждому числу
В худшем случае, когда m = 400 (200 ходов на игрока), для кодирования потребуется 1734 бита.
Обратите внимание, что позиция, которую мы хотим закодировать, должна быть дана нам по кратчайшему пути, чтобы пройти по правилам. Например, для теоретической игры здесь не требуется m = 11741 для кодирования конечной позиции. Вместо этого мы запускаем поиск в ширину, чтобы найти кратчайший путь к этой позиции и вместо этого кодировать его. Я не знаю, насколько нам нужно было бы перечислить все шахматные позиции, но я подозреваю, что 400 - это завышенная оценка.
Быстрый расчет:
В игре 12 уникальных фигур или квадрат может быть пустым, поэтому их расположение на шахматной доске - 13 64 . Это огромная переоценка, поскольку включает в себя много недопустимых позиций. Когда мы м движется в игре мы создали около 20 м позиций. Поэтому мы ищем, когда 20 м = 13 64 . Зарегистрируйте обе стороны, чтобы получить m = 64 * log 20 (13) = 54,797. Это показывает, что мы должны быть в состоянии добраться до любой позиции за 55 ходов.
Теперь, когда я рассчитал наихудший случай для m = 55, а не m = 400, я отредактирую свои результаты. Для кодирования позиции, где m = 55 требуется 243 бита. Я также хочу сказать, что средний регистр составляет около m = 40, для кодирования которого требуется 177 бит.
Если мы используем аргумент амортизации из предыдущего, мы кодируем 400 «шахматных досок» в 1734 битах, так что мы получаем, что каждая «шахматная доска» занимает 4,335 бит в худшем случае.
Обратите внимание, что g = 0 обозначает действительную игру, ту, в которой фигура на самом нижнем квадрате перемещается на самый нижний квадрат, который она может.
Дополнительные замечания:
Если вы хотите сослаться на определенную позицию в игре, вам может понадобиться закодировать индекс. Это может быть добавлено либо вручную, например, объединить указатель к игре, либо добавить дополнительный «конец» хода в качестве последнего возможного хода каждого хода. Теперь это может учитывать пропущенных игроков или 2 подряд для обозначения игроков, согласившихся на ничью. Это необходимо только в том случае, если игра не заканчивалась матом или патом в зависимости от позиции, в данном случае это подразумевается. В этом случае он увеличивает количество необходимых битов в среднем до 356, а в худшем - 1762.
источник