Kleinste Schachbrettkompression

39

Schreiben Sie einen Algorithmus oder ein Programm, das ein Schachbrett codieren und decodieren kann. Das Ziel ist es, die kleinste Darstellung eines Schachbretts zu erstellen, die verwendet werden kann (einmal dekodiert), um alle Bewegungsmöglichkeiten für einen Spieler in diesem Zug zu bestimmen.

Die Kodierung muss zeigen können:

  • Wem gehört es?
  • Ob der Spieler auf jeder Seite ziehen kann.
  • Ob der Spieler einen Passanten ausführen kann und wenn ja, welche seiner Bauern?
  • Positionen aller Stücke.

Wichtiger Hinweis zur Rochade: Wenn Weiß seinen König in einer Runde bewegt und ihn in der nächsten zurückzieht, muss klar sein, dass er danach nicht mehr auf beiden Seiten burgieren kann. Gleiches würde passieren, wenn sie ihren linken oder rechten Turm bewegen würden. Obwohl sich das Brett optisch im selben Zustand wie vor zwei Runden befindet, hat sich der Spielzustand geändert. Mehr Infos hier: http://en.wikipedia.org/wiki/Chess#Castling

Wichtiger Hinweis zu En-Passant: Dies ist auch ein zugempfindlicher Zug. Lesen Sie die Regeln für weitere Informationen. http://en.wikipedia.org/wiki/Chess#En_passant

Bestimmen Sie die Eingabe und Ausgabe nach Bedarf. Wichtige Requisiten für alle, die es am besten komprimieren können!

Ihre Punktzahl ist das Worst-Case-Szenario - die maximal mögliche Größe in Bits. Stellen Sie sicher, dass Sie zeigen, wie Sie diese Zahl berechnet haben und was Sie berücksichtigt haben. Schieße auf den kleinsten Worst-Case!

Seltzer
quelle
Was meinst du mit "bitweise"?
Peter Taylor
Ist dieser kleinste Code oder am meisten komprimiert? Am meisten komprimiert ist interessanter.
Justin
Entschuldigung für die Unklarheit. Bitweise in dem Sinne, dass Sie es nur komprimieren können, wenn Sie damit beginnen, es als Bits darzustellen, was eine bitweise Operation erfordert. Schlechte Verwendung meinerseits. Auch meistkomprimierter, nicht kleinster Code.
Seltzer
2
@GeekWithALife Ja, es ist möglich, 18 Damen gleichzeitig auf dem Brett zu haben. Folgen Sie diesem Link und klicken Sie auf die Wiedergabeschaltfläche, um ein Beispiel zu sehen.
Squeamish Ossifrage
1
@AJMansfield, das könnte für Boards mit ungefähr 28 Männern nützlich sein, aber ich berechne, dass 117 Bits für Boards mit allen 32 Männern ausreichend sind, was ungefähr 50 Bits weniger als das Ziel ist. Die Schwierigkeit ist, dass eine Beförderung, sobald Sie unter 32 Mann sind, einem Spieler mehr Bischöfe geben kann.
Peter Taylor

Antworten:

27

Min: 12 Bit
Max:
Durchschn .:

Hatte und dachte letzte Nacht, dass ich es möglicherweise noch kleiner machen könnte.

x   Colour to play next (0 -> Black, 1-> White)
1   Only King left?

00000 Position of White King (0 -> A1 ... 63 -> H8)
00000 Position of Black King

01 00000 11111  WK:A1, BK:H2 (Black to play)
11 00000 11111  WK:A1, BK:H2 (White to play)

Das Ergebnis ist eine beeindruckende Größe von 12 Bit !

Was ist also mit K + 1 anderer Art von Stück?

x
 0
   0
     000  +Pawn
     001  +Rook   
     010  +Knight
     011  +Bishop
     100  +Queen

Es gibt 2 mögliche Anordnung des Teilbaums.

   /\      /\
  +  K    K  +

Beide ergeben für alle Teile die gleichen Bitgrößen. Damit es keinen Unterschied macht, welchen wir verwenden, werde ich den ersten auswählen.

x
 0
  0
   000
      1011001110000000000000000000000000000000000000000000000000000000000000
(+ 000) En-Passant (if >= 2 pawn & pawn in en-passant positions)
(+ 00 ) Castlings  (if >= 1 rook)
Min: 75 bit
Max: 109 bits

Also auf König +2 andere Stückarten

x
 0
  1
   PRBNQ
   00011  +N +Q
   00101  +B +Q
   00110  +B +N
   01001  +R +Q
   01010  +R +N
   01100  +R +B
   10001  +P +Q
   10010  +P +N
   10100  +P +B
   11000  +P +R

Es gibt 5 mögliche Unterbäume (ich werde 1 und 2 verwenden, um anzugeben, welche der Stücke.)

   /\          /\       /\         /\          /\
  /  \        /  \     /  \       /  \        /  \
 K   /\      /\   2   /\   \     1   /\      /\   \
    1  2    K  1     K  2   1       K  2    1  2   K

Daher benötigen wir 3 Bits, um den zu verwendenden Teilbaum zu codieren.

x
 0
  1
   PRBNQ
         000  Sub Tree used

Min:= 11 = Header 
       6 = 2 * 3
       4 = 1 * 4
       4 = 1 * 4
      60 = 60    Empty
      --
      85 bits

Max:=  11 = Header
        4 =  2 * 4 Kings
       48 = 16 * 3 Pawns
       12 =  4 * 3 Rook
       42 = 42 * 1 Empty
        3 =  1 * 3 En-Passant
        2 =  1 * 2 Castlings
      ---
      122 bits

Mache noch die Analyse für mehr Stücke

+3 Sonstiges

x
 0
  1
   PRBNQ
         0000  Sub Tree used (of 14 possible)

+4 Sonstiges

x
 0
  1
   PRBNQ
         000000  Sub Tree used (of 42 possible)

+5 Sonstiges

x
 0
  1
   PRBNQ
         0000000  Sub Tree used (of 132 possible)
 (+000)
 (+00)

Max: 208?


Ist es möglich, alle diese Unterbäume in 9 Bit zu kodieren?

Wenn wir alle möglichen Teilbäume aufsummieren, erhalten wir 392 mögliche Teilbäume.

 1  0
 2  2
 3  5
 4  14
 5  42
 6  132
    ---
    392  <= 2^9

Freq ID verwenden

Seitdem gibt es 164603 Einzelstückfrequenzen .

Log2( 164603) = 17.3286110452
             ~ 18 bits

0
 0000 0000 0000 0000 00  Freq ID

(+000) (+00) Rochade

Max: = 204 Bits


rev 3

Min: 82 Max: 199 Durchschn .: 160

Schließlich machte ich mich an die Analyse, um die maximale Bitgröße zu finden. Mit optimaler Huffman-Codierung für jede der einzigartigen Stückfrequenzen .

               0   Player
              00  Castling
               0  En-Passant Possible
            ?000  En-Passant column (include if En-Passant Possible = 1
  0000 0000 0000  Tree Encoding ID
[Board Encoding]  Between 66 .. 180 bits 

Beachten Sie, dass dies die schlechteste mögliche Größe ist, die die Spalte En-Passant verwendet, wenn die Anzahl der Bauern größer als eins ist. Unabhängig von den Bauernfarben und -positionen können einige Bretter 3 Bit kleiner sein.

Auch gibt es nur 144 verschiedene Größen (Worst Case) für die Größe der Platine.


75 - 216 Bit (v2) v1 Die Mindestgröße beträgt 98 Bit (12,25 Byte), nur die beiden Könige auf der Karte.

Die maximale Größe beträgt nur 216 Bit (27 Byte). Im unwahrscheinlichen: -

  9 x Queens
  1 x King
  2 x Rooks
  2 x Knights
  2 x Bishops
on each side.

Im Durchschnitt beträgt die Größe ca. 157 Bit (19.625 Byte).

Stücke

Zum Kodieren der Karte verwende ich ein binäres Baumkodierungsschema. Ein leeres Quadrat ist das häufigste von allen, bei denen zwischen 32 und 62 Erscheinungen auftreten. Als nächstes kommen die Bauern, dann Türme, Ritter, Bischöfe und am seltensten die Königin und der König.

0 - left node
1 - righ node

     /\
    e  \    e:= Empty Square
      B/\W  B:= Black ; W:= White
      /  \
     /    \
    /      \
   /\      /\
  p  \    p  \  p:= Pawn
     /\      /\
    /  \    /  \
   /\  /\  /\  /\
  r  b n \ r b n \  r:= Rook; b:= Bishop; n:= Knight
         /\      /\ 
        q  k    q  k  q:= Queen ; k:= King

Die Startkarte kann in nur 166 Bit (20,75 Byte) codiert werden

  A     B     C      D      E     F     G     H
-----+-----+-----+------+------+-----+-----+------+
10100 10101 10110 101110 101111 10110 10101 10100 | 8 
  100   100   100    100    100   100   100   100 | 7
    0     0     0      0      0     0     0     0 | 6
    0     0     0      0      0     0     0     0 | 5
    0     0     0      0      0     0     0     0 | 4
    0     0     0      0      0     0     0     0 | 3
  110   110   110    110    110   110   110   110 | 2
11100 11101 11110 111110 111111 11110 11101 11100 | 1

Um anzuzeigen, wer sich bewegt, ist nur ein einziges Bit erforderlich

0-> Black , 1-> White

Die Rochade kann in 4 Bits codiert werden.

 B  W
LR LR
00 00

Also habe ich 171 Bits (21.375 Bytes) verwendet

En-Passe kann in nur 16 Bits (2 Bytes) codiert werden

Das sind also insgesamt 187 Bit (23.375 Bytes).

Layout

  bits    Encodes
 0 -  15  En-Passe
16 -  19  Castling
      20  Move 
21 -  23  Unused
24 -> ..  Board

Noch keinen Code geschrieben.

Beachten Sie, dass 3 der Bits nicht verwendet werden. Die maximale Länge beträgt also 213 Bit .


Mögliche Verbesserungen

1) Reduziert den Headerblock von 24 auf 8 Bits (mit @ Peter Taylor Vorschlag)

0 - 2 En-Passant
    3 Move
4 - 7 Castling
8 ... Board Pieces 

2) Header variabler Länge

Ein kleiner fester 4-Bit-Header

0 0 0 0
| | | |
| | | +-> En-Passant Block Present?
| | | 
| | +---> Pawns on board?
| |
| +-----> Castling still possible?
|                
+-------> Who's move? 0-Black 
                      1-White

Nächster Block mit zusätzlichen Bits (Wenn noch Rochade möglich ist)

00 00
|| ||
|| |+-> White Castle Right
|| +--> White Castle Left
||
|+----> Black Castle Right
+-----> Black Castle Left

Nächster Block zusätzlicher Bits (falls Bauern vorhanden sind)

000--> En-Passant column Position

Also habe ich jetzt einen Header mit variabler Länge von 4 - 11 Bit


3) Verwenden Sie ein anderes Kodierungsschema, je nachdem, welche Teile noch auf der Tafel liegen.

Durch Ändern der Baumkodierung abhängig davon, welche Teile auf dem Brett sind und in welcher Häufigkeit.

Eine mögliche Kodierung für einen Endspielstatus (Keine Bauern)

        /\            
       e /\           
  Black /  \ White
       /    \
      /      \
     /        \       
    /\        /\
   /  \      /  \     
  /   /\    /   /\
 /\  / /\  /\  / /\   
r b n q k  r b n q k

Das sind ungefähr 4 Bits pro Stück.

Welche Art von Stücken sind auf der Tafel vorhanden?

RBNQK Permutation
11111 (11111)

Die Permutation ist 0-5 Bit mit variabler Länge. Wenn nur noch eine Stückart übrig ist, darf diese nicht berücksichtigt werden.

Welche Permutation dieser Teile für den Baum? Dies ist die Fakultät der Anzahl der Teile im obigen Beispiel. Es sind 5 Teile, also 120 mögliche Permutationen, die codiert werden können.

 #    !  bit 
 6  720  10  (If pawn included)
 5  120   6
 4   24   5
 3    6   3
 2    2   1  Don't include as of equal size.
 1    1   0  Don't include as its not needed.

Denken Sie daran, dass es für die leeren Quadrate und Farben zusätzliche Bits gibt.


Beispiele

Lassen Sie uns ein Beispiel von nur noch QK geben

RBNKQ
00011

  /\
 s  \
    /\
  B/  \W
  /\  /\
q  k q  k

101 100  0 x 60 110 111 ==> 60 + (2 x 6) = 60 + 12 = 72 bits for the board

0000 00011 Header ==> 9 bits

81 Bits insgesamt


Lassen Sie uns ein Beispiel geben, dass nur noch Könige übrig sind

 RBNQK
 00001 

  /\
 s  k
   / \
  B   W

 10 0 0 0 0 0 0 0   K... ....
  0 0 0 0 0 0 0 0   .... ....
  0 0 0 0 0 0 0 0   .... ....
  0 0 0 0 0 0 0 0   .... ....
  0 0 0 0 0 0 0 0   .... ....
  0 0 0 0 0 0 0 0   .... ....
  0 0 0 0 0 0 0 0   .... ....
  0 0 0 0 0 0 0 11  .... ...k

Alles zusammen

 header  4   0 0 0 0
 pieces  5   0 0 0 0 1
 perm    0   - - - - - -
  board 66   10 0 0 0 0 0 0 0
              0 0 0 0 0 0 0 0
              0 0 0 0 0 0 0 0
              0 0 0 0 0 0 0 0
              0 0 0 0 0 0 0 0
              0 0 0 0 0 0 0 0
              0 0 0 0 0 0 0 0
              0 0 0 0 0 0 0 11

Also berechne ich die kleinste Kodierung für Board bei 75Bits (9 Bit, 3 Bit)

Noch zu berechnen, wie sich dieses Kodierungsschema auf die maximale Größe auswirkt.


Verbesserung 4

Reduzieren Sie die Anzahl der Bits für die Rochade auf nur 2 Bits. Nur Rochade für den Spieler, der an der Reihe ist.

 0 Castling possible (from header block)
 LR 
 00

Wenn Sie darüber nachdenken, ist es vielleicht besser, nur die 2 Bits in den Header-Block aufzunehmen.

Adam Speight
quelle
Sie brauchen keine 16 Bits für en passant. Höchstens ein Bauer hat sich in der letzten Runde bewegt, so dass vier Bits ausreichen (zB 1111für "no en passant possible" oder ansonsten die Spalte als Binärzahl).
Peter Taylor
Warum bekommen Bauern eine bessere Position in einem Baum? Im Normalfall sind sie am häufigsten, aber im Extremfall kann R / B / N 10-mal auftreten.
Ugoren
@PeterTaylor, eigentlich reichen 3 Bit für en passant. Wenn Sie nur Spalten mit einem schwarzen Bauern 5. Ranges zählen (unter der Annahme eines weißen Zuges), wird 8 ungültig.
Ugoren
1
Beachten Sie, dass Ihr Worst-Case tatsächlich nicht möglich ist. Eine Promotion ist ohne Captures nicht möglich (mindestens ein Capture pro zwei Promotions ist erforderlich).
Ugoren
2
Beachten Sie, dass Sie zum Codieren von 64 Positionen (für weißen oder schwarzen König) 6 Bits benötigen (2 ** 6 = 64).
LambruscoAcido
17

192 Bits (schlechtester Fall)

Hier ist ein sehr einfaches Speicherschema, das willkürliche Bauernaktionen bewältigen sollte und niemals mehr als 64 + 4 × 32 = 192 Bits erfordert:

  • Die ersten 64 Bits speichern ein Bitboard , das angibt , wo sich die Teile befinden (aber nicht, was sie sind). Das heißt, wir speichern ein Bit für jedes Feld des Schachbretts (beginnend mit Feld a1, dann b1, c1 usw. bis zu Feld h8), sodass ein freies Feld durch 0 und ein belegtes Feld durch 1 dargestellt wird.

  • Als nächstes speichern wir für jedes der Quadrate, die auf der Bitboard als belegt markiert sind, ein 4-Bit-Nibble, das das Stück auf diesem Quadrat codiert. Das erste der vier Bits kodiert die Farbe des Stücks (0 = Weiß, 1 = Schwarz), während die restlichen drei Bits den Typ des Stücks kodieren:

    +-----+-----+-----+-----+
    |Black|   Piece Type    |
    +-----+-----+-----+-----+
       4     3     2     1    Bits
    

    Stückart

    0 = (normaler) Bauer
    1 = (normaler) Turm
    2 = Ritter
    3 = Läufer
    4 = Dame
    5 = König (des nächsten Spielers)
    6 = König (des anderen Spielers)

    Beachten Sie die beiden Kodierungen für den König, mit denen festgelegt wird, welcher Spieler an der Reihe ist, um sich zu bewegen. (Da es immer zwei Könige auf der Tafel gibt, die vier Kombinationen der Codes 5 und 6 zulassen, könnten wir hier ziemlich einfach ein zweites Informationsbit codieren.)

    Black Type Description
    +----+----+--------------------------------+
    |  0 | 5  | White King; White to move next |
    +----+----+--------------------------------+
    |  0 | 6  | White King                     |
    +----+----+--------------------------------+
    |  1 | 5  | Black King; Black to move next |
    +----+----+--------------------------------+
    |  1 | 6  | Black King                     |
    +----+----+--------------------------------+
    

    Um die zusätzlichen Informationen zu kodieren, die für die En-Passant- und Castling-Regeln erforderlich sind, führen wir einen zusätzlichen Teiletyp ein, der abhängig von der Zeile, in der er angezeigt wird, entweder einen Bauern oder einen Turm kennzeichnet:

    7 (in den Reihen 1 und 8) = ein Turm, der sich nie bewegt hat und dessen König sich ebenfalls nie bewegt hat und der daher für die Rochade
    7 (in den Reihen 4 und 5) geeignet ist = ein Bauer, der gerade zwei Felder vorgerückt ist, und kann daher en passant erfasst werden

Alles zusammenfassen:

     Hex Description
    +---+---------------------------------------------+
    | 0 | White Pawn (normal)                         |
    | 1 | White Rook (has moved)                      |
    | 2 | White Knight                                |
    | 3 | White Bishop                                |
    | 4 | White Queen                                 |
    | 5 | White King; White to move next              |
    | 6 | White King                                  |
    | 7 | White Rook (pre castle) / Pawn (en Passant) |
    | 8 | Black Pawn (normal)                         |
    | 9 | Black Rook (has moved)                      |
    | A | Black Knight                                |
    | B | Black Bishop                                |
    | C | Black Queen                                 |
    | D | Black King; Black to move next              |
    | E | Black King                                  |
    | F | Black Rook (pre castle) / Pawn (en Passant) |
    +---+---------------------------------------------+

Die Gesamtzahl der zum Codieren des Platinenzustands erforderlichen Bits beträgt daher 64 + 4 × Anzahl der auf der Platine befindlichen Teile. Da sich nie mehr als 32 Teile auf dem Board befinden dürfen, beträgt die maximale Länge dieser Codierung 192 Bit.

Unter Verwendung der oben beschriebenen Codierung würde der Anfangszustand der Karte beispielsweise wie folgt codiert (Leerzeichen zur besseren Lesbarkeit eingefügt):

1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111
0111 0010 0011 0100 0101 0011 0010 0111 0000 0000 0000 0000 0000 0000 0000 0000
1000 1000 1000 1000 1000 1000 1000 1000 1111 1010 1011 1100 1110 1011 1010 1111

oder hexadezimal:

FFFF 0000 0000 FFFF 7234 5327 0000 0000 8888 8888 FABC EBAF
Ilmari Karonen
quelle
2
"Bauer, der gerade zwei Felder vorgerückt hat" und "Turm, der sich nie bewegt hat" könnten sich denselben Statusplatz teilen, da sie sich in Abhängigkeit von der Reihe, in der sie sich befinden, gegenseitig ausschließen. Der zusätzliche freie Zustand könnte verwendet werden, um "König der Farbe, dessen Zug es ist" zu codieren; Sie sollten in der Lage sein, das baumelnde Bit auf diese Weise loszuwerden.
FireFly
Sie können auch ein Bit speichern, indem Sie nur 63 Bit für das Bitboard speichern und das letzte Bit aus der Anzahl der codierten Männer ableiten. (Es ist mir nicht klar, ob dies betrügt oder nicht, weil es eine externe Codierung der Länge der Bitsequenz erfordert). Und wenn Sie die Zustände 6 und 7 für die Männer außer Kraft setzen, müssen Sie bis zu 6 ^ 32 codieren, was 82,7 Bit dauert; Wenn Sie auf 83 aufrunden, sparen Sie 13 Bit bei Verwendung der Zustände 6 und 7, und Sie können dieselben Informationen in nur 8 Bit codieren.
Peter Taylor
Vielen Dank, @FireFly! Ich habe Ihren Vorschlag umgesetzt. (Peter Taylors Vorschlag ist natürlich noch effizienter, aber ich habe ihn bisher nicht verwendet, weil mir die einfache binäre Codierung des aktuellen Schemas irgendwie gefällt. Sie können ihn jederzeit als separaten Eintrag einreichen ...)
Ilmari Karonen
Okay - das ist ein bisschen kompliziert. Aber hör mir zu. Wenn Sie nur einen 1-Bit-Schlag auf einen Blinker ausführen , können Sie König durch Zug durch ein Stück ersetzen, das ich Bauer1 nenne. Ändern Sie pawn zu pawn0. Immer wenn es einen (nicht passant verwundbaren) Bauern gibt, erhalten Sie auch eine Information über die nächste Figur (entweder eine 0 für den Bauern 0 oder eine 1 für den Bauern 1). Da es 16 Bauern gibt, erhält man 16 Bits weniger 1 für den Blinker. Immer wenn es einen Bauern gibt, der für den Passanten anfällig ist, muss man ein Bit nachträglich hinzufügen. Da dies jedoch sofort geschehen muss, betragen Ihre minimalen Gewinne 14 Bit.
user5957401
Ähnliches könnte man auch mit Bischöfen machen. Angenommen, Sie haben einen Bischof, der sich nicht in einer speziellen Zone befindet (die 10 Punkte in den Ecken und die mittlere Reihe auf der Seite), ist als besonders markiert. Weil Sie seinen Standort kennen - Sie wissen, dass es ein Bischof ist. Jetzt haben Sie zwei Bischöfe und können jedem von ihnen beim nächsten Stück eine 0 oder 1 geben. Dies ergibt weitere 4 Bits - aber im schlimmsten Fall gibt es Bischöfe in allen Sonderzonen und keine Verstärkung.
user5957401
14

160 Bits Worst Case

Nachdem ich meine vorherige Antwort mit 22 Bytes gepostet hatte, begann ich mich zu fragen, ob wir auf 21 Bytes kommen könnten. Als ich jedoch Peter Taylors unglaubliche 166 Bytes sah, dachte ich: "Moment mal, es sieht so aus, als wären fünf 32-Bit-Wörter möglich!"

Nach langem Überlegen kam ich auf folgende Idee: 159.91936391 Bytes (eine ziemlich enge Passform!) Diese Komprimierungsstufe würde ein ziemlich kompliziertes Programm erfordern, aber ich habe darüber nachgedacht, wie ich es in angemessener Zeit zum Laufen bringen kann.

Dies wird ein langer Beitrag sein. Bitte nehmen Sie Kontakt mit mir auf. Ich werde heute veröffentlichen, was ich kann, und demnächst ein paar Code-Teile hinzufügen.

So geht's:

En Passant und Rochade von illegalen Positionen (0 Bits) codiert

En Passant

Wie in anderen Antworten erwähnt, gibt es maximal 5 mögliche Felder, auf denen ein Bauer stehen kann, der für einen Passanten anfällig ist. Dies sind die Felder neben den Bauern des Spielers, der an der Reihe ist.

Um dies zu kodieren, wird der für En-Passant anfällige Bauer mit dem ausgetauscht, was sich auf einem der Quadrate in der ersten oder letzten Reihe befindet. Dies kann entweder ein Mann oder ein leeres Feld sein. Dies führt zu einer illegalen Position, da sich keine Bauern in diesen Reihen befinden können. Der Decoder muss den Bauern in die richtige Position zurückbringen und die entsprechenden Informationen extrahieren.

Damit dies die Codierung der Rochade nicht beeinträchtigt, ist es wichtig, dass die Quadrate, auf denen die Könige zu Beginn des Spiels stehen, nicht gestört werden und dass die Könige bei der En-Passant-Codierung nicht nebeneinander platziert werden. Das wäre eine illegale Königsposition. Um den zweiten dieser Punkte zu erfüllen, hat der Encoder zwei Möglichkeiten, welches Quadrat er gegen den en passant-Bauern austauscht. Erste Wahl für jeden der bis zu 5 Bauern sind A8, B8, C8, G8, H8. Zweite Wahl: A1, B1, C1, G1, H1.

Rochade

Ein König, dem es erlaubt ist zu burgieren, befindet sich per definitionem immer noch auf seinem ursprünglichen Platz. Mit dem weißen König auf seinem Anfangsfeld gibt es insgesamt 63 Felder, auf denen der schwarze König stehen kann, von denen 58 legal sind (er darf sich nicht direkt neben dem weißen König bewegen, weil er sich selbst in Schach setzen würde.) Wenn der weiße König eine Burg errichten darf, darf er entweder mit seinem linken Turm, seinem rechten Turm oder mit beiden Burgen errichten. Es gibt also 3x58 = 174 Möglichkeiten, bei denen der weiße König eine Burg errichten kann, weitere 174, bei denen der schwarze König eine Burg errichten kann, und weitere 3x3 = 9, bei denen beide eine Burg errichten können, insgesamt 357.

Es gibt 420 illegale Arrangements der beiden Könige, bei denen sie sich auf benachbarten Feldern befinden: 3x4 = 12, wenn sich der weiße König in der Ecke befindet, 5x24 = 120, wenn er sich am Rand befindet, und 8x36 = 288, wenn er sich auf einem anderen Feld befindet. Daher gibt es leicht genug illegale Positionen, um alle möglichen Rochierungsmöglichkeiten zu verschlüsseln.

Wenn mindestens ein König ein Schloss errichten darf, schlägt der Encoder die Rochierungsdaten und die Positionsdaten der Könige, die kein Schloss errichten dürfen, in einer Tabelle nach (oder verwende alternativ einen Algorithmus, den ich hier nicht spezifiziere) und erstellt einen illegalen Code Position der beiden Könige. Es würde dann die Könige mit allem austauschen, was sich auf diesen Feldern befand.

Es ist wichtig, dass dies nach dem En-Passant codiert und vor dem En-Passant decodiert wird, da es sonst zu möglichen Interferenzen kommen kann.

Vergleich

Also, bisher habe ich keine Bits benutzt! Wenn ich mir Peters Antwort ansehe, muss ich noch Folgendes codieren:

Whose turn is it?                                   1.000 bits
Which squares are occupied by men of which colour? 91.552 bits 
Subtotal                                          *92.552 bits* 
For the two colours, which men and which order?   *68.613 bits* 
GRAND TOTAL                                       161.165 bits

Dies gilt für den schlimmsten Fall von 29 Männern (siehe Peters Antwort). Im Folgenden werde ich zeigen, wie ich mich geringfügig (zumindest für den Fall von 29 Männern) in Bezug auf beide in ** markierten Punkte verbessere.

Welche Plätze sind besetzt / wer ist an der Reihe?

Die einfache Art zu kodieren, welche Quadrate belegt sind, ist mit einem 64-Bit-Raster. Dies sagt uns auch, wie viele Felder belegt sind. Es ist jedoch etwas verschwenderisch, da es nicht möglich ist, mehr als 32 Felder zu belegen. Meine Lösung besteht darin, Einsen zu verwenden, um für die belegten Felder zu codieren, wenn Weiß an der Reihe ist, und Nullen, um für belegte Felder zu codieren, wenn Schwarz an der Reihe ist. Jetzt werden alle Kombinationen verwendet und es entsteht kein Abfall.

So sparen wir ein bisschen für die Speicherung der Runde: weniger als 32 1, es ist weiß dran, mehr als 32 1, es ist schwarz dran. Der einzige zweideutige Fall ist, wenn alle Männer auf dem Brett sind und es 32 Einsen und 32 Nullen gibt. Daher wird nur für diesen Fall ein zusätzliches Bit benötigt. Da es keine Beförderungen geben kann, bis eine Eroberung stattgefunden hat, wirkt sich dieses zusätzliche Bit nicht auf den schlimmsten Fall insgesamt aus (der bei 3 erbeuteten und 29 verbleibenden Männern auftritt).

Farbe der Männer auf den Plätzen

Aus den obigen Angaben wissen wir, wie viele Männer es gibt. Der folgende Ausschnitt aus Pascals Dreieck zeigt, wie viele Möglichkeiten es für die verschiedenen Verteilungen von Schwarz und Weiß gibt. Für 3 Männer gibt es beispielsweise folgende Möglichkeiten: 3 schwarze Männer (1 Permutation) 2 schwarze, 1 weiße (3 Permutationen), 1 schwarze, 2 weiße (3 Permutationen), 3 weiße (1 Permutation). Die Summe beträgt 2 3 = 8. Im Allgemeinen gibt es für die geringere Anzahl von Männern 2 n Möglichkeiten. Jedoch sind alle schwarzen und alle weißen Möglichkeiten illegal (mindestens der König jeder Seite muss auf dem Brett sein), so dass die tatsächliche Anzahl der zulässigen Permutationen 2 n -2 beträgt (ignorieren Sie die Einsen im Pascal-Dreieck).

Bei mehr als 16 Männern besteht eine zusätzliche Einschränkung darin, dass nicht mehr als 16 Männer in jeder Farbe auf dem Brett sein dürfen. Wenn also alle 32 Männer auf dem Brett sind, müssen es jeweils 16 sein, und die Gesamtzahl der Möglichkeiten beträgt 601080390, was ziemlich viel weniger als 2 32 ist .

1   1    1    1      1     1      1       1       1        1        1         1         1         1          1          1          1 
1   2    3    4     5      6      7       8       9       10       11        12        13        14         15         16         17
1   3    6   10    15     21     28      36      45       55       66        78        91       105        120        136        153
1   4   10   20    35     56     84     120     165      220      286       364       455       560        680        816        969
1   5   15   35    70    126    210     330     495      715     1001      1365      1820      2380       3060       3876       4845
1   6   21   56   126    252    462     792    1287     2002     3003      4368      6188      8568      11628      15504      20349
1   7   28   84   210    462    924    1716    3003     5005     8008     12376     18564     27132      38760      54264      74613
1   8   36  120   330    792   1716    3432    6435    11440    19448     31824     50388     77520     116280     170544     245157
1   9   45  165   495   1287   3003    6435   12870    24310    43758     75582    125970    203490     319770     490314     735471
1  10   55  220   715   2002   5005   11440   24310    48620    92378    167960    293930    497420     817190    1307504    2042975
1  11   66  286  1001   3003   8008   19448   43758    92378   184756    352716    646646   1144066    1961256    3268760    5311735
1  12   78  364  1365   4368  12376   31824   75582   167960   352716    705432   1352078   2496144    4457400    7726160   13037895
1  13   91  455  1820   6188  18564   50388  125970   293930   646646   1352078   2704156   5200300    9657700   17383860   30421755
1  14  105  560  2380   8568  27132   77520  203490   497420  1144066   2496144   5200300  10400600   20058300   37442160   67863915
1  15  120  680  3060  11628  38760  116280  319770   817190  1961256   4457400   9657700  20058300   40116600   77558760  145422675
1  16  136  816  3876  15504  54264  170544  490314  1307504  3268760   7726160  17383860  37442160   77558760  155117520  300540195
1  17  153  969  4845  20349  74613  245157  735471  2042975  5311735  13037895  30421755  67863915  145422675  300540195  601080390

Die Anzahl der Möglichkeiten kann durch Summieren der "Zeilen" dieses Pascal-Dreieck-Extrakts ermittelt werden (womit ich die NE-SW-Diagonalen der Tabelle meine, da ich das Dreieck zur bequemen Darstellung um 45 Grad gegen den Uhrzeigersinn gedreht habe. Die Anzahl der benötigten Bits Um den Zug, die besetzten Felder und die Farbe der Männer zu codieren, ist daher wie folgt:

Bis zu 25 Männer: etwas weniger als 64+ (Anzahl der Männer)
Bei mehr als 25 Männern:

men permutations  bits required  occupied sq+turn   
    of colours                   (bits required)  total bits
26   55791790     25.7335495      64              89.7335495
27  100960110     26.58921015     64              90.58921015
28  175844430     27.3897244      64              91.3897244
29  290845350     28.115677       64              92.115677   
30  445962870     28.73234836     64              92.73234836
31  601080390     29.16298271     64              93.16298271
32  601080390     29.16298271     65              94.16298271

Für die beiden Farben, welche Männer und in welcher Reihenfolge?

Gemäß den vorherigen Antworten können keine Bauern befördert werden, bis eine Eroberung stattgefunden hat, da jeder Bauer von einem Bauern der entgegengesetzten Farbe in derselben Spalte geblockt wird. Bei Peters Antwort wurde (als obere Schranke) angenommen, dass jede Erfassung zu einer Beförderung für die zu erfassende Seite und zu zwei Beförderungen für die zu erfassende Seite führen könnte. Wir können dies jedoch in mehrere Fälle aufteilen:

  1. Schwarzer Bauer fängt weißen Bauern: Jetzt kann der erbeutende Bauer befördert werden, da er sich in einer anderen Spalte befindet. Sein Kollege in der gleichen Kolumne kann auch fördern. Der schwarze Bauer auf der ursprünglichen Spalte des weißen Bauern kann auch fördern. Dies ist der einzige Fall, der 3 Promotionen erlaubt.

  2. Schwarzer Bauer geht an weißem Bauer auf benachbarter Säule vorbei und fängt dann weißes Stück (außer Bauer) dahinter ein. Dadurch können der einfangende Bauer und der weiße Bauer, der sich in der ursprünglichen Spalte befand, befördert werden. Eine Promotion für jede Seite.

  3. Weißer Bauer wird stückweise gefangen (außer Bauer). Dies würde normalerweise eine Beförderung nur für Schwarz ermöglichen. Die einzige Ausnahme ist, wenn eine blockierte Bauernformation freigesetzt wird, die bereits durch mehrere Eroberungen verursacht wurde, bei denen Bauern auf dieselbe Säule verschoben wurden.

Grundsätzlich können wir also davon ausgehen, dass jede Erfassung eine Beförderung für beide Seiten zulässt. Für den Fall, dass der erbeutete Mann ein Bauer ist, kann eine zusätzliche Beförderung für die erbeutende Seite erfolgen.

Ich habe ein Programm geschrieben, das dem von Peter ähnlich ist. Es ist etwas gröber, hat aber einen wichtigen Zusatz: Es kann die Anzahl der möglichen Permutationen berechnen, wenn ein Spieler mit weniger als den normalen 8 Bauern beginnt. Hier sind einige vom Programm erzeugte Daten:

Max promotions   0            1            2             3             4              5 
8 PAWNS 
13 men    18725850    146911050    567991710    1373480394    2297173164     2902775304
14 men    36756720    339459120   1555313760    4501448952    9021804792    13325103792
15 men    60810750    660810150   3555401850   12144582450   28834205400    50030580600
16 men    64864800    843242400   5383778400   21810428640   61514893440    1.26476E+11
7 PAWNS                         
13 men    17760600    141003720    546949260    1321302840    2200401060     2761730400
14 men    30270240    287567280   1331890560    3852728880    7641553920    11068817760
15 men    32432400    372972600   2075673600    7209001800   17135118000    29315286000
6PAWNS                          
13 men    14054040    114594480    447026580    1069488420    1739577840     2113185360
14 men    15135120    151351200    718918200    2087805720    4073028960     5697051360                         
5 PAWNS                         
13 men     6486480     55135080    217297080     510630120     794233440      910235040

Wir können sehen, dass für einen Fall wie 8 Bauern, 15 Männer, 0 Beförderungen die Anzahl der Permutationen nur geringfügig geringer ist als für 8 Bauern, 16 Männer, 0 Beförderungen. Betrachten wir jedoch einen Fall wie 7 Bauern, 15 Männer, 0 Beförderungen (was dasselbe ist, als wäre der gefangene Mann definitiv ein Bauer), erhalten wir ungefähr die Hälfte der Anzahl von Permutationen.

Für den Fall, dass Schwarz 16 Männer und Weiß 15 Männer hat, können wir eine Schätzung der Obergrenze von 2 Beförderungen für Schwarz und einer Beförderung für Weiß in Betracht ziehen:

5383778400 x 660810150 = 3.55766E+18 possibilities

Wir können es jedoch besser machen, wenn wir wie folgt vorgehen.

A. Betrachten Sie jeweils eine Beförderung für Schwarz und Weiß, vorausgesetzt, der Mann, den Weiß verloren hat, könnte von beliebiger Art sein:

843242400 x 660810150 = 5.57223E+17 possibilities

B. Betrachten Sie die zusätzlichen Möglichkeiten für Schwarz, wenn er zwei Beförderungen hat, multipliziert mit den Möglichkeiten für Weiß, bei denen er einen Bauern verloren hat.

(5383778400-843242400) x 372972600 = 1.6935 E+18 possibilities.

Addiert man diese beiden Werte, erhält man 2.25072E + 18, was eine kleinere Zahl als 3.55766E + 18 ist. Im Folgenden sind alle Möglichkeiten für bis zu 3 Eroberungen (29 verbleibende Männer) aufgeführt.

(Promotions, Pawns lost) possibilities

BLACK 16 MEN, WHITE 15 MEN. ESTIMATE   3.55766E+18 = 2^61.62563249
(1,0)   843242400 x (1,0)  660810150 = 5.57223E+17
(2,0)  4540536000 x (1,1)  372972600 = 1.6935 E+18
                               TOTAL   2.25072E+18 = 2^60.96509144


BLACK 16 MEN, WHITE 14 MEN. ESTIMATE   9.5675 E+19 = 2^66.3747752
(2,0)  5383778400 x (2,0) 1555313760 = 8.37346E+18
(3,0) 16426650240 x (2,1) 1331890560 = 2.18785E+19
(4,0) 39704464800 x (2,2)  718918200 = 2.85443E+19
                               TOTAL   5.87962E+19 = 2^65.67235739


BLACK 16 MEN, WHITE 13 MEN. ESTIMATE   2.69447E+20 = 2^67.86856193
(3,0) 21810428640 x (3,0) 1373480394 = 2.99562E+19
(4,0) 39704464800 x (3,1) 1321302840 = 5.24616E+19
(5,0) 64960896000 x (3,2) 1069488420 = 6.94749E+19
(6,0) 69702272640 x (3,3)  510630120 = 3.55921E+19
                               TOTAL   1.87485E+20 = 2^67.34533572


BLACK 15 MEN, WHITE 15 MEN. ESTIMATE   1.47491E+20 = 2^66.99918768
(2,0)  3555401850 x (2,0) 3555401850 = 1.26409E+19
(2,1)  2075673600 x (3,0) 8589180600 = 1.78283E+19
(3,0)  8589180600 x (2,1) 2075673600 = 1.78283E+19
(3,1)  5133328200 x (3,1) 5133328200 = 2.63511E+19
                  TOTAL BOTH COLUMNS   7.46486E+19 = 2^66.01674923


BLACK 15 MEN, WHITE 14 MEN. ESTIMATE   4.51366E+20 = 2^68.61286007      
(3,0) 12144582450 x (3,0) 4501448952 = 5.46682E+19
(3,1)  7209001800 x (4,0) 4520355840 = 3.25873E+19
(4,0) 16689622950 x (3,1) 3852728880 = 6.43006E+19
(4,1)  9926116200 x (4,1) 3788825040 = 3.76083E+19
(5,0) 21196375200 x (3,2) 2087805720 = 4.42539E+19
(5,1) 12180168000 x (4,2) 1985223240 = 2.41804E+19
                  TOTAL BOTH COLUMNS   2.57599E+20 = 2^67.80368692

Für den schlimmsten Fall einer Seite mit 15 Männern und der anderen mit 14 Männern benötigen wir also 67.804 Bits.

Addiert man dies zu den 92,116 Bits, die erforderlich sind, um anzugeben, welche Quadrate und welche Farbe verwendet werden sollen, erhält man insgesamt 67,804 + 92,116 = 159,92 Bits.

Level River St
quelle
1
Vielen Dank an @Einacio für das Ändern meiner Kommas in Dezimalstellen. Ich habe viele meiner Tabellen in Excel auf einem spanischen Computer erstellt, und es war eine große Aufgabe, dies zu veröffentlichen. Deshalb musste ich das Problem später beheben. Wie gesagt, ich habe diesen Beitrag noch nicht fertiggestellt. Ich werde mein Permutationszählprogramm und einige Codefragmente zum Codieren / Decodieren hinzufügen, wenn ich Zeit habe. PS. Ich hatte keine Ahnung, dass so viele Leute dies lesen :-)
Level River St
Am Ende haben Sie es geschafft, Bytes anstelle von Bits zu nehmen. Dies ist das, was Sie gemeint haben und was zu einer gewissen Verwirrung der Leser führen könnte
masterX244
13

177-Bit-Worst-Case

Obwohl dieser Algorithmus nicht einfach ist, ergibt er einen 177-Bit-Worst-Case (184b = 23B in der Praxis) und ein 13-Bit-Best-Case-Szenario (16b = 2B), wenn nur noch 2 Könige übrig sind.

Bit     Description
  1     Turn (0=white 1=black)
  2-  7 White king position (2-4=letter, 5-7=number)
  8- 13 Black king position (8-10=letter, 11-13=number)
 14- 75 Which squares contain pieces (skipping the 2 king squares, so only 62)
        Ordered a1-h1,a2-h2,(...)
 76-105 Which color owns the square with their piece (0=white, 1=black)
        If there's LESS than 30 pieces (apart from kings), this area is
        smaller
106-end Square data

Square data has the following system:
Every square gets assigned a number which determines piece. Number is:
0 Queen
1 Rook
2 Bishop
3 Knight
4 Pawn OR allowed-castle rook depending on square
5 Pawn subject to potential enpassant

The first bits (max 13) is the potential enpassant slots from A-H, determined
from data of 1 + 14-105 for which of the squares has a piece, and which color
owns the piece and whose turn it is. For example, if turn is White (bit 1 is
0), all pieces on row 5 which is Black owned (determined from 14-105 metadata)
and has at least 1 adjacant (on the same row) square owned by White, is
explained in A-H order. A base 6 number is used which is converted to binary
for the storage. On reading, it's converted and read A-H according to the
numbers above (4 is obviously pawn in this case).
The second amount of bits takes care of the 1st and 8th row (not corners!)
in b1-g1,b8-g8. These only take up 2 bits since 4 or 5 is never needed
(pawn on 1st or 8th is invalid).
The third amount of bits takes care of the rest of the board, in the following
order: a1,h1,a2-h2,a3-h3,a4-h4,a5-h5,a6-h6,a7-h7,a8,h8 (skipping the
"enpassant" slots), in base 5 (since piece ID 0-4 are the only used) converted
to binary.

Best case: 13 bits (bit 1 for turn, bit 2-12 for kings)
Worst case: 177 bits
* 32 pieces with kings
* 5 viable enpassant pawns
* No pieces at 1st or 8th row (except if kings+rooks are at initial posions
whether or not they can castle)
In this case, the space as following:
  1   bit   turn
+ 12  bits  king positions
+ 62  bits  which squares have pieces
+ 30  bits  color of pieces
+ 13  bits  enpassant area
+ 0   bits  initial rows area
+ 59  bits  the rest of the area
= 177 bits  total

Potential optimizations but not really worth it IMO:
* Decrease average by make corners 2 bits as well if kings aren't at e1/e8
* Alter reading order to read b1-g1,b8-g8 last - decreases worst case to
  176 bits if the "which squares have pieces" area is cut off if 30 existing
  pieces has been defined already. Would actually save 8 bits on file but meh
FIQ
quelle
Sehr schön. Sie können dies noch effizienter gestalten, indem Sie die Bits 14-105 (92 Bits) durch eine Codierung ersetzen, die auf Multinomialkoeffizienten basiert. sum_{i=0}^{15} sum_{j=0}^{15} 62! / (i! j! (62-i-j)!) < 2^87.45.
Peter Taylor
Das einzige, was ich ändern würde, ist, eine etwas vereinfachte Version für den enpassant-Bereich zu erstellen. Beispiel: Wenn Sie die 30 Teile in Basis 5 codieren und es maximal 5 Enpassant-Positionen gibt, können Sie 5 ^ 31 <2 ^ 72 haben. Das gleiche, als würden Sie sie in enpassant (13) und non-enpassant (59) aufteilen, jedoch ohne die zusätzliche Komplexität.
Alin Stoian
Dies würde tatsächlich 1 zusätzliches Bit verbrauchen. Der Grund ist, dass es (im schlimmsten Fall) 5 Möglichkeiten geben kann, aber ich muss immer noch die Möglichkeit für "no enpassant" deklarieren, dh einen 6. Zustand. Das 1 zusätzliche Bit würde in diesem Fall dazu führen, dass Enpassant für möglich erklärt wird oder nicht (und mit diesem Ansatz könnte ich auch einen noch einfacheren Ansatz für die Codierung der 30 Teile verwenden, die den Enpassant-Block überspringen, und 3 Bits separat für die Enpassant-Prüfung verwenden, was der Fall wäre führen auch zu +1 Bit Nutzung). Die folgende fünfte Reihe würde 5 potenzielle Passanten ermöglichen (Weiß ist an der Reihe): BWBBWBBW
FIQ
ja, du hast Recht.
Alin Stoian
7

166 Bits

  • 1 bit: wessen an der Reihe ist es?
  • 2bits: Welche Rochade-Möglichkeiten gibt es? (Hinweis: Beim genauen Lesen der Frage müssen nur die Rochierungsoptionen für den Spieler aufgezeichnet werden, der an der Reihe ist.)
  • lg 6 ~= 2.585bits: welche en passant optionen sind offen? (Siehe meine andere Antwort)
  • lg sum_{i=1}^{16} sum_{j=1}^{16} 64! / (i! j! (64-i-j)! = lg 3629590441720924477681996172 ~= 91.552 Bits: Welche Felder sind mit Männern welcher Farbe besetzt?
  • Im schlimmsten Fall, lg 451366131803622235200 ~= 68.613um anzuzeigen, welche Männer und in welcher Reihenfolge (siehe unten)

Mit der arithmetischen Codierung (da wir bei jedem Schritt eine gleichmäßige Verteilung anwenden) können wir ceil(3 + 2.585 + 91.552 + 68.613) = 166Bits erzielen .

Die Kodierung für die Männer: Wenn wir wissen, wie viele Männer einer bestimmten Farbe es gibt, können wir leicht alle möglichen Verteilungen / Mehrfachmengen von Männern aufzählen (z. B. haben wir bei 5 Männern einen König, eine Dame, zwei Türme und einen Pawn) und dann können wir alle möglichen Permutationen jeder Distribution berücksichtigen.

Wir können es jedoch noch besser machen, wenn wir gegenseitige Abhängigkeiten berücksichtigen. Ich mache das nur auf einer sehr einfachen Ebene: Wie viele mögliche Aktionen? Ein Bauer kann nur auf drei Arten "bestanden" und befördert werden: Er fängt und bewegt sich auf diese Weise in eine andere Spalte. oder sein gegnerischer Bauer fängt und bewegt sich so in eine andere Spalte; oder sein gegnerischer Bauer wird gefangen genommen. Somit erzeugt eine Erfassung für Weiß möglicherweise zwei übergebene Spielsteine ​​für Weiß und einen für Schwarz.

Wir können eine Teiltabelle der Obergrenzen für Werbeaktionen erstellen:

(Max white promos, max black promos):

           White men
           16      15      14      13
Black men
       16  (0, 0)  (1, 2)  (2, 4)  (3, 6)
       15  (2, 1)  (3, 3)  (4, 5)  (5, 7)
       14  (4, 2)  (5, 4)  (6, 6)  (7, 8)
       13  (6, 3)  (7, 5)  (8, 7)  (8, 8)

Wir können auch die Anzahl der Permutationen berechnen, vorausgesetzt, ein Spieler hat NMänner und nicht mehr als Pbeförderte Bauern:

Num of permutations (cumulative):
    max promotions: 0              1              2              3              4              5              6              7              8
 1 men              1              1              1              1              1              1              1              1              1
 2 men             10             10             10             10             10             10             10             10             10
 3 men             72             75             75             75             75             75             75             75             75
 4 men            436            496            500            500            500            500            500            500            500
 5 men           2305           3025           3120           3125           3125           3125           3125           3125           3125
 6 men          10746          17106          18606          18744          18750          18750          18750          18750          18750
 7 men          44170          88795         106260         109179         109368         109375         109375         109375         109375
 8 men         159832         415360         575240         619200         624744         624992         625000         625000         625000
 9 men         509841        1721961        2884815        3398769        3504735        3515301        3515616        3515625        3515625
10 men        1447200        6258240       13063080       17697780       19260180       19510320       19530840       19531230       19531240
11 men        3706065       20021265       52183395       85007571      102173181      106786581      107369592      107409918      107410281
12 men        8678340       57101220      183088620      364510476      509818716      570620556      584017632      585352152      585430164
13 men       18725850      146911050      567991710     1373480394     2297173164     2902775304     3107861328     3143928216     3146014014
14 men       36756720      339459120     1555313760     4501448952     9021804792    13325103792    15664512864    16283899632    16360920576
15 men       60810750      660810150     3555401850    12144582450    28834205400    50030580600    66655789200    73588394880    74576231730
16 men       64864800      843242400     5383778400    21810428640    61514893440   126475789440   196178062080   240747386880   253686232800

Durch Kombination der beiden können wir die Anzahl der erforderlichen Bits erhalten, um beide Permutationen zu spezifizieren, wenn die Anzahl der Männer auf beiden Seiten gegeben ist:

           White men
           16      15      14      13      <13
Black men
       16  51.902  61.626  66.375  67.868  <=67.009
       15  --      67.000  68.613  67.534  <=65.243
       14  --      --      67.734  65.480  <=63.055
       13  --      --      --      63.102  <=60.676

Wenn es nicht in diesem Abschnitt der Tabelle steht, können wir davon ausgehen, dass beide Seiten bis zu 8 Beförderungen haben, und wir machen es immer noch besser als im schlimmsten Fall, der 68.613 Bits beträgt, wenn einer 14 Männer und der andere 15 Männer hat.

Beachten Sie, dass dies noch weit davon entfernt ist, eine perfekte Darstellung zu sein, da es viele, viele illegale Positionen zulässt.

Code zur Berechnung der Permutationstabelle:

import java.util.*;

public class ChessCombinatorics {
    public static void main(String[] args) {
        long[] f = new long[17];
        f[0] = 1;
        for (int i = 1; i < 17; i++) f[i] = i * f[i-1];

        // Indexed by num promotions, then total num men.
        long[][] distribs = new long[9][17];
        long[][] perms = new long[9][17];

        for (int promotedPawns = 0; promotedPawns < 9; promotedPawns++) {
            Map<Integer, Map<String, Long>> numCases = new HashMap<Integer, Map<String, Long>>();
            for (int i = 1; i < 17; i++) numCases.put(i, new HashMap<String, Long>());

            for (int extraQ = 0; extraQ <= promotedPawns; extraQ++) {
                for (int extraR = 0; extraR + extraQ <= promotedPawns; extraR++) {
                    for (int extraN = 0; extraN + extraR + extraQ <= promotedPawns; extraN++) {
                        int extraB = promotedPawns - extraN - extraR - extraQ;
                        int unpromotedPawns = 8 - promotedPawns;

                        // Promoted pawns should only count towards their new type if the existing ones are alive.
                        // Otherwise we double-count some cases.
                        int minQ, maxQ, minR, maxR, minN, maxN, minB, maxB;
                        if (extraQ == 0) {minQ = 0; maxQ = 1;} else {minQ = maxQ = 1 + extraQ;}
                        if (extraR == 0) {minR = 0; maxR = 2;} else {minR = maxR = 2 + extraR;}
                        if (extraN == 0) {minN = 0; maxN = 2;} else {minN = maxN = 2 + extraN;}
                        if (extraB == 0) {minB = 0; maxB = 2;} else {minB = maxB = 2 + extraB;}

                        for (int numQ = minQ; numQ <= maxQ; numQ++) {
                            for (int numR = minR; numR <= maxR; numR++) {
                                for (int numN = minN; numN <= maxN; numN++) {
                                    for (int numB = minB; numB <= maxB; numB++) {
                                        for (int numP = 0; numP <= unpromotedPawns; numP++) {
                                            // The number of possibilities at these values is (numK + numQ + numR + numN + numB + numP)! / (numK! numQ! numR! numN! numB! numP!)
                                            numCases.get(1+numQ+numR+numN+numB+numP).put(numQ+","+numR+","+numN+","+numB+","+numP, f[1 + numQ + numR + numN + numB + numP] / f[numQ] / f[numR] / f[numN] / f[numB] / f[numP]);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            for (int numMen = 1; numMen < 17; numMen++) {
                distribs[promotedPawns][numMen] = numCases.get(numMen).size();
                if (distribs[promotedPawns][numMen] > 0) {
                    for (Long l : numCases.get(numMen).values()) perms[promotedPawns][numMen] += l;
                }
            }
        }

        System.out.println("Num of permutations (cumulative):");
        System.out.println("    max promotions: 0              1              2              3              4              5              6              7              8");
        for (int numMen = 1; numMen < 17; numMen++) {
            System.out.print(String.format("%2d men", numMen));
            long cumul = 0;
            for (int promotedPawns = 0; promotedPawns < 9; promotedPawns++) {
                cumul += perms[promotedPawns][numMen];
                System.out.print(String.format("%15d", cumul));
            }
            System.out.println();
        }

        System.out.println("Entropy of permutations:");
        System.out.println("    max promotions: 0              1              2              3              4              5              6              7              8");
        for (int numMen = 1; numMen < 17; numMen++) {
            System.out.print(String.format("%2d men", numMen));
            long cumul = 0;
            for (int promotedPawns = 0; promotedPawns < 9; promotedPawns++) {
                cumul += perms[promotedPawns][numMen];
                System.out.print(String.format("  %6.3f", Math.log(cumul) / Math.log(2)));
            }
            System.out.println();
        }

    }
}
Peter Taylor
quelle
Wie leitet man die Positionen der Könige ab? Sie verwenden 15 Männer in Ihrer Berechnung und keine speziellen Bits für Königspositionen.
Alin Stoian
@AlinStoian, hoppla. Ich hatte <eher eine als eine <=in der Ausgabeschleife meines Programms. Vielen Dank für den Hinweis. Ich könnte immer noch die vorherige Punktzahl wiederherstellen, indem ich alle 32 Männer, die auf dem Brett sind, einer Spezialkiste unterziehe, aber das werde ich jetzt noch nicht tun.
Peter Taylor
Interessante Daten! Theoretisch schlimmster Fall mit 3 Männern gefangen genommen
Level River St
@steveverrill, was ich wirklich gerne tun würde, ist die Bauernpositionen und die Anzahl der Beförderungen in einem "Block" und dann die Stückpositionen und Werte zu kodieren. Es gibt jedoch mindestens 2 ^ 38 Bauernpositionen ohne Berücksichtigung von Beförderungen, und die effiziente Aufzählung ist mir bisher entgangen.
Peter Taylor
@petertaylor Wenn Sie nur 16 Bauern auf dem Brett haben, die auf 48 Felder beschränkt sind, haben Sie 48! / 32! / 8! / 8! = 29019905518636890 Möglichkeiten. Etwas mehr als 2 ^ 54! Von diesen sind einige illegal, Sie können nicht alle Bauern einer Farbe auf einer Seite des Brettes haben.
Level River St
5

178 Bits (174 zur Not!) Im schlimmsten Fall

Hi, ich komme gerade auf das Programmieren zurück, was ich seit dem College nicht wirklich gemacht habe. Ich habe diese Seite gesehen und fand sie interessant. Ich habe eine kleine theoretische Überprüfung durchgeführt und es scheint, dass mindestens 146 Bits für einen perfekten Algorithmus benötigt werden, wahrscheinlich einige mehr.

Auf diese Weise strukturiere ich die Daten. Das Grundkonzept liegt bei 178 Bit, aber mit einigem Durcheinander kann es auf 174 reduziert werden (das sind 21 3/4 Byte). 175 ist etwas einfacher zu programmieren, ist besser lesbar und liegt immer noch innerhalb von 22 Bytes.

A) Position beider Könige: jeweils 6 Bits für weiße und schwarze 12 BITS

B) Welche der verbleibenden 62 Felder sind belegt? Eine Matrix von 62 BITS

C) Wer ist dran? 1 BIT

INSGESAMT BISHER: 75 BITS

D) En Passant. Wenn Weiß an der Reihe ist, können bis zu 5 schwarze Bauern aussehen, als könnten sie En Passant gefangen werden. Der schwarze Bauer muss sich in Reihe 5 befinden (von unten nach oben beginnend bei Null) und einen weißen Bauern daneben haben. Eine Situation mit maximal möglicher Anzahl von Erfassungen sieht folgendermaßen aus:

BWBBWBBW

Wenn es 6 schwarze Bauern in Reihe 5 gäbe, hätte Weiß nur 2 Felder und könnte nur 4 schwarze Bauern bedrohen, so dass es nicht möglich ist, mehr als 5 schwarze Bauern gleichzeitig von En passant zu bedrohen. Wir brauchen also eine Zahl von 1 bis 5 , die angibt, welcher der (bis zu 5) Bauern in Reihe 5, neben dem sich ein feindlicher (in diesem Fall weißer) Bauer befindet, in der letzten Runde 2 Felder vorgerückt hat ( oder Null, wenn kein Bauer vorhanden ist) in dieser Situation wurde auf diese Weise in der letzten Runde bewegt.)

E) Welche der bis zu 30 besetzten Felder (ohne Könige) enthalten sie?

Es gibt 10 Möglichkeiten, die jeweils durch eine Dezimalzahl dargestellt werden.

Das niedrigstwertige Bit repräsentiert die Farbe.

Daher sind gerade Zahlen weiß, ungerade Zahlen sind schwarz.

Weiß schwarz

Bauer 0/1 (oder Turm, der ziehen darf *)

Ritter 2/3

Bischof 4/5

Turm 6/7

Königin 8/9

* Ein Turm, der ein Schloss bilden darf (und daher niemals aus der ersten oder letzten Reihe bewegt wurde), wird durch 0 oder 1 anstelle von 6 oder 7 dargestellt. Er kann nicht mit einem Bauern verwechselt werden, da auf der ersten Reihe keine Bauern gefunden werden können oder letzte Reihe.

Dies ergibt eine Dezimalzahl von bis zu 30 Stellen, die wir mit 6 multiplizieren und dann den Code für En passant hinzufügen können. Die resultierende Zahl passt in 103 Bits, die, wenn sie zu den oben erwähnten 75 addiert wird, 103 + 75 = 178 Bits sind . Wenn wir einfach mit 10 anstatt mit 6 multiplizieren, macht dies keinen Unterschied in der Anzahl der verwendeten Bits, und das Dekodieren ist einfacher.

Dies sind nur 2 Bits mehr als 22 Bytes. Wir können es jedoch auf 174 Bit herunterschieben, wie unten erläutert.

Wenn keine Figur erbeutet wurde, kann kein Bauer befördert werden .

Der Beweis ist wie folgt. Stellen Sie sich vor, Weiß ist von Anfang an davon besessen, seinen Bauern in Spalte E zu befördern. Es gibt einen schwarzen Bauern gegenüber diesem Bauern, der im Weg ist. Um diesen Bauern zu befördern, muss daher eine der folgenden Bedingungen erfüllt sein:

1) Der schwarze Bauer wird gefangen genommen.

2) Der schwarze Bauer fängt eine weitere Figur und tritt damit aus dem Weg.

3) der weiße Bauer fängt einen Bauern auf einer benachbarten Spalte, wie z. B. Spalte D.

4) Der weiße Bauer übergibt einen schwarzen Bauern an einer angrenzenden Säule (oder wird daran vorbeigeführt) und fängt dann ein Stück an derselben angrenzenden Säule ein, wodurch der weiße Bauer die Spalte wechselt.

Fall 4 ist der interessanteste, da nicht nur der weiße Bauer, der in Spalte E begann, jetzt einen klaren Weg zur Beförderung hat. Der schwarze Bauer auf Spalte, der auf Spalte E verbleibt, kann ebenfalls befördern. Daher kann eine einzelne Erfassung den Weg für einen Bauern jeder Farbe freimachen.

Wie auch immer, die Tatsache, dass kein Bauer befördern kann, bis eine Figur gefangen ist, bedeutet, dass wir die 30. Figur nicht lagern müssen. Wir können es durch Eliminieren (oder durch Subtrahieren) herausfinden, da sich der gesamte Satz an Stückcodes zu Beginn des Spiels immer auf den gleichen Betrag summiert = 80. Ein kleiner Punkt ist, dass wir sicherstellen müssen, dass die Quadrate die Türme sind Stand zu Beginn des Spiels werden unter anderem die ersten gescannten (denn wenn sie die letzten wären, würden wir nicht wissen, ob der Turm ziehen könnte oder nicht) 8 bis 1 Scanreihe [r mod 8].

Die Bitmatrix in (B) gibt an, wie viele Teile es gibt (ausgenommen Könige). Wenn es volle 30 gibt, ignorieren Sie das letzte Stück beim Codieren, der Decoder berechnet, was es war. Wir haben jetzt eine bis zu 29-stellige Dezimalzahl, die wir mit 6 multiplizieren und zum En Passant-Code hinzufügen. Die resultierende Zahl wird einfach in 99 Bits zerquetscht, was insgesamt 99 + 75 = 174 Bits ergibt.

Als Beispiel Hier ist eine aktuelle Position. Weiß hat gerade seinen ersten Zug gemacht (Königspfand) und Schwarz ist an der Reihe.

rnbqkbnr
pppppppp


    P

PPPP PPP
RNBQKBNR

A) Position der Könige (Weiß / Schwarz in Oktal, 12 Bit ): 03 73 = 000011 111011

B) Welche Felder sind belegt? Beginnen Sie mit Zeile Null (untere Zeile) und dann mit allen anderen Zeilen von oben nach unten, wobei Sie die Könige überspringen:

1111 111

1111 111
11111111
00000000
00000000
00001000
00000000
11110111 

C) Schwarz dran: Bit drehen = 1

D) En Passant. Es gibt keinen weißen Bauern neben einem schwarzen Bauern, daher gibt es keinen Bauern, der en passant genommen werden kann (obwohl dieser Bauer den letzten Zug vorgezogen hat), also D = 0. Wenn wir anstatt nur Bauern zu betrachten, die einen feindlichen Bauern neben sich haben, alle Bauern betrachten, die auf beiden Seiten keine befreundeten Figuren neben sich haben, dann wäre D 1, da es in dieser Situation und in dieser besonderen Situation einen solchen Bauern gibt der Bauer wurde in der Tat in der letzten Runde bewegt.

E) Wieder die unterste Reihe zuerst, dann alle anderen Reihen von oben nach unten, wobei die Könige übersprungen werden und die vier nicht besetzten Türme als 0 oder 1 bezeichnet werden (Zahlen, die normalerweise für Bauern reserviert sind).

RNBQ BNR =   0248 420
rnbq bnr =   1359 531
pppppppp =   11111111
PPPPPPPP = (0)0000000

Die 30. Ziffer (in Klammern) kann verworfen werden.

Obwohl es hier nicht sehr offensichtlich ist, befindet sich der Bauer, den Weiß vorgerückt hat, tatsächlich an einem Ende der Bauernliste, da wir Zeile für Zeile scannen.

Unsere Daten sehen jetzt so aus, mit 29 Codes für den Inhalt der Quadrate plus dem En Passant-Code:

 (0 discarded) 0000000 11111111 1359531 0248420 (0 en passant)

Es ist am besten, beim Decodieren von rechts nach links und beim Codieren von links nach rechts (umgekehrte Reihenfolge) zu scannen. Dies bedeutet, dass wir bei weniger Teilen eine kleinere Anzahl haben, während wir die maximale Konsistenz beibehalten (dh wir möchten, dass das Leerzeichen / die Nullen vor- und nicht nachgezogen werden, um die Komprimierung dünn besetzter Bretter zu ermöglichen). Wenn wir nur 2 Könige haben Auf der Platine befinden sich die oben genannten 75 Bit plus 3 Bit zum Speichern von en passant data = 78 Bit im besten Fall. Jedes weitere Stück ist etwas kleiner als 3,5 Bit (2 Stück können in 7 Bit gespeichert werden, da 100 <128).

Ein praktisches Problem besteht darin, dass eine 99-Bit-Ganzzahl zu groß ist, um in eine 64-Bit-Ganzzahlvariable zu passen. Dies bedeutet, dass viele Programmiersprachen dies nicht unterstützen (Sie können eine Zeichenfolgendarstellung mit 29 bis 30 Ziffern nicht einfach konvertieren) Zahl in eine ganze Zahl umwandeln.) Um auf einfache Weise 22 Bytes zu codieren, können wir eine 30-stellige Zahl (29 Stück-Codes + ein Passant-Code) in zwei 15-stellige Zahlen aufteilen, von denen jede 50 Bits (insgesamt 100 Bits) fasst plus die oben genannten 75 machen 175 Bits Worst Case.)

Wie oben angegeben, passen 29 Dezimalstellen plus En Passant-Code (6 mögliche Werte) für eine maximale Komprimierung gerade mal in 99 Bit (insgesamt 174 Bit), jedoch ohne Unterstützung durch die Sprache für Ganzzahlen dieser Größe kompliziert zu programmieren. Es kann einfacher sein, die 29 Farbbits zu trennen und mit den Stückcodes (5 Möglichkeiten) und dem En passant-Code (6 Möglichkeiten) getrennt von den Farben zu arbeiten (70 Bits, passt fast in eine 64-Bit-Variable).

Level River St
quelle
Schöner Trick mit dem letzten Mann.
Peter Taylor
5

Hier ist eine vollständige Lösung, der tatsächliche Worst-Case-181-Bit

Der Schwerpunkt liegt hier auf einem einfachen Programm, das Sie leicht verstehen können

Die Eingabe ist FEN, hier ist die Öffnungsposition, es gibt sechs Felder (5 & 6 werden ignoriert):

rnbqkbnr / pppppppp / 8/8/8/8 / PPPPPPPP / RNBQKBNR w KQkq - 0 1

Das erste Feld (Stückplatzierung) wird analysiert

perl -pe 's/\d/"_"x$&/ge;s/\s.*//;s|/||g'

Produzieren:

rnbqkbnrpppppppp________________________________PPPPPPPRNBQKBNR

Feld eins: Kodiere den Ort der Könige (12 Bits):

printf("%b",index('k',$_))
printf("%b",index('K',$_))

Feld zwei: Teile kodieren (bis zu 5 Bits pro Stück):

s/_/0/g     Blank
s/P/100/g   From here, as normal chess meaning
s/p/101/g
s/Q/11000/g
s/q/11001/g
s/R/11010/g
s/r/11011/g
s/B/11100/g
s/b/11101/g
s/N/11110/g
s/n/11111/g
s/K//
s/k//

Feld drei: aktive Farbe (1 Bit)

s/w/0/
s/b/1/

Feld 4: Verfügbarkeit der Rochade (4 Bits)

m/K/?1:0
m/k/?1:0
m/Q/?1:0
m/q/?1:0

Fünftes Feld: en passant (null oder drei Bits)

printf("%b",ord($1)-ord("a")) unless m/-/
// The EP's rank is 3 or 6 based on active color, only need to encode file

Naiver Worst-Case 200 Bit

  • Zwei Könige Platzierungen - 12 Bits
  • Tafel
    • QRRBBNN QQQQQQQQ - 75 Bits
    • qrrbbnn qqqqqqqq - 75 Bits
    • Leere Quadrate - 30 Bits
  • Aktive Farbe - 1 Bit
  • Rochade - 4 Bits
  • En Passant - 3 Bits

Tatsächlich der schlimmste Fall

Jeder Spieler kann nicht alle Bauern befördern, ohne andere Figuren zu erbeuten . Hier ist der Entropieeffekt der Stückerfassung:

  • PpR(3 + 3 + 5 = 11 Bits) => Qq_(5 + 5 + 1 = 11 Bits)
  • PPpp(3 + 3 + 3 + 3 = 12 Bits) => QQq_(5 + 5 + 5 + 1 = 16 Bits)

Das Worst-Case-Board ist also:

  • QRRBBNN QQQQQQQQ - 75 Bits
  • qrrbbnn qqqq - 55 Bits
  • Leere Quadrate - 34 Bits

Am schlimmsten ist es, alle Figuren zu promoten, anstatt den Bauern en passant zu lassen.

TOTAL ACTUAL WORST CASE MIT ANGEZEIGTEM CODE 12 + 75 + 55 + 34 + 1 + 4 = 181 Bits

FIQ zeigt zwei Verbesserungen an diesem einfachen Schema, die jedoch schwerer zu codieren sind:

  • Entfernen Sie Bit 2 aus der Teilecodierung in den Zeilen 1 und 8, da die Bauern dort nicht hinkommen können (bis zu 16 Bit Ersparnis).
  • Verwende Bauern, um gießbare Türme zu kodieren (4-Bit-Ersparnis)

Der einzige verbleibende Code, der in dieser Antwort aus Gründen der Kürze nicht angezeigt wird, ist: Aufteilen der Eingabe-FEN in Felder ( split /\s/) und Variablenzuweisung.

William Entriken
quelle
Ein Spieler kann alle seine Bauern befördern (vorausgesetzt, er kann feindliche Bauern erbeuten). Qn4QQ / Qb6 / Qq1k4 / Qr6 / Qb6 / Qr6 / Qn4NK / RNB2B1R b - - 0 84
Krzysztof Szewczyk
@ KrzysztofSzewczyk, ja, das ist oben bei PPpp=>QQq_
William Entriken
4

Gesamtdaten benötigen 33 Bytes

(Dank jemandem in den Kommentaren wurde mir klar, dass dies für die Bauernwerbung nicht funktioniert. Wird aktualisiert, wenn ich es lösen kann.)

Für das erste Byte verwenden wir fünf Bits:

  • erstes Bit: Spieler an der Reihe, 1 = weiß
  • Zweites Bit: Schwarzes Königsschloss, 1 = Dosenschloss
  • drittes Bit: Schwarzköniginnenschloss, 1 = Dosenschloss
  • viertes Bit: weißes Königsschloss, 1 = Dosenschloss
  • fünftes Bit: weiße Königin Seite Burg, 1 = kann Burg

Die nächsten 32 Bytes werden verwendet, um jede Schachfigur in einer vordefinierten Reihenfolge darzustellen

  • 3 Bits: repräsentieren die Zeile
  • 3-Bit: Stellt eine Spalte dar
  • 1-Bit: Stellen Sie en-passant dar, 1 = kann en-passant sein
  • 1-Bit: Wenn das Bit "can en-passant" 1 ist: Gibt an, auf welcher Seite 0 = übrig bleibt
    , um anzuzeigen, ob es erfasst wurde. 0 = nicht erfasst
    (Wenn es passant ist, wird es definitiv nicht erfasst)

Ein C-Code zur Darstellung dieser Idee (was eigentlich nicht funktioniert)

int main() {
    char b, c[32], i;

    //decode:

    FILE *p=fopen("/path/to/file.csv","r");
    fscanf(p,"%d,",&b);
    for(i=0;i<31;i++) fscanf(p,"%d,",&c[i]);
    fscanf(p,"%d",&c[31]);
    fclose(p);
    if(b&16) /* white's turn */
    else /* black's turn */
    if(b&8) /* black king side can castle */
    if(b&4) /* black queen side can castle */
    if(b&2) /* white king side can castle */
    if(b&1) /* white queen side can castle */

    for(i=0;i<32;i++) {
        int row, column;
        row=c[i]&7;
        column=c[i]&56;
        if(c[i]&64 && isPawn(c[i])) { //can en-passant
            if(c[i]&128) //can en-passant to the right
            else //can en-passant to the left
        }
        if(!(c[i]&64)) {
            if(c[i]&128) //captured
            else //not captured
        }
    }

    //encode:

    p=fopen("/path/to/file.csv","w");

    if(b&16) b&=239;
    else b|=16;
    if(black_king_side_cannot_castle) b&=247;
    if(black_queen_side_cannot_castle) b&=251;
    if(white_king_side_cannot_castle) b&=253;
    if(white_queen_side_cannot_castle) b&=254;

    for(i=0;i<32;i++) {
        c[i]=row;
        c[i]+=column*8;
        if(isPawn(c[i]) && can_en_Passant) {
            c[i]|=64;
            if(can_en_Passant_left) c[i]&=127;
            else c[i]|=128;
        }
        if(!(c[i]&64)) {
            if(isCaptured(c[i])) c[i]|=128;
            else c[i]&=127;
        }
    }
    fprintf(p,"%d,",b);
    for(i=0;i<31;i++) fprintf(p,"%d,",c[i]);
    fprintf(p,"%d",c[31]);
    fclose(p);
    return 0;
}
ace_HongKongIndependence
quelle
-1, das ist keine Antwort ...
Türklinke
1
Ihre vordefinierte Reihenfolge ist nicht hilfreich, wenn ein Bauer den achten Rang erreicht und zum Ritter, Bischof, Turm oder zur Königin befördert wird.
Squeamish Ossifrage
@Doorknob of Snow ok Ich arbeite an dem Algorithmus, es ist nur ein bisschen spät in der Nacht und ich bin müde, also mache ich es etwas langsamer
ace_HongKongIndependence
Na, warum hast du das dann gepostet, wenn du nicht mal eine Lösung hast?
Türklinke
3
Wenn Sie immer noch der Meinung sind, dass diese Antwort Mist ist und hier keinen Wert hat, stimmen Sie ab, um sie zu löschen, und stimmen Sie ab. Sie können auch meinen Account hier löschen. Ich möchte nur mitteilen, woran ich denken könnte. Warum müsst ihr so ​​gemein sein?
ace_HongKongIndependence
4

256 242 Bits

Hier ist ein grundlegender Komprimierungsalgorithmus, der wahrscheinlich verbessert werden kann, weil er bestimmte illegale Positionen nicht von der Darstellung ausschließt.

Die Karte beginnt mit 5 Bits Header-Info wie folgt:

0 1 1 1 1
---------
1 2 3 4 5

1: Turn (black = 1, white = 0)
2: Black can castle queen-side
3: Black can castle king-side
4: White can castle queen-side
5: White can castle king-side

Dann eine Folge von 12 Bits, die die Positionen der Könige darstellen.

0 0 0 1 0 0 1 1 1 1 0 0
-----------------------
0 0 0 0 0 0 0 0 0 1 1 1
1 2 3 4 5 6 7 8 9 0 1 2

01 - 03: white king's rank
04 - 06: white king's file
07 - 09: white king's rank
10 - 12: white king's file

Dann eine riesige 64-stellige Zahl in der Basis 11, die dann mit 9 multipliziert wird, um eine weitere Ziffer am Ende hinzuzufügen, die den Status des Passanten darstellt. Jede Ziffer in Basis 11 repräsentiert ein Quadrat auf der Tafel mit den folgenden möglichen Werten:

0: empty

1: white pawn
2: white knight
3: white bishop
4: white rook
5: white queen

For the black equivalent of each white piece, add 5.

Und die Ziffern in Basis 9:

0: no en-passant possible
1 - 8: en-passant on rank 1 - 8

11 64 × 9 ist ungefähr 2 224,57 , was 225 Bits zum Codieren erfordert. Plus die 17 Header-Bits an der Spitze sind insgesamt 242 Bits.


Danke an ugoren für die Verbesserungen.

Joe Z.
quelle
Dies ist dem Algorithmus von ace sehr ähnlich, verwendet jedoch Brettpositionen anstelle von Teilen in einer vorgegebenen Reihenfolge, wodurch beide das Problem der Bauernwerbung ausschließen und die Daten ein wenig abgeschnitten werden können.
Joe Z.
Sie können En-Passant als eine Zahl zwischen 0 und 8 speichern (in welcher Spalte kann der aktuelle Spieler En-Passant erfassen?). 13^64 * 9ist 239,99 und spart 11 Bits. Sparen Sie mehr, indem Sie Königspositionen separat codieren.
Ugoren
Laut Doorknob of Snow, der meinen Beitrag kommentiert hat, ist diese Art von Antwort "keine Antwort". Ich sage es nur. Zu Ihrer Information, sein Kommentar wurde gepostet, bevor ich den C-Code zu meiner Antwort hinzufügte.
ace_HongKongIndependence
@ugoren: Das habe ich vergessen. Sie haben Recht, ich habe vergessen, dass nur ein Bauer gleichzeitig passiv sein kann.
Joe Z.
@ace: Ihre Antwort ist nicht ungültig, da sie keinen Kodierungs- und Dekodierungscode enthält. Es ist ungültig, weil es den Bauernwerbefall nicht berücksichtigt (in diesem Fall hat Ihre vordefinierte Reihenfolge der Teile keine Wirkung). Das Problem verlangt im Kern nach einem Datencodierungsschema. Das Programm ist nur eine Schnittstelle dazu.
Joe Z.
3

? Bits

(≥ 217 Worst-Case, 17 Best-Case, 179 für Initial Board)


Kodierungsbeschreibung

Zusätzliche Metadaten bestehen aus deren Zug (ein Bit) und Rochade (vier Bits, dh darf weiße Burg auf der Seite der Könige - auf der Seite der Königinnen - und ähnlich für Schwarz).

Für die Brettposition selbst codieren wir sie als Satz aktiver Teile. Nun, eigentlich stellen wir sicher, dass wir die Teile aus Gründen, die ich gleich erläutern werde, in einer bestimmten Reihenfolge aufzählen. Für jedes Stück speichern wir seine Farbe (ein Bit), seine Art (drei Bits, um 6 Arten zu umfassen, plus eine zusätzliche Art für "Bauer, der von einem Passanten genommen werden kann") sowie seine Position.

Hier ist der interessante Teil: Um die Position eines Stücks zu codieren, anstatt es als Koordinate zu speichern, speichern wir seinen relativen Abstand zum letzten Stück, wenn wir die Stücke in der Reihenfolge von links nach rechts von oben nach unten auflisten (dh A8 , B8, ..., G1, H1). Außerdem speichern wir den Abstand als Zahl mit variabler Länge. 1Dies bedeutet, dass dieses Stück direkt neben dem vorherigen liegt, 0xxzum Überspringen von 1 bis 3 Stücken, 000xxxzum Überspringen von 4 bis 10 Stücken, 000000xxxxfür 11 0000000000xxxxxbis 25 Stücken und für 26 bis 56 Stücken und schließlich 000000000000000xxxfür 57-62.

Beispiele

Ich habe einige Positionen zusammengefasst, die mit dieser Codierung codiert wurden, und die Position für die Anfangsposition mit einigen Kommentaren versehen.

Ich weiß nicht, wie ich die Bitgröße im ungünstigsten Fall analysieren soll, aber anhand der Beispiele im Kern glaube ich, dass der Algorithmus zumindest einigermaßen effizient sein sollte.


Implementierung von Decoder

Nachfolgend finden Sie einen schnellen und fehlerhaften Decoder für diese Codierung (Eingabe der im Text codierten Binärdaten, wie im oben angegebenen Beispiel, und Überspringen von Dingen, die nicht "0" oder "1" sind). Produziert ein Unicode-Schachbrett nach Standard.

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

char buf[1024];
int wi = 0, ri = 0;

int read_n(int n) {
  int res = 0;
  for (int i = 0; i < n; i++) {
    res = res << 1 | (buf[ri++] == '1');
  }
  return res;
}

int read_varnum() {
  int v, c = 0;

  for (int i = 1; i <= 5; i++) {
    v = read_n(i);
    if (v != 0) return c + v;
    c += (1 << i) - 1;
  }

  assert(false); /* Shouldn't happen */
}

char *piece_to_str(int piece, int color) {       /* ↓ pawn that may be taken with en passant */
  char *pieces[] = { "♙", "♘", "♗", "♖", "♕", "♔", "♙",
                     "♟", "♞", "♝", "♜", "♛", "♚", "♟" };
  return pieces[color * 7 + piece];
}

int main(void) {
  int ch;
  while (ch = getchar(), ch != EOF) {
    if (ch == '0' || ch == '1') buf[wi++] = ch;
  }

  int board[64];
  memset(board, -1, 64 * sizeof(int));

  /* Read metadata */
  int is_white = read_n(1);
  int castling = read_n(4);

  /* Read the board state */
  int bi = -1;
  while (ri != wi) {
    int color = read_n(1);
    int kind  = read_n(3);
    int delta = read_varnum();
    board[bi + delta] = color << 8 | kind;
    bi += delta;
  }

  /* Print metadata */
  printf("  Current turn: %s's turn to play.\n", is_white? "white" : "black");
  printf("  Castling: White may castle? %s %s\n",
         castling & 0x8? "left" : "", castling & 0x4? "right" : "");
  printf("            Black may castle? %s %s\n",
         castling & 0x2? "left" : "", castling & 0x1? "right" : "");
  printf("\n");

  /* Print the board out */
  printf("+");
  for (int x = 0; x < 8; x++) printf("--");
  printf("-+\n");

  for (int y = 0; y < 8; y++) {
    printf("|");
    for (int x = 0; x < 8; x++) {
      int piece = board[y*8 + x],
          color = piece >> 8,
          kind  = piece & 0xFF;

      if (piece == -1) printf("  ");
      else printf(" %s", piece_to_str(kind, color));
    }
    printf(" |\n");
  }

  printf("+");
  for (int x = 0; x < 8; x++) printf("--");
  printf("-+\n");

  return 0;
}
FireFly
quelle
Ich habe keine Ahnung, wie hoch Ihre Bitanzahl im schlimmsten Fall ist, aber ich vermute, dass sie erheblich mehr als 179 Bit beträgt. Wie würde Ihr Algorithmus beispielsweise mit diesem Layout umgehen ? (Es ist gültig, nebenbei gesagt, ich machte es den Editor bei Verwendung von chess.com )
zimperlich ossifrage
@squeamishossifrage, dass man anscheinend 217 Bits benötigt: gist.github.com/FireyFly/8639791 (danke für den Testfall, ich wollte es mit einem
kniffligeren
Hey, das ist nicht schlecht. Mach weiter!
Squeamish Ossifrage
2

Max: 184 Bit, Min: 75 Bit

Ich wurde von @ AdamSpeights Huffman inspiriert, mit dem ich versuchen wollte, mein eigenes Schema zu erstellen. Ich bezweifle, dass dies gewinnen wird, aber es gibt berechenbare Grenzen.

Bei diesem Schema werden die Schachfiguren so behandelt, als gäbe es 11 verschiedene Arten von Figuren. Ich folgte ungefähr dem Huffman-Codierungsalgorithmus, um diese Klassen nach ihren Frequenzen und reellen Typen zu gruppieren und die folgenden Codierungen zu generieren:

 Piece Class                | Frequency Per Team | Encoding
============================+====================+==========
 Pawn, normal               | 0 - 8              | 0
 Pawn, jumped two last turn | 0 - 1              | 1111
 Knight                     | 0 - 2              | 1000
 Bishop                     | 0 - 2              | 1001
 Queen-side rook, unmoved   | 0 - 1              | 10100
 Queen-side rook, moved     | 0 - 1              | 10101
 King-side rook, unmoved    | 0 - 1              | 10110
 King-side rook, moved      | 0 - 1              | 10111
 Queen                      | 0 - 1              | 1110
 King, unmoved              | 0 - 1              | 1100
 King, moved                | 0 - 1              | 1101

Vor jedem Stückcode können zwei Bits stehen, um anzuzeigen, zu welchem ​​Team er gehört ( 10für Weiß, 11für Schwarz). 0kann verwendet werden, um Leerzeichen zu kodieren. Mit diesen Ideen können wir eine Quadrat-für-Quadrat-Codierung für das gesamte Board erstellen, und zwar nach dem von uns gewünschten Verfahren. Ich werde die Iterationsreihenfolge übernehmen a1, b1, c1, ... f8, g8, h8. Dies bedeutet, dass nur das Auflisten dieser Codes, wie oben gezeigt, alle Informationen verschlüsselt, mit Ausnahme derer, die an der Reihe sind. Eine sehr einfache Schachengine kann die "Klassen" für die Bauern, Türme und Könige verwenden, um festzustellen, ob Rochade und En-Passant legal sind. Darüber hinaus können mit diesem Schema Bauernaktionen problemlos durchgeführt werden. Wenn ein Spieler einen Bauern zu einem Turm befördert, kann entweder der Königs- oder der Dame-Code verwendet werden, solange die "bewegte" Variante gewählt wird.

Abgesehen von pathologischen Positionen, von denen ich nicht glaube, dass sie jemals eintreten könnten, ist das Worst-Case-Szenario für diese Kodierung, dass sich alle Teile noch auf dem Brett befinden und der vorherige Spieler einen Bauern zwei Felder vorwärts bewegt hat. Die folgende Karte codiert als Beispiel 1. e4:

1101010010100010100110111010110010100110100010101101001001001100100100100000000000000101111000000000000000000011011011011011011011011011101001110001110011111101111001110011110001110110
===========================================================================
                              Black's move
1110100 111000 111001 111110 111100 111001 111000 1110110 | r n b q k b n r
    110    110    110    110    110    110    110     110 | p p p p p p p p
      0      0      0      0      0      0      0       0 | . . . . . . . .
      0      0      0      0      0      0      0       0 | . . . . . . . .
      0      0      0      0 101111      0      0       0 | . . . . P . . .
      0      0      0      0      0      0      0       0 | . . . . . . . .
    100    100    100    110      0    100    100     100 | P P P P . P P P
1010100 101000 101001 101110 101100 101001 101000 1010110 | R N B Q K B N R

Dies bedeutet, dass die Worst-Case-Codierung 184 Bits hat: 1 für die Anzeige des Spielers, 32 für die leeren Felder, 45 für die ungerührten Bauern, 6 für die Zwei-Raum-springenden Bauern, 24 für die Ritter, 24 für die Bischöfe. 28 für die Türme, 12 für die Königinnen und 12 für die Könige.

Wenn sich Teile bewegen und erfasst werden, nimmt die Größe der Codierung ab. Das beste Szenario wird von zwei Königen allein auf der Tafel dargestellt: 1 Bit für die Anzeige des Spielers + 62 Bit für die Anzeige der leeren Felder + 12 Bit für die Anzeige der Könige ergeben eine Mindestlänge von 75 Bit.

Ich komme zurück und bearbeite diese Antwort mit einem Code, der diese Codierung später heute oder morgen demonstriert. Im Moment bin ich gespannt, was andere Leute von dieser Kodierung halten.

sadakatsu
quelle
1
Sie können Bits auf den Türmen speichern. Sie können die Queen- und King-Seite basierend auf der Position bestimmen, und Sie müssen nicht wissen, von welcher Seite ein Turm kam. Sie brauchen also nur eine Information über den Turm - bewegt oder unbewegt.
Nicht dass Charles
... Und tatsächlich, ist , dass Daten auf einem Stück Ebene Speicherung einfacher Encoder / Decoder, aber wenn Sie eine Markierung am Anfang nur gespeichert, können Sie Bits insgesamt schlechtesten Fall (zB die Markierung speichern 11001Mittel B'S MOVE W CAN KSC W CANT QSC B CANT KSC B CAN QSC). Das sind 4 Bits anstelle von 5 Bits pro Seite in Ihrer Codierung oder 3 Bits pro Seite, wenn Sie die Seitenmarkierung auf den Türmen entfernen. ( KSC= Königsschloss. QSC= Königsschloss)
Nicht dass Charles
Aufgrund von Werbeaktionen ist es durchaus möglich, bis zu 9 Damen oder 10 Ritter (oder andere nicht-königliche, nicht-
nicht dass Charles
1

184 Bits = 23 Bytes im schlimmsten Fall und nicht zu kompliziert:

A. Welche Quadrate belegt sind: 64 Bits = 8 Bytes B. Welche Farben für die <= 32 belegten Quadrate sind: 32 Bits = 4 Bytes Und jetzt nur die <= 30 Quadrate verwenden, die von Nichtkönigen belegt sind: B. PNBRQ-codiert in Radix verwenden 5, für 5 ^ 30 Möglichkeiten; und 32 * 31 * 2 * 4 * 4 * 9 für Königspositionen, Mover-Color, White & Black Castling Rights, en passant Square (unter 8 Möglichkeiten plus keine, ein 9.); Diese Zahl 5 ^ 30 * 32 * 31 * 2 * 4 * 4 * 9 = 2660751342773437500000000 = 2 ^ 87.782 passt in 88 Bits für insgesamt 64 + 32 + 88 = 184 Bits für die gesamte Codierung.

Dies kann reduziert werden, z. B. 32 * 31 * 2 * 4 * 4 * 9 = 285696 kann durch Verwendung von fact auf 2 * (32 * 31 + 31 * 3 + 31 * 3 + 3 * 3) * 6 = 14244 reduziert werden Höchstens 6 vorübergehende Opferkandidaten (einschließlich keiner) und die Kodierung der Rechte für die Rochade und der Königspositionen innerhalb desselben Satzes unter Verwendung der Rechte für die Rochade spielen nur dann eine Rolle, wenn der König auf dem Anfangsquadrat steht. Dies spart 4 Bits.

Ich habe Grund zu der Annahme, dass es nicht möglich ist, 18 Bytes zu erreichen, dh die Gesamtzahl der zulässigen Schachpositionen übersteigt 2 ^ 144.

Ihr 160-Bit-Schema ist sehr genial, aber ich denke, es muss als Codierungs- / Decodierungsprogramm angegeben werden, bevor ich mir vollständig sicher sein kann.

Warren D. Smith
quelle
1

171-Bit-Worst-Case:

Ich habe ein paar Ideen sowie einige meiner eigenen Gedanken kombiniert.

Wir werden mit einer 64-Bit-Karte beginnen. Jedes Bit repräsentiert einen belegten Platz auf der Tafel. Sie füllen sich entlang der Reihen. So sieht der Start aus:1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111

Jetzt wird jedes Stück durch 4 Bits dargestellt. 1. Bit: Farbe ( 0=white, 1=black) 2.-4. Bit: Eine von 8 Arten.

0=king, 1=queen, 2=bishop0, 3=knight, 4=rook, 5=pawn0, 6=pawn1, 7=bishop1

Am Ende werden wir ein bisschen die Kurve bezeichnen. 0=white, 1=black.

4 Bits * 32 Teile = 128 Bits und ich habe bereits 64 + 1 von Turn und Board. Das ergibt insgesamt 128 + 64 + 1 = 193 Ich habe noch nicht einmal mit En Passant oder Castling angefangen. Weit über meiner Grenze mit nichts - dreht sich nicht einmal. Hier fangen die Tricks an.

Okay - siehst du diese Typen oben? Bischof0 und Bischof1? Bauer0 und Bauer1? Diese Typen sind so bezeichnet, weil sie uns sagen, dass wir etwas nach diesem Stück einfügen sollen. Bishop0 bedeutet also, dass es danach eine 0 gibt - dh, dass das nächste Stück weiß ist. Bischof 1 sagt uns, dass das nächste Stück schwarz ist und dass der Bauer 0 und der Bauer 1 gleich funktionieren. (Wenn es sich bei diesem Stück um das letzte Stück handelt, das aufgezählt wird, werden wir stattdessen über die nächste Runde informiert.)

Mein schlimmster Fall betrifft alle Teile auf dem Brett, also erspart mir das mit 16 Bauern und 4 Bischöfen 20 Bits. Ich bin runter auf 173.

Okay. Für ein weiteres bisschen in meinem schlimmsten Fall - sobald 16 Farben codiert sind, hören wir auf, Farben zu codieren - so wie wir es vorwärts wissen. In meinem schlimmsten Fall schafft es ein weißes Stück ohne Fänge in die hinterste Ecke. Dort spare ich nur ein bisschen. 172.

Ich werde jetzt die Reihenfolge ändern, in der ich die Teile benenne. Wir werden sie entlang der Spalten benennen, die von außen nach innen beginnen. Das am Anfang genannte Brett wird gleich bleiben, aber wenn ich Stücke darauf lege, beginne ich unten rechts mit Weiß und gehe diese Spalte hinauf. Dann springe ich rechts unten zu Schwarz und gehe die Spalte hoch. Ich springe in die unbekannte Zelle rechts unten und so weiter - das heißt, mein schlimmster Fall ist wieder der Anfang. Mein Grund hat mit meinem en passant Trick, den nächsten zwei Bits, die ich verliere, und der Rochade zu tun.

Damit ein Bauer befördert werden kann (wie bereits ausführlich besprochen), muss eine Figur erbeutet werden. Wenn wir also wissen, dass es 32 Teile gibt, müssen wir nur 31 davon bezeichnen. Das letzte Stück ist eindeutig identifiziert. Wie sich herausstellt, spart dies für mich nur 2 Bit - weil mein letztes Stück vielleicht ein Bauer / Läufer ist (was mich normalerweise 3 Bit kostet, weil ich eines für das nächste Stück speichere), dessen Farbe bereits festgelegt ist und es auch nur war 2 Bits. Ich habe nur noch 170 Bits.

Wenn Bauern befördert werden, ändern sie einfach ihren Typ. Für jedes Stück, das vom Brett geht, befreie ich mich von (mindestens) 3 Bits, und zwei Bauernaktionen kosten mich 2 Bits, so dass ich bei Aktionen (langsam) nachlasse.

Rochade. Damit die Rochade stattfinden kann, haben sich möglicherweise weder der König noch der relevante Turm bewegt. Wenn ein Turm also in der Lage ist, sowohl ihn als auch den König zu besetzen, befindet er sich an seinen ursprünglichen Orten. So werden die zum Rochieren fähigen Türme an der gleichen Stelle aufgeführt wie die Könige dieser Farbe. Da dies illegal ist (zwei Könige oder drei Könige der gleichen Farbe auf dem Brett) und nur in drei möglichen Aufstellungen für jede Farbe vorkommen kann (links, rechts, beide Türme sind als Könige aufgeführt), ist eine Dekodierung absolut möglich. Wir haben also kein bisschen Rochade verschlüsselt.

En Passant Hier werden auch illegale Positionen verwendet. Es kann immer nur ein Bauer en passant in Gefahr sein. Es muss in der vierten Reihe sein. Der Bauer, der verwundbar ist, wird zurück in seine Ausgangsreihe gedreht - mit allem, was da ist, vertauscht. Da sich dieser Bauer in seiner eigenen ersten Reihe befindet - eine illegale Position -, ist die Situation für den Decoder offensichtlich. Er kehrt die Positionen um und markiert den Bauern als anfällig für unbefugte Personen.

Wir mussten uns über die Bestellung lustig machen, da das letzte Stück eindeutig identifiziert werden muss. In einer Standardreihenfolge würden wir nicht erkennen können, ob der Turm in der hinteren Ecke eine Burg bilden könnte - das ist nicht bekannt. Wenn wir von außen nach innen arbeiten, garantieren wir, dass dort, wo der Turm in seiner eigenen Ecke oder in der Mitte des Bretts „aufgeführt“ ist, weil er mit einem en passant verwundbaren Bauern getauscht wurde, ein Stück nachher aufgeführt wird es - so wird uns der Turm-Typ erzählt. Wir wissen, dass es ein Stück danach geben wird, denn damit ein Bauer verwundbar ist, muss es einen Bauern im Inneren geben (der später entscheidend gemäß den obigen Anweisungen codiert wird).

Oh, und um sicherzustellen, dass der schlimmste Fall alle Teile auf dem Brett betrifft, können wir, sobald wir weniger als 32 Teile haben, das 64-Bit-Brett verwenden, um Spielzug- und Besetzungspositionen zu identifizieren drehen und 1 ist, wenn es schwarz ist, drehen.

So wurden wir en passant und kostenlos Rochade. Wir haben das letzte Stück umsonst abgeholt, aber es hat ein bisschen geklärt, um das Spiel mit den Regeln von en passant und castling schön zu machen. Wir haben 20 Bits auf die Standardteile geworfen. Ich glaube, dass der schlimmste Fall darin besteht, dass ein mittelgroßer weißer Bauer vorwärts bewegt wird und ein schwarzes Stück zwischen ihm und seiner Königin liegt, während sich alle Teile auf dem Brett befinden. Schneller Doppelcheck: Die erste Figur wird erbeutet - nenne es einen Bauern, 3 Bits von der Tafel in der Figur, 3 Bits auf der Tafel in Form einer letzten Figur, ein Bit von der Spielzugmarke verschwinden. Bewerben Sie zwei Bauern 2 Bits zurück auf dem Brett. Verdammt, ich bin bei 171.

BEARBEITEN Ich habe Code für einen (funktionierenden?) Decoder hinzugefügt - in R - unten. Es werden Vektoren von Booleschen Werten als Eingabe verwendet - (Entschuldigung - ich bin nicht in der Lage, alles zu codieren, was es mir ermöglichen würde, die Bits tatsächlich zu verwenden). Ich habe auch die Startposition eingefügt.

separate = function(vec){
    #Using a boolean vector (sorry R doesn't handle bits well and this will build quickest)
    board = matrix(vec[1:64],8,8,byrow=T)
    npieces = min(sum(board),64-sum(board))
    n = length(vec)
    a = vec[65:n]
    counter = 0
    pieces = list()
    white = 0
    Letters=c(letters,LETTERS)
    for (i in 1:npieces){
        col = ifelse(a[1],"black",{white=white+1;"white"})
        typ = a[2:4]
        a=a[-(1:4)]
        num = 4*typ[1] + 2*typ[2] + typ[3]
        type = switch(letters[num+1],a="king",b="queen",c="knight",d="rook",e="bishop0",f="bishop1",g="pawn0",h="pawn1")
        if (num > 3) {
            if(num%%2){
                a = c(T,a)
            } else {
                a = c(F,a)
            }
            type = substr(type,1,nchar(type)-1)
        }
        pieces[[Letters[i]]] = list(color=col,type=type)
        if (length(pieces)==31&&npieces==32) {
            col = ifelse(16-white,{white=white+1;"white"},"black")
            type = "TBD"
            pieces[[Letters[i+1]]] = list(color=col,type=type)
            break
        }
    }

    if (npieces==32) {
        f=function(y){sum(sapply(pieces,function(x)x$type==y))}
        if (f("pawn")<16) {pieces[[32]]$type="pawn"}
        if (f("bishop")<4) {pieces[[32]]$type="bishop"}
        if (f("knight")<4) {pieces[[32]]$type="knight"}
        if (f("queen")<2)  {pieces[[32]]$type="queen"}
        if (f("king")<2)   {pieces[[32]]$type="king"}
        if (f("rook")<(6-f("king"))) {pieces[[32]]$type="rook"}
    }
    return(list(board,pieces,turn=ifelse(a[length(a)],"black","white")))
}


fillboard = function(out) {
    board = out[[1]]
    pieces = out[[2]]
    turn = out[[3]]
    lpieces = lapply(pieces,function(x) paste(substr(x$color,1,1),x$type))
    game = matrix("     ",8,8)
    #Start with corners.
    a = c(1,57,8,64)
    #Then kings
    b = c(25,32)
    #Then rooks in en passant
    c = c(4,60,5,61)
    #Then kings in en passant
    d = 28:29
    exceptions = list(a,b,c,d)
    for (places in exceptions) {
        c= which(board[places])
        if (length(c)) {
            repl = lpieces[1:length(c)]
            game[places[c]] = unlist(repl)
            board[places] = F
            lpieces = lpieces[-(1:length(c))]
        }
    }
    #Loop through rows.
    for (i in c(1:4,8:5)) {
        j = which(board[i,])
        if (length(j)) {
            repl = lpieces[1:length(j)]
            game[i,j] = unlist(repl)
            board[i,j] = F
            lpieces = lpieces[-(1:length(j))]
        }
    }
    return(matrix(unlist(game),8,8,F))
}

swapillegal = function(matr) {
    mat = matr
    if (any(mat[8,]=="b pawn")) {
        j = which(mat[8,]=="b pawn")
        mat[8,j] = mat[5,j]
        mat[5,j] = "b pawn-e"
    }
    if (any(mat[1,]=="w pawn")) {
        j = which(mat[1,]=="w pawn")
        mat[1,j] = mat[4,j]
        mat[4,j] = "w pawn-e"
    }

    if (sum(mat[8,]=="b king") > 1) {
        j = which(mat[8,-4]=="b king")
        j[j==7] = 8
        mat[8,j] = "b rook-c"
    }
    if (sum(mat[1,]=="w king") >1) {
        j = which(mat[1,-4]=="w king")
        j[j==7] = 8
        mat[1,j] = "w rook-c"
    }
    return(mat)
}

decode = function(vec) {
    a = separate(vec)
    b = fillboard(a)
    c = swapillegal(b)
    list(board=c,turn=a[[3]])
}


startboard = c(rep(T,16),rep(F,32),rep(T,16))
#Re-ordering -- first spots will be the corners. Then kings. then en passant positions of those spots
pieces = c(F,F,T,T,F,F,T,T,T,F,T,T,T,F,T,T,F,F,F,F,T,F,F,F,F,F,T,F,F,T,F,F,F,F,T,F,T,F,F,F,T,F,F,T,T,F,T,T,F,T,T,F,T,T,F,T,T,F,T,T,F,T,T,F,T,T,T,F,T,F,T,T,F,T,F,F,T,T,T,F,T,F,T,F,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,F)
########## w rook -w rook -B rook -B rook -W king -B king -w kni  -w bi 0 -w Q  -w Bi 0 -w kni-w p0   - 2   -   3 -  4  - 5   -  6  -  7  -w p1 -b kni-b bi1  -b q  -b bi1  -b kni-b p1   -2    - 3   - 4   - 5   - 6   - b p0- implicit b p0.
#After the kings come all the prior en passant positions. which are empty at start. Then we start at whites bottom right, and move across rows to middle. Then we go to blacks bottom left, and fill across to the middle.
#Changing start to properly encode rooks for castling
newpieces= c(F,F,F,F,F,F,F,F,T,F,F,F,T,F,F,F ,pieces[-(1:16)])
test2 = decode(c(startboard,newpieces))

Dieser Code baut 4 Funktionen auf. Eine, die eine grundlegende Trennung der Teile und der Brettstruktur vornimmt sowie den Teiletyp und alle "impliziten" Teile herausfindet. Die nächste Funktion füllt die Board-Struktur mit diesen Stücken in einer leicht bizzarren (und von meiner anfänglichen Algorithmus) Reihenfolge [in Code-Kommentaren erklärt]. Die nächste Funktion nimmt die ausgefüllte Tafel und erkennt illegale Positionen - sie repariert sie dann und benennt Bauern, die für en passant "x pawn-e" anfällig sind, und alle Türme, die "x rook-c" ziehen können, um. Die letzte Funktion ist ein Wrapper, der diese Funktionen der Reihe nach ausführt und eine Ausgabe ausgibt, die sowohl die aktuelle Karte als auch den Turn darstellt.

Ich habe auch die Codierung der Startposition eingefügt (um dies zu sehen, müssen Sie jedoch aufrufen c(startboard,newpieces)und der Code ruft die Wrapper-Funktion an dieser Position auf.

user5957401
quelle
Das ist interessant. Ich würde gerne eine funktionierende Implementierung als Proof of Concept sehen.
Mego
Die Implementierung ist in der Regel ein paar Schritte vom Proof of Concept entfernt, aber ich habe einen Decoder hinzugefügt. Es ist in R und verwendet daher eher Boolesche als Bits (sorry - wollte nicht zu viel Zeit verwenden). Aber ich glaube, es sollte ein Proof of Concept sein.
user5957401
0

229/226 Bits

Dies stellt sich als nicht sehr erfolgreich heraus, könnte aber andere Menschen davon abhalten, den gleichen Weg zu gehen.

Die einfache Version:

  • 1 bisschen für wessen an der Reihe ist
  • 4 Bits für die vier Rochiermöglichkeiten
  • 3Bits für die en passant Möglichkeiten. Das hat mehr Tiefe, als ich zuerst verstanden habe. En passant muss von einem Bauern gemacht werden, der sich vom gleichen Rang (Reihe) bewegt wie der Bauer, der erbeutet wird. Die Fallanalyse zeigt, dass, sobald wir wissen, wie viele Bauern der Farbe, die sich zuletzt bewegt haben, genau zwei Felder vorgerückt haben, es höchstens 6 Fälle en passant gibt (einschließlich des Falls, dass es keinen Bauern gibt, der für en passant anfällig ist ). Der schlimmste Fall sind 5 Bauern (potenziell alle anfällig: zB PpPPpPPphat fünf anfällige Ps). Mit 6 Bauern gibt es höchstens 2 gegnerische Bauern im gleichen Rang, von denen jeder höchstens 2 Bauern en passant bedrohen kann . Deshalb brauchen wir ceil(lg 6) = 3hier Bits.

Dann die Tafel. Die Karte hat 64 Quadrate, so dass ein Quadratindex in 6 Bits codiert werden kann. Wir listen die Männer abwechselnd nach Rängen auf, beginnend mit dem König.

  • 6Bits: Position des weißen Königs. (Garantiert auf dem Brett zu sein).
  • 6Bits: Position des schwarzen Königs. (Garantiert auf dem Brett. Im schlimmsten Fall, dass der weiße König in einer Ecke ist, gibt es 60 mögliche Stellen, die er sein könnte; im besten Fall, dass der weiße nicht auf einer Kante ist, gibt es 55).
  • 6Bits: Position der weißen Königin. Wenn es keine weiße Königin gibt, wiederholen Sie die Position des weißen Königs als Signal.
  • Für jede weitere weiße Dame ein 1Bit gefolgt von 6 Bits für die Position.
  • Ein 0bisschen.
  • Das Gleiche gilt für schwarze Königin (en).
  • Ähnliches gilt für Türme, Bischöfe, Ritter und Bauern, obwohl wir die Bauern für eine Farbe überspringen können, wenn wir bereits 16 Männer dieser Farbe haben.
  • Löschen Sie das letzte 0Bit.

Das kostet ein 12bisschen für die Könige und ein 2*7*5-1 = 69bisschen für die anderen Männer. Im schlimmsten Fall, dass alle 32 Männer auf dem Brett sind, kostet es 7für jeden Mann außer den Königen etwas 12 + 7*30 - 1 = 221 bits. Mit den Anfangsbits 8für den globalen Status haben wir also 229 Bits .


Die erweiterte Version:

Durch die Verwendung von arithmetischer Codierung können wir nicht mit einer arbeiten, lg num_possibilitiessondern ceil(lg num_possibilities)nur mit einer ceilam Ende.

  • 1 bisschen für wessen an der Reihe ist
  • 4 Bits für die vier Rochiermöglichkeiten
  • lg 6Bits für die en passant Möglichkeiten.
  • 6 Bits für den weißen König
  • lg 60 Bits (Worst Case) für den schwarzen König
  • lg 63 Bits (weil ich es nicht so komplizieren möchte, dass ich mir die Schecks anschaue) für die weiße Königin, wobei die Position des weißen Königs verwendet wird, wenn es keine gibt
  • Für jede weitere weiße Königin, ein , 1gefolgt von Bit lg 62, lg 61usw. Bits für ihre Position.
  • Ein 0bisschen.
  • lg 63 Bits (oder weniger, wenn es weiße Königinnen gab) für die schwarze Königin.
  • etc.

Der n-te Mann, der tatsächlich anwesend ist, hat 66-nmögliche Werte. Wenn ein Typ für eine Farbe fehlt, haben wir 66-#men so farBits für die Aufzeichnung verwendet (plus ein Bit für das Trennzeichen). Die Extremfälle sind:

  1. Alle anwesenden Männer, einschließlich mindestens eines nicht beförderten Bauern von jeder Seite. Wir geben 5+lg 6für den globalen Staat, 6+lg 60für die Könige, 29für Trennbits und SUM_{n=32}^{63} lg nBits für Positionen aus. Gesamtsumme: ceil(225.82)Bits. Enttäuschend.
  2. Nur noch unbewegte Bauern übrig. Wir geben 5+lg 6für den globalen Staat, 6+lg 60für die Könige, 29für Trennzeichen aus und 8*lg 63sagen, dass es keine anderen Teile gibt, und SUM_{n=48}^{63} lg nfür die Positionen der Bauern. Gesamtsumme: ceil(188.94)Bits. Besser - indem wir den zweiten Turm, den zweiten Ritter und den zweiten Bischof für jede Seite retten, sind wir ein Stück weitergekommen.

Der schlimmste Fall scheint also 226 Bit zu sein , was einer miesen Einsparung von 3 entspricht.

Wir können es im Durchschnitt definitiv besser machen, indem wir Bauern vor Stücken codieren, da sie auf 48 Felder anstatt auf die vollen 64 beschränkt sind. Im schlimmsten Fall sind jedoch alle Männer auf dem Brett und alle Bauern wurden befördert, denke ich Dies würde am Ende 2 Bit mehr kosten, da wir eine "keine Bauern" -Flagge benötigen würden, anstatt die Männer zählen zu können.

Peter Taylor
quelle
0

Dies ist ein Diskussionsthema in Schachkreisen.

Hier ist ein sehr einfacher Beweis mit 164 Bit https://groups.google.com/forum/#!topic/rec.games.chess.computer/vmvI0ePH2kI 155 wird hier gezeigt http://homepages.cwi.nl/~tromp /schach/schach.html

Über vereinfachte Strategie:

  • Beschränken Sie die Bauern auf den Ort, an dem sie gefunden werden können
  • Begrenzen Sie Armeen, um Originalteile und mögliche Bauernaktionen zu berücksichtigen
  • Denken Sie genau über Aktionen nach und Situationen, in denen Aktionen nicht möglich sind
William Entriken
quelle
2
Nur-Link-Antworten sind keine guten Antworten. Sie sollten die vollständige Antwort in Ihrem Beitrag angeben, nicht nur einige Links zur Antwort. Und wenn Ihre Antwort nicht Ihre eigene ist, sollten Sie Ihren Beitrag wahrscheinlich zu einem Community-Wiki machen.
ace_HongKongIndependence
Post ist original. Hinzufügen von Details zur Antwort.
William Entriken
1
Dies ist ein Beispiel dafür, warum Sie den Inhalt in Ihre Antwort aufnehmen. Der 2. Link ist tot. Ist es das? tromp.github.io/chess/chess.html
mbomb007
-2

Min: 0 Bits

Max: 1734 243 Bits (4,335 4.401 Bits / Platine abgeschrieben)

Erwartet: 351 177 Bits (4,376 4.430 Bits / Platine abgeschrieben)

Da ich die Eingabe und Ausgabe jedoch bestimmen kann, möchte ich, dass ich mich bis zu diesem Punkt für die Codierung der Spielhistorie entscheide. Ein Vorteil ist, dass die zusätzlichen Informationen darüber, wer an der Reihe ist, nicht weitergegeben werden und wer die Fähigkeit hat, sich zu verschließen, wo sie abgeleitet und nicht verschlüsselt werden können.

Versuch 1:

Naiv dachte ich, dass ich jeden Zug in 12 Bits, 4 Tripletts der Form (Start x, Start y, Ende x, Ende y), codieren kann, wobei jedes 3 Bits ist.

Wir würden die Ausgangsposition einnehmen und die Teile von dort wegbewegen, wobei Weiß zuerst geht. Die Tafel ist so angeordnet, dass (0, 0) die linke untere Ecke von Weiß ist.

Zum Beispiel das Spiel:

  e4    e5
 Nf3    f6
Nxe5  fxe5
...    ...

Wäre codiert als:

100001 100010 100110 100100
110000 101010 101110 101101
101010 100100 101101 100100
...

Dies führt zu einer Codierung von 12 m Bits, wobei m die Anzahl der durchgeführten Bewegungen ist

Einerseits könnte dies sehr groß werden, andererseits kann man jeden Zug als eigenes Spiel betrachten, so dass jede Kodierung wirklich m "Schachbretter" kodiert . Wenn Sie dies amortisieren, erhalten Sie, dass jedes "Schachbrett" 12 Bits hat. Aber ich denke, das ist ein bisschen schummeln ...

Versuch 2:

Mir wurde klar, dass jeder Zug des vorherigen Versuchs viele illegale Züge enthält. Also habe ich mich entschieden, nur legale Züge zu kodieren. Wir zählen mögliche Züge wie folgt auf und nummerieren jedes Quadrat so, dass (0, 0) → 0, (1, 0) → 1, (x, y) → x + 8 y. Durchlaufen Sie die Kacheln und prüfen Sie, ob ein Teil vorhanden ist und sich bewegen kann. Wenn ja, fügen Sie die Positionen hinzu, die es zu einer Liste gehen kann. Wählen Sie den Listenindex aus, den Sie verschieben möchten. Addiere diese Zahl zur laufenden Summe der Züge, gewichtet mit 1 plus der Anzahl der möglichen Züge.

Beispiel wie oben: Ausgehend von der Startposition kann sich der Ritter auf Feld 1 als erstes auf Feld 16 oder 18 bewegen. Fügen Sie diese also der Liste hinzu [(1,16),(1,18)]. Als nächstes kommt der Ritter auf Feld 6 und fügt seine Züge hinzu. Insgesamt bekommen wir:

[(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)]

Da wir den Zug (12, 28) wollen, codieren wir diesen als 13 in Basis 20, da es 20 mögliche Züge gibt.

So, jetzt bekommen wir die Spielnummer g 0 = 13

Als nächstes machen wir dasselbe für Schwarz, außer dass wir die Kacheln in umgekehrter Reihenfolge nummerieren (um es einfacher zu machen, nicht erforderlich), um die Liste der Züge zu erhalten:

[(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)]

Da wir den Zug (11, 27) wollen, codieren wir diesen als 11 in Basis 20, da es 20 mögliche Züge gibt.

Jetzt erhalten wir also die Spielnummer g 1 = (11 ⋅ 20) + 13 = 233

Als nächstes erhalten wir die folgende Liste von Zügen für Weiß:

[(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)]

Da wir den Zug (6, 21) wollen, codieren wir diesen als 13 in Basis 29, da 29 mögliche Züge vorhanden sind.

Jetzt erhalten wir also die Spielnummer g 2 = ((13 ⋅ 20) + 11) 20 + 13 = 5433

Als nächstes erhalten wir die folgende Liste von Zügen für Schwarz: [(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)]

Da wollen wir den Zug $ (10, 18) $ (10, 18)

Jetzt erhalten wir also die Spielnummer g 3 = (((19 ⋅ 29 + 13) 20) + 11) 20 + 13 = 225833

Und setzen Sie diesen Vorgang für alle verbleibenden Züge fort. Sie können sich g als die Funktion g (x, y, z) = x y + z vorstellen. Somit ist 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)

Um eine Spielnummer g 0 zu dekodieren , beginnen wir an der Anfangsposition und zählen alle möglichen Züge auf. Dann berechnen wir g 1 = g 0 // l , m 0 = g 0 % l , wobei l die Anzahl der möglichen Bewegungen ist, '//' der Ganzzahlteilungsoperator ist und '%' der Moduloperator ist. Es sollte gelten, dass g 0 = g 1 + m 0 ist . Als nächstes machen wir den Zug m 0 und wiederholen.

Aus dem obigen Beispiel, wenn g 0 = 225833, dann ist g 1 = 225833 // 20 = 11291 und m 0 = 225833% 20 = 13. Als nächstes ist g 2 = 11291 // 20 = 564 und m 1 = 11291% 20 = 11. Dann g 3 = 11291 // 20 = 564 und m 2 = 11291% 20 = 11. Daher g 4 = 564 // 29 = 19 und m 3 = 564% 29 = 13. Schließlich g 5 = 19 // 29 = 0 und m 4 = 19% 29 = 19.

Wie viele Bits werden also verwendet, um ein Spiel auf diese Weise zu codieren?

Nehmen wir der Einfachheit halber an, es gibt immer 20 Züge pro Runde, und im schlimmsten Fall wählen wir immer den größten, 19. Die Zahl, die wir erhalten, ist 19 19 20 m

+ 19 ⋅ 20 m-1 + 19 ⋅ 20 m-2 + ⋯ + 19 ⋅ 20 + 19 = 20 m + 1 - 1 wobei _m die Anzahl der Züge ist. Um 20 m + 1 - 1 zu codieren, benötigen wir ungefähr log 2 (20 m + 1 ) Bits, was ungefähr (m + 1) ∗ log 2 (20) = 4,3219 ∗ (m + 1) ist.

Im Durchschnitt ist m = 80 (40 Züge pro Spieler), so dass die Codierung 351 Bits benötigt. Wenn wir viele Spiele aufnehmen würden, bräuchten wir eine universelle Codierung, da wir nicht wissen, wie viele Bits jede Zahl benötigt

Im schlimmsten Fall, wenn m = 400 (200 Züge pro Spieler), würde dies 1734 Bits zum Codieren erfordern.

Beachten Sie, dass die Position, die wir codieren möchten, auf dem kürzesten Weg angegeben werden muss, um unter Einhaltung der Regeln dorthin zu gelangen. Zum Beispiel benötigt das hier theoretisierte Spiel nicht m = 11741, um die endgültige Position zu kodieren. Stattdessen führen wir eine Breitensuche durch, um den kürzesten Weg zu dieser Position zu finden, und codieren ihn stattdessen. Ich weiß nicht, wie tief wir gehen müssten, um alle Schachpositionen aufzuzählen, aber ich vermute, dass 400 eine Überschätzung ist.

Schnelle Berechnung:

Es gibt 12 Einzelstücke oder das Quadrat kann leer sein, um sie auf einem Schachbrett zu positionieren, ist 13 64 . Dies ist eine enorme Überschätzung, da es viele ungültige Positionen enthält. Wenn wir m bewegt sich in das Spiel haben wir etwa 20 erstellt m Positionen. Wir suchen also nach 20 m = 13 64 . Protokollieren Sie beide Seiten, um m = 64 * log 20 (13) = 54,797 zu erhalten. Dies zeigt, dass wir in 55 Zügen in der Lage sein sollten, jede Position zu erreichen.

Nun, da ich den schlimmsten Fall mit m = 55 und nicht mit m = 400 berechnet habe, werde ich meine Ergebnisse bearbeiten. Um eine Position zu codieren, an der m = 55 ist, werden 243 Bits benötigt. Ich werde auch sagen, dass der Durchschnittsfall bei m = 40 liegt, was 177 Bits zum Codieren erfordert.

Wenn wir das Amortisationsargument von früher verwenden, codieren wir 400 "Schachbretter" in 1734 Bits, so dass jedes "Schachbrett" im schlimmsten Fall 4,335 Bits belegt.

Beachten Sie, dass g = 0 ein gültiges Spiel bezeichnet, bei dem sich die Figur auf dem untersten Feld zum untersten Feld bewegt, das es kann.

Zusätzliche Bemerkungen:

Wenn Sie sich auf eine bestimmte Position im Spiel beziehen möchten, müssen Sie möglicherweise den Index codieren. Dies kann entweder manuell hinzugefügt werden, z. B. indem der Index dem Spiel zugeordnet wird, oder indem ein zusätzlicher "End" -Zug als letztmöglicher Zug in jeder Runde hinzugefügt wird. Dies kann nun die Gegentore der Spieler oder 2 in Folge zur Kennzeichnung der Spieler berücksichtigen, die einem Unentschieden zugestimmt haben. Dies ist nur erforderlich, wenn das Spiel nicht aufgrund der Position mit einem Schachmatt oder einer Pattsituation endete. In diesem Fall ist dies impliziert. In diesem Fall wird die Anzahl der durchschnittlich benötigten Bits auf 356 und im schlimmsten Fall auf 1762 erhöht.

nervös
quelle
1
Ihr Argument "Amortisation" funktioniert nicht. Ziel ist es, eine vom Benutzer vorgegebene Karte zu codieren. Sie können die Kosten für die Codierung dieser Karte nicht auf die 400 Zusatzkarten aufteilen, die Sie möglicherweise auf diesem Weg generieren. (Dies wäre nur in Ordnung, wenn diese 400 Bretter vom Benutzer unabhängig ausgewählt werden könnten und nicht durch die Anforderung, ein Schachspiel zu bilden, eingeschränkt würden.) Außerdem kann ein Schachspiel theoretisch viele tausend Züge dauern , und das OP ist klar darüber, im schlimmsten Fall interessiert zu sein.
Anders Kaseorg
@AndersKaseorg: Sehr wahr. Es kommt wirklich auf das Ziel an. Wenn Sie versuchen, ein ganzes Spiel mit allen anderen Algorithmen zu speichern, werden m * c Bytes benötigt, wobei m die Anzahl der Züge und c die Größe ihrer Ausgabe ist. Wenn Sie also versuchen, ein ganzes 80-Züge-Spiel mit der 160-Bit-Lösung zu speichern, werden 12800 Bit benötigt, während meines nur 351 Bit benötigt. Um der Konkurrenz willen gebe ich zu, dass Sie Recht haben, aber ich dachte, es war eine schöne Eigenschaft zu betonen, da es sehr häufig ist, ganze Spiele und nicht nur Bretter speichern zu wollen.
nervös
Das Ziel ist eindeutig. „Ziel ist es, die kleinste Darstellung eines Schachbretts zu erstellen, mit der (einmal dekodiert) alle Bewegungsmöglichkeiten für einen Spieler in diesem Zug bestimmt werden können. … Ihre Punktzahl ist das Worst-Case-Szenario - maximal mögliche Größe in Bits. ”
Anders Kaseorg
@AndersKaseorg: Ich habe nie behauptet, es sei mehrdeutig. Ich habe mich nur für einen anderen Ansatz entschieden. Um mit meinem Algorithmus das kleinste Board zu finden, brauche ich den kleinsten Pfad, um an diese Position zu gelangen. Zum Beispiel muss ich in dem Spiel, in dem Sie eine Verbindung zu 11741 hergestellt haben, nicht diesem Pfad folgen, wenn uns nur das Spielbrett am Herzen liegt. Um das verknüpfte Spiel zu codieren, finde ich einfach das kürzeste Spiel, das mit 2 Königen auf den Feldern übrig bleibt, die möglicherweise nur 200 Runden oder weniger betragen. Dies kann mit einer Tiefensuche erfolgen.
nervös
Die Verwendung eines kürzeren gleichwertigen Spiels ist in Ordnung, wenn Sie tatsächlich nachweisen können, dass jede Position in 200 Runden oder weniger erreichbar ist (im Moment scheint dies nur eine Vermutung zu sein). Sie müssen auch Schachpositionen mit mehr als 100 legalen Zügen berücksichtigen , es sei denn, Sie können nachweisen, dass sie nicht innerhalb Ihrer Konstruktion entstehen. Das Teilen Ihres Ergebnisses durch die Anzahl der Züge im Spiel ist nach den Regeln dieser Herausforderung immer noch nicht zulässig.
Anders Kaseorg