Min: 0 bit
Max: 1734 243 bit (4.335 4.401 bit / scheda ammortizzata)
Previsto: 351 177 bit (4.376 4.430 bit / scheda ammortizzata)
Dal momento che posso determinare l'input e l'output che desidero, ho deciso di continuare con la codifica della storia del gioco fino a questo punto. Un vantaggio è che l'informazione aggiuntiva di chi è il turno è, en-passant, e chi ha la capacità di fortificare dove può essere derivato e non codificato.
Tentativo 1:
Ingenuamente ho pensato di poter codificare ogni mossa in 12 bit, 4 terzine del modulo (inizio x, inizio y, fine x, fine y) dove ognuno è 3 bit.
Assumiamo la posizione di partenza e spostiamo i pezzi da lì con il bianco che va per primo. Il tabellone è organizzato in modo tale che (0, 0) sia l'angolo in basso a sinistra del bianco.
Ad esempio il gioco:
e4 e5
Nf3 f6
Nxe5 fxe5
... ...
Sarebbe codificato come:
100001 100010 100110 100100
110000 101010 101110 101101
101010 100100 101101 100100
...
Ciò porta a una codifica di 12 m bit in cui m è il numero di mosse effettuate
Da un lato questo potrebbe diventare davvero grande, dall'altro puoi considerare ogni mossa come il suo gioco, quindi ogni codifica codifica davvero m "scacchiere". Se lo hai ammortizzato, ottieni che ogni "scacchiera" è di 12 bit. Ma penso che questo sia un po 'barare ...
Tentativo 2:
Mi sono reso conto che ogni mossa nel tentativo precedente codifica molte mosse illegali. Quindi ho deciso di codificare solo le mosse legali. Enumeriamo le possibili mosse come segue, numerando ogni quadrato in modo tale che (0, 0) → 0, (1, 0) → 1, (x, y) → x + 8 y. Scorrere le tessere e controllare se c'è un pezzo e se può muoversi. In tal caso aggiungi le posizioni in cui può andare a un elenco. Scegli l'indice dell'elenco che è la mossa che vuoi fare. Aggiungi quel numero al totale corrente di mosse ponderato per 1 più il numero di mosse possibili.
Esempio come sopra: dalla posizione di partenza il primo pezzo che può spostarsi è il cavaliere nel quadrato 1, può spostarsi nel quadrato 16 o 18, quindi aggiungi quelli alla lista [(1,16),(1,18)]
. Il prossimo è il cavaliere sul quadrato 6, aggiungi le sue mosse. Complessivamente otteniamo:
[(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)]
Poiché vogliamo la mossa (12, 28), la codifichiamo come 13 nella base 20 poiché ci sono 20 mosse possibili.
Quindi ora otteniamo il numero di gioco g 0
= 13
Quindi facciamo lo stesso per il nero, tranne per il fatto che numeriamo le tessere al contrario (per rendere più semplice, non necessario) ottenere l'elenco delle mosse:
[(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)]
Poiché vogliamo la mossa (11, 27), la codifichiamo come 11 nella base 20 poiché ci sono 20 mosse possibili.
Quindi ora otteniamo il numero di gioco g 1
= (11 ⋅ 20) + 13 = 233
Successivamente otteniamo il seguente elenco di mosse per il bianco:
[(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)]
Poiché vogliamo la mossa (6, 21), la codifichiamo come 13 nella base 29 poiché ci sono 29 mosse possibili.
Quindi ora otteniamo il numero di gioco g 2
= ((13 ⋅ 20) + 11) 20 + 13 = 5433
Quindi otteniamo il seguente elenco di mosse per il nero:
[(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)]
Dal momento che vogliamo la mossa $ (10, 18) $ (10, 18)
Quindi ora otteniamo il numero di gioco g 3
= ((((19 ⋅ 29 + 13) 20) + 11) 20 + 13 = 225833
E continua questo processo per tutte le mosse rimanenti. Puoi pensare a g come alla funzione g (x, y, z) = x y + z. Quindi 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)
Per decodificare un numero di gioco g 0 , partiamo dalla posizione iniziale ed enumeriamo tutte le mosse possibili. Quindi calcoliamo g 1 = g 0 // l , m 0 = g 0 % l , dove l è il numero di mosse possibili, '//' è l'operatore di divisione intera e '%' è l'operatore del modulo. Dovrebbe contenere quel g 0 = g 1 + m 0 . Quindi eseguiamo lo spostamento m 0 e ripetiamo.
Dall'esempio sopra se g 0 = 225833 quindi g 1 = 225833 // 20 = 11291 e m 0 = 225833% 20 = 13. Avanti g 2 = 11291 // 20 = 564 e m 1 = 11291% 20 = 11. Quindi g 3 = 11291 // 20 = 564 e m 2 = 11291% 20 = 11. Pertanto g 4 = 564 // 29 = 19 e_m_ 3 = 564% 29 = 13. Infine g 5 = 19 // 29 = 0 e m 4 = 19% 29 = 19.
Quindi, quanti bit vengono utilizzati per codificare un gioco in questo modo?
Per semplicità, supponiamo che ci siano sempre 20 mosse per turno e per lo scenario peggiore scegliamo sempre la più grande, 19. Il numero che otterremo è 19 ⋅ 20 m
+ 19 ⋅ 20 m-1
+ 19 ⋅ 20 m-2
+ ⋯ + 19 ⋅ 20 + 19 = 20 m + 1
- 1 dove _m è il numero di mosse. Per codificare 20 m + 1
- 1 sono necessari circa i
bit del log 2
(20 m + 1 ) che sono circa (m + 1) ∗ log 2
(20) = 4.3219 ∗ (m + 1)
In media m = 80 (40 mosse per giocatore), quindi occorrerebbero 351 bit per codificare. Se stessimo registrando molti giochi avremmo bisogno di una codifica universale poiché non sappiamo quanti bit saranno necessari per ogni numero
Peggior caso quando m = 400 (200 mosse per giocatore), quindi occorrerebbero 1734 bit per codificare.
Nota che la posizione che vogliamo codificare ci deve essere data tramite il percorso più breve per arrivarci seguendo le regole. Ad esempio, il gioco teorizzato qui non ha bisogno di m = 11741 per codificare la posizione finale. Invece eseguiamo una ricerca Breadth-First per trovare il percorso più breve verso quella posizione e codificarlo invece. Non so quanto dovremmo approfondire per enumerare tutte le posizioni degli scacchi, ma sospetto che 400 sia sopravvalutato.
Calcolo rapido:
Ci sono 12 pezzi unici o il quadrato può essere vuoto, quindi posizionarli su una scacchiera è 13 64 . Questa è una sovrastima enorme poiché include molte posizioni non valide. Quando siamo m ci muoviamo nel gioco abbiamo creato circa 20 m di posizioni. Quindi stiamo cercando quando 20 m = 13 64 . Registra entrambi i lati per ottenere il registro m = 64 * 20 (13) = 54.797. Ciò dimostra che dovremmo essere in grado di raggiungere qualsiasi posizione in 55 mosse.
Ora che ho calcolato il caso peggiore per essere m = 55 non m = 400, modificherò i miei risultati. Per codificare una posizione in cui m = 55 richiede 243 bit. Sto anche per dire che il caso medio è di circa m = 40 che richiede 177 bit per codificare.
Se utilizziamo l'argomento di ammortamento di prima, stiamo codificando 400 "scacchiere" in 1734 bit, in modo che ogni "scacchiera" occupi 4.335 bit nel peggiore dei casi.
Nota che g = 0 indica un gioco valido, quello in cui il pezzo sul quadrato più basso si sposta sul quadrato più basso che può.
Note aggiuntive:
Se vuoi fare riferimento a una posizione specifica nel gioco, potresti dover codificare l'indice. Questo può essere aggiunto manualmente, ad es. Concatenare l'indice al gioco o aggiungere una mossa "fine" aggiuntiva come ultima mossa possibile in ogni turno. Questo ora può rendere conto dei giocatori che hanno concesso, o 2 di fila per indicare che i giocatori hanno accettato un pareggio. Ciò è necessario solo se il gioco non è terminato in uno scacco matto o in una situazione di stallo in base alla posizione, in questo caso è implicito. In questo caso porta il numero di bit necessari in media a 356 e nel peggiore dei casi 1762.