Mín: 0 bits
Máx: 1734 243 bits (4,335 4,401 bits / placa amortizados)
Esperado: 351 177 bits (4,376 4.430 bits / placa amortizados)
Como eu posso determinar a entrada e a saída, no entanto, eu quero que eu decidi continuar com a codificação do histórico do jogo até este ponto. Uma vantagem é que as informações adicionais sobre quem é a vez, são passivas e quem tem a capacidade de localizar onde podem ser derivadas e não codificadas.
Tentativa 1:
Ingenuamente, pensei que poderia codificar cada movimento em 12 bits, 4 trigêmeos da forma (início x, início y, final x, final y), onde cada um possui 3 bits.
Assumiríamos a posição inicial e moveríamos as peças a partir daí, com o branco indo primeiro. O quadro é organizado de forma que (0, 0) seja o canto inferior esquerdo do branco.
Por exemplo, o jogo:
e4 e5
Nf3 f6
Nxe5 fxe5
... ...
Seria codificado como:
100001 100010 100110 100100
110000 101010 101110 101101
101010 100100 101101 100100
...
Isso leva a uma codificação de 12 m bits em que m é o número de movimentos feitos
Por um lado, isso pode ficar muito grande; por outro, você pode considerar cada jogada como sendo seu próprio jogo, de modo que cada codificação realmente codifique m "tabuleiros de xadrez". Se você amortizou isso, obtém que cada "tabuleiro de xadrez" é de 12 bits. Mas acho que isso é um pouco trapaceiro ...
Tentativa 2:
Percebi que cada movimento na tentativa anterior codifica muitos movimentos ilegais. Então, decidi codificar apenas movimentos legais. Enumeramos os movimentos possíveis da seguinte forma, numere cada quadrado de modo que (0, 0) → 0, (1, 0) → 1, (x, y) → x + 8 y. Itere através dos ladrilhos e verifique se há uma peça e se ela pode se mover. Nesse caso, adicione as posições que podem ser encontradas em uma lista. Escolha o índice da lista que é a jogada que você deseja fazer. Adicione esse número ao total de movimentos em execução, ponderado por 1, mais o número de movimentos possíveis.
Exemplo como acima: A partir da posição inicial, a primeira peça que pode ser movida é o cavaleiro no quadrado 1, pode ser movida para o quadrado 16 ou 18, portanto, adicione-as à lista [(1,16),(1,18)]
. Em seguida é o cavaleiro no quadrado 6, adicione seus movimentos. No geral, temos:
[(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)]
Como queremos a jogada (12, 28), a codificamos como 13 na base 20, pois existem 20 jogadas possíveis.
Então agora temos o número do jogo g 0
= 13
Em seguida, fazemos o mesmo para o preto, exceto que numeramos os blocos ao contrário (para facilitar, não é necessário) para obter a lista de movimentos:
[(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)]
Como queremos a jogada (11, 27), a codificamos como 11 na base 20, pois há 20 jogadas possíveis.
Então agora temos o número do jogo g 1
= (11 ⋅ 20) + 13 = 233
A seguir, temos a seguinte lista de movimentos para o branco:
[(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)]
Como queremos a jogada (6, 21), nós a codificamos como 13 na base 29, pois existem 29 possíveis.
Então agora temos o número do jogo g 2
= ((13 ⋅ 20) + 11) 20 + 13 = 5433
A seguir, temos a seguinte lista de movimentos para preto:
[(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)]
Como queremos a mudança $ (10, 18) $ (10, 18)
Então agora temos o número do jogo g 3
= (((19 ⋅ 29 + 13) 20) + 11) 20 + 13 = 225833
E continue esse processo para todos os movimentos restantes. Você pode pensar em g como a função g (x, y, z) = x y + z. Assim, 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)
Para decodificar um número de jogo g 0 , começamos na posição inicial e enumeramos todos os movimentos possíveis. Em seguida, calculamos g 1 = g 0 // l , m 0 = g 0 % l , onde l é o número de movimentos possíveis, '//' é o operador de divisão inteira e '%' é o operador de módulo. Deveria sustentar que g 0 = g 1 + m 0 . Em seguida, fazemos o movimento m 0 e repetimos.
A partir do exemplo acima, se g 0 = 225833, em seguida, g 1 = 225833 = 20 // 11291 e m 0 = 225833% 20 = 13. Próximo g 2 = 11291 // 20 = 564 e m 1 = 11291% 20 = 11. Então g 3 = 11291 // 20 = 564 e m 2 = 11291% 20 = 11. Portanto, g 4 = 564 // 29 = 19 e_m_ 3 = 564% 29 = 13. Finalmente g 5 = 19 // 29 = 0 e m 4 = 19% 29 = 19.
Então, quantos bits são usados para codificar um jogo dessa maneira?
Para simplificar, digamos que sempre haja 20 movimentos a cada turno e, no pior dos casos, sempre escolhemos o maior, 19. O número que obteremos é 19 is 20 m
+ 19 ⋅ 20 m-1
+ 19 ⋅ 20 m-2
+ ⋯ + 19 ⋅ 20 + 19 = 20 m + 1
- 1 onde _m é o número de movimentos. Para codificar 20 m + 1
- 1, precisamos do log 2
(20 m + 1
) bits que é de cerca de (m + 1) ∗ log 2
(20) = 4,3219 ∗ (m + 1)
Em média, m = 80 (40 movimentos por jogador), o que levaria 351 bits para codificar. Se estivéssemos gravando muitos jogos, precisaríamos de uma codificação universal, pois não sabemos quantos bits cada número precisará
Na pior das hipóteses, quando m = 400 (200 movimentos por jogador), isso levaria 1734 bits para codificar.
Observe que a posição que queremos codificar deve ser dada pelo caminho mais curto para chegar lá, seguindo as regras. Por exemplo, o jogo teorizado aqui não precisa de m = 11741 para codificar a posição final. Em vez disso, executamos uma pesquisa de largura em primeiro lugar para encontrar o caminho mais curto para essa posição e codificá-la. Não sei até que ponto precisaríamos ir para enumerar todas as posições do xadrez, mas suspeito que 400 seja uma superestimação.
Cálculo rápido:
Existem 12 peças únicas ou o quadrado pode estar vazio, portanto, para posicioná-las em um tabuleiro de xadrez é 13 64 . Essa é uma superestimação enorme, pois inclui muitas posições inválidas. Quando estamos m movimentos de jogo, criamos cerca de 20 m posições. Então, estamos procurando quando 20 m = 13 64 . Registre os dois lados para obter m = 64 * log 20 (13) = 54,797. Isso mostra que devemos conseguir chegar a qualquer posição em 55 movimentos.
Agora que calculei o pior caso para m = 55 e não m = 400, editarei meus resultados. Para codificar uma posição em que m = 55 leva 243 bits. Também vou dizer que o caso médio é de cerca de m = 40, o que leva 177 bits para codificar.
Se usarmos o argumento de amortização anterior, codificamos 400 "tabuleiros de xadrez" em 1734 bits, para que cada "tabuleiro de xadrez" ocupe 4,333 bits no pior dos casos.
Observe que g = 0 indica um jogo válido, aquele em que a peça no quadrado mais baixo se move para o quadrado mais baixo possível.
Notas Adicionais:
Se você quiser se referir a uma posição específica no jogo, pode ser necessário codificar o índice. Isso pode ser adicionado manualmente, por exemplo, concatenar o índice para o jogo ou adicionar um movimento "final" adicional, como o último movimento possível a cada turno. Agora, isso pode levar em conta os jogadores que concederam, ou 2 consecutivos para indicar que os jogadores concordaram com um empate. Isso só é necessário se o jogo não terminar em xeque-mate ou impasse com base na posição, neste caso, está implícito. Nesse caso, ele eleva o número de bits necessários em média para 356 e, no pior caso, 1762.