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!
quelle
Antworten:
Min: 12 Bit
Max:
Durchschn .:
Hatte und dachte letzte Nacht, dass ich es möglicherweise noch kleiner machen könnte.
Das Ergebnis ist eine beeindruckende Größe von 12 Bit !
Was ist also mit K + 1 anderer Art von Stück?
Es gibt 2 mögliche Anordnung des Teilbaums.
Beide ergeben für alle Teile die gleichen Bitgrößen. Damit es keinen Unterschied macht, welchen wir verwenden, werde ich den ersten auswählen.
Also auf König +2 andere Stückarten
Es gibt 5 mögliche Unterbäume (ich werde 1 und 2 verwenden, um anzugeben, welche der Stücke.)
Daher benötigen wir 3 Bits, um den zu verwendenden Teilbaum zu codieren.
Mache noch die Analyse für mehr Stücke
+3 Sonstiges
+4 Sonstiges
+5 Sonstiges
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.
Freq ID verwenden
Seitdem gibt es 164603 Einzelstückfrequenzen .
(+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 .
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: -
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.
Die Startkarte kann in nur 166 Bit (20,75 Byte) codiert werden
Um anzuzeigen, wer sich bewegt, ist nur ein einziges Bit erforderlich
Die Rochade kann in 4 Bits codiert werden.
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
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)
2) Header variabler Länge
Ein kleiner fester 4-Bit-Header
Nächster Block mit zusätzlichen Bits (Wenn noch Rochade möglich ist)
Nächster Block zusätzlicher Bits (falls Bauern vorhanden sind)
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)
Das sind ungefähr 4 Bits pro Stück.
Welche Art von Stücken sind auf der Tafel vorhanden?
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.
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
81 Bits insgesamt
Lassen Sie uns ein Beispiel geben, dass nur noch Könige übrig sind
Alles zusammen
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.
Wenn Sie darüber nachdenken, ist es vielleicht besser, nur die 2 Bits in den Header-Block aufzunehmen.
quelle
1111
für "no en passant possible" oder ansonsten die Spalte als Binärzahl).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:
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.)
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:
Alles zusammenfassen:
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):
oder hexadezimal:
quelle
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:
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 .
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:
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:
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.
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.
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:
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:
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:
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.
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.
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.
quelle
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.
quelle
sum_{i=0}^{15} sum_{j=0}^{15} 62! / (i! j! (62-i-j)!) < 2^87.45
.166 Bits
1
bit: wessen an der Reihe ist es?2
bits: 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.585
bits: 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?lg 451366131803622235200 ~= 68.613
um 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) = 166
Bits 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:
Wir können auch die Anzahl der Permutationen berechnen, vorausgesetzt, ein Spieler hat
N
Männer und nicht mehr alsP
beförderte Bauern: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:
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:
quelle
<
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.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.
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:
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).
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:
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).
quelle
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):
Das erste Feld (Stückplatzierung) wird analysiert
Produzieren:
Feld eins: Kodiere den Ort der Könige (12 Bits):
Feld zwei: Teile kodieren (bis zu 5 Bits pro Stück):
Feld drei: aktive Farbe (1 Bit)
Feld 4: Verfügbarkeit der Rochade (4 Bits)
Fünftes Feld: en passant (null oder drei Bits)
Naiver Worst-Case 200 Bit
QRRBBNN QQQQQQQQ
- 75 Bitsqrrbbnn qqqqqqqq
- 75 BitsTatsä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 Bitsqrrbbnn qqqq
- 55 BitsAm 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:
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.quelle
PPpp
=>QQq_
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:
Die nächsten 32 Bytes werden verwendet, um jede Schachfigur in einer vordefinierten Reihenfolge darzustellen
, 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)
quelle
256242 BitsHier 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:
Dann eine Folge von 12 Bits, die die Positionen der Könige darstellen.
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:
Und die Ziffern in Basis 9:
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.
quelle
13^64 * 9
ist 239,99 und spart 11 Bits. Sparen Sie mehr, indem Sie Königspositionen separat codieren.? 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.
1
Dies bedeutet, dass dieses Stück direkt neben dem vorherigen liegt,0xx
zum Überspringen von 1 bis 3 Stücken,000xxx
zum Überspringen von 4 bis 10 Stücken,000000xxxx
für 110000000000xxxxx
bis 25 Stücken und für 26 bis 56 Stücken und schließlich000000000000000xxx
fü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.
quelle
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:
Vor jedem Stückcode können zwei Bits stehen, um anzuzeigen, zu welchem Team er gehört (
10
für Weiß,11
für Schwarz).0
kann 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 übernehmena1, 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
: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.
quelle
11001
MittelB'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)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.
quelle
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.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.
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.quelle
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 ist4
Bits für die vier Rochiermöglichkeiten3
Bits 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: zBPpPPpPPp
hat fünf anfälligeP
s). 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 wirceil(lg 6) = 3
hier 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.
6
Bits: Position des weißen Königs. (Garantiert auf dem Brett zu sein).6
Bits: 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).6
Bits: 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.1
Bit gefolgt von 6 Bits für die Position.0
bisschen.0
Bit.Das kostet ein
12
bisschen für die Könige und ein2*7*5-1 = 69
bisschen für die anderen Männer. Im schlimmsten Fall, dass alle 32 Männer auf dem Brett sind, kostet es7
für jeden Mann außer den Königen etwas12 + 7*30 - 1 = 221 bits
. Mit den Anfangsbits8
fü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_possibilities
sondernceil(lg num_possibilities)
nur mit einerceil
am Ende.1
bisschen für wessen an der Reihe ist4
Bits für die vier Rochiermöglichkeitenlg 6
Bits für die en passant Möglichkeiten.6
Bits für den weißen Königlg 60
Bits (Worst Case) für den schwarzen Königlg 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 gibt1
gefolgt von Bitlg 62
,lg 61
usw. Bits für ihre Position.0
bisschen.lg 63
Bits (oder weniger, wenn es weiße Königinnen gab) für die schwarze Königin.Der n-te Mann, der tatsächlich anwesend ist, hat
66-n
mögliche Werte. Wenn ein Typ für eine Farbe fehlt, haben wir66-#men so far
Bits für die Aufzeichnung verwendet (plus ein Bit für das Trennzeichen). Die Extremfälle sind:5+lg 6
für den globalen Staat,6+lg 60
für die Könige,29
für Trennbits undSUM_{n=32}^{63} lg n
Bits für Positionen aus. Gesamtsumme:ceil(225.82)
Bits. Enttäuschend.5+lg 6
für den globalen Staat,6+lg 60
für die Könige,29
für Trennzeichen aus und8*lg 63
sagen, dass es keine anderen Teile gibt, undSUM_{n=48}^{63} lg n
fü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.
quelle
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:
quelle
Min: 0 Bits
Max:
1734243 Bits (4,3354.401 Bits / Platine abgeschrieben)Erwartet:
351177 Bits (4,3764.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:
Wäre codiert als:
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.
quelle