Мин: 0 бит
Максимум: 1734 243 бита (4,335 4,401 бит / доска амортизируется)
Ожидаемое: 351 177 бит (4,376 4,430 бит / плата амортизируется)
Так как я могу определить вход и выход, как мне хочется, я решил продолжить с кодирования истории игры до этого момента. Одним из преимуществ является то, что дополнительная информация о том, кто в свою очередь, энсант, и у кого есть возможность блокировки, может быть получена, а не закодирована.
Попытка 1:
Наивно я думал, что могу кодировать каждый ход в 12 битах, 4 триплета в форме (начало x, начало y, конец x, конец y), где каждый равен 3 битам.
Мы бы заняли исходную позицию и отодвинули фигуры оттуда первыми белыми. Доска расположена так, что (0, 0) - левый нижний угол белых.
Например, игра:
e4 e5
Nf3 f6
Nxe5 fxe5
... ...
Будет закодировано как:
100001 100010 100110 100100
110000 101010 101110 101101
101010 100100 101101 100100
...
Это приводит к кодированию битов длиной 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.