En küçük satranç tahtası sıkıştırma


38

Satranç tahtasını kodlayan ve kodunu çözebilecek bir algoritma veya program yazın. Amaç, o sırada bir oyuncunun tüm hareket imkanlarını belirlemek için kullanılabilecek (bir kez kodu çözülmüş) kullanılabilecek bir satranç tahtasının en küçük gösterimini yapmaktır.

Kodlamanın şunları göstermesi gerekir:

  • Kimin sırası.
  • Oyuncunun her iki yanında kale olup olamayacağı.
  • Oyuncunun pasaport yapıp yapamayacağı ve eğer öyleyse, piyonlarından hangisi?
  • Tüm parçaların pozisyonları.

Döküm yapmayla ilgili önemli not: Eğer beyazlar krallarını bir tur döndürür, sonra bir sonrakini geri alırlarsa, bundan sonra iki taraftan da kale yapamayacakları açık olmalıdır. Sol ya da sağ kale taşını oynatırlarsa aynı şey geçerli olurdu. Oyun tahtası görsel olarak iki tur öncekiyle aynı durumda olsa da oyun durumu değişti. Daha fazla bilgi burada: http://en.wikipedia.org/wiki/Chess#Castling

En-passant ile ilgili önemli not: Bu aynı zamanda dönüşe duyarlı bir hareket. Daha fazla bilgi için kuralları okuyun. http://en.wikipedia.org/wiki/Chess#En_passant

Giriş ve çıkışı gerektiği gibi belirleyin. Kimin en çok sıkıştırabileceği büyük aksesuarlar!

Puanınız en kötü senaryo olarak belirlenmiştir - bit cinsinden mümkün olan maksimum boyut. Bu sayıyı nasıl hesapladığınızı ve hesapladığınızı gösterdiğinizden emin olun. En küçük kötü durum için ateş et!


Ne demek "bitsel"?
Peter Taylor

Bu en küçük kod mu yoksa sıkıştırılmış mı? En sıkıştırılmış olan daha ilginçtir.
Justin

Açıklığa kavuşturmadığım için üzgünüm. Bitsel olarak, yalnızca bit olarak çalıştırmayı gerektiren bitler olarak göstermeye başlarsanız, sıkıştırabilirsiniz. Benim açımdan zayıf kullanım. Ayrıca en sıkıştırılmış, en küçük kod değil.
Seltzer

1
@GeekWithALife Evet, aynı anda tahtada 18 kraliçe bulundurmak mümkün. Bu linki takip edin ve bir örnek için oynatma düğmesine tıklayın.
pembemsi ossifrage

1
@ AJMansfield, bu yaklaşık 28 kişiden oluşan panolar için faydalı olabilir, ancak hedefin yaklaşık 50 biti olan 32 kişiden oluşan panolar için 117 bitin bol olduğunu hesaplarım. Buradaki komplikasyon, bir kez 32 erkeğin altına düştüğünüzde, promosyon bir oyuncuya daha fazla piskopos verebilir.
Peter Taylor

Yanıtlar:


27

Min: 12 bit
Maksimum:
Ort:

Dün gece düşündüm ve daha da küçük hale getirebileceğimi düşündüm.

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)

Sonuç, etkileyici bir şekilde 12 bit !

Peki ya K +1 diğer parçalardan ne haber?

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

Alt ağacın 2 olası düzenlemesi vardır.

   /\      /\
  +  K    K  +

Her ikisi de tüm parçalar için aynı bit boyutlarına neden olur. Bu yüzden kullandığımızın hiçbir önemi yoktur, ilkini seçeceğim.

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

Böylece King +2 diğer parça tipleri

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

5 olası alt ağaç vardır (hangisinin parça olduğunu belirtmek için 1 ve 2'yi kullanacağım.)

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

Bu yüzden hangi alt ağacın kullanılacağını kodlamak için 3 bit gerekir.

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

Hala daha fazla parça için analiz yapıyorum

+3 Diğer

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

+4 Diğer

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

+5 Diğer

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

Max: 208?


Tüm bu alt ağaçları 9 bit olarak kodlamak mümkün mü?

Olası tüm alt ağaçları toplarsak, 392 olası alt ağacı alırız.

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

Frek ID Kullanımı

O zamandan beri 164603 eşsiz parça frekansı .

Log2( 164603) = 17.3286110452
             ~ 18 bits

0
 0000 0000 0000 0000 00  Freq ID

(+000) (+00) Döküm

Maks: = 204 bit


rev 3

Min: 82 Maks: 199 Ort: 160

Sonunda maksimum bit boyutunu bulmak için bazı analizler yaptı. Benzersiz parça frekanslarının her biri için en uygun kodlayıcı kodlaması ile .

               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 

Bu, piyon sayısının birden fazla olması durumunda En-Passant sütunun bit ettiği olası en kötü boyut olduğuna dikkat edin. Bu piyonların renkleri ve pozisyonlarından bağımsız olarak, bazı panoların 3 bit daha küçük olma potansiyeli vardır.

Ayrıca tahtanın boyutu için sadece 144 farklı boyut (En kötü durum) vardır.


75 - 216 bit (v2) v1 Minimum boyut 98 bit'tir (12.25 bayt), sadece tahtadaki iki papaz.

Maksimum boyut yalnızca 216 bit'dir (27 bayt.) Çoğunlukla: -

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

Ortalama olarak boyut yaklaşık 157 bit (19.625 bayt) olacaktır.

parçalar

Tahtayı kodlamak için ikili bir ağaç kodlama şeması kullanıyorum. Boş bir kare, 32 ila 62 görünüm arasında en sık görülen alandır. Sonra piyonlar, sonra Rooks, Şövalyeler, Piskoposlar ve en az sık olan Kraliçe ve Kral.

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

Başlangıç ​​kartı yalnızca 166 bit (20.75 bayt) olarak kodlanabilir

  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

Kimin hareket ettiğini göstermek için sadece tek bir bit sürüyor

0-> Black , 1-> White

Döküm 4 bit olarak kodlanabilir.

 B  W
LR LR
00 00

Bu yüzden 171 bit kullandım (21.375 bayt)

En-Passe sadece 16 bit (2 byte) olarak kodlanabilir

Toplamda bu 187 bit (23.375 bayt).

Yerleşim

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

Henüz bir kod yazılmadı.

Kullanılmayan bitlerin 3 tanesine dikkat edin. Yani maksimum 213 bit .


Olası İyileştirmeler

1) Başlık bloğu formunu 24 ila 8 bit düşürdü (@Peter Taylor önerisiyle)

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

2) Değişken uzunluk başlığı

Küçük bir 4 bit sabit başlık

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

Ek bitlerin bir sonraki bloğu (Eğer döküm hala mümkün ise)

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

Bir sonraki ek bit bloğu (piyon varsa)

000--> En-Passant column Position

Şimdi bir değişken uzunluk başlığım 4 - 11 bit var


3) Tahtada hangi parçaların kaldığına bağlı olarak farklı bir kodlama şeması kullanın.

Tahtadaki hangi parçalara ve orada sıklığa bağlı olarak ağaç kodlamasını değiştirerek.

Oyun sonu durumu için olası bir kodlama (Piyon yok)

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

Hangi parça başına yaklaşık ~ 4 bit.

Tahtada hangi tip parçalar var?

RBNQK Permutation
11111 (11111)

Permütasyon Değişken uzunluk 0-5 bittir. Sadece bir tip parça kalmışsa, onu dahil etmeyin.

Ağaç için hangi parçaların kullanılmasına izin verilir? Bu, yukarıdaki örnekteki parça sayısının faktörüdür, kodlanabilen 120 olası permütasyon 5 adettir.

 #    !  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.

Boş kareler ve renk için ek bitler olduğunu unutmayın.


Örnekler

Sadece QK sola bir örnek verelim

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

Toplam 81 bit


Hadi sadece krallara bir örnek verelim

 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

Hepsini bir araya getir

 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

Bu yüzden board için en küçük kodlamayı 75 bit (9 bit 3 bit) olarak hesaplarım.

Yine de, bu kodlama düzeninin maksimum boyutu nasıl etkilediğini hesaplamak için henüz.


İyileştirme 4

Döküm için bit sayısını sadece 2 bit olarak azaltın. Sadece sıran oyuncu için oyun.

 0 Castling possible (from header block)
 LR 
 00

Bunu düşünerek, sadece başlık bloğuna 2 bit eklemek daha iyi olabilir.


Passant için 16 bit gerekmez. En fazla bir piyon geçen turda taşındı, bu yüzden dört bit yeterli (örneğin 1111, "mümkün değil" ya da başka bir ikili sayı olarak sütun).
Peter Taylor

Piyonlar neden ağaçta daha iyi bir pozisyon alıyor? Genel durumda en yaygın olanlarıdır, ancak aşırı durumlarda R / B / N 10 kez görünebilir.
Ocak'ta ugoren

@ PeterTaylor, aslında 3 bit en passant için yeterli. Yalnızca siyah bir 5. derece piyonu olan sütunları sayarsanız (beyaz hamle varsayarak), 8 geçersiz hale gelir.
Ocak'ta ugoren

1
En kötü durumun gerçekten mümkün olmadığını unutmayın. Promosyon yakalama olmadan mümkün değildir (2 promosyon için en az bir yakalama gereklidir).
Ocak'ta ugoren 9

2
64 konumu kodlamak için not edin (beyaz veya kara kral için) 6 bit gerekir (2 ** 6 = 64).
lambruscoAcido

17

192 bit (en kötü durum)

İşte keyfi piyon promosyonlarıyla başa çıkması gereken ve hiçbir zaman 64 + 4 × 32 = 192 bit'ten daha fazlasını gerektirmeyen çok basit bir depolama şeması:

  • İlk 64 bit , parçaların nerede olduğunu söyleyen bir bitboard depolar (ancak ne olduklarını değil ). Yani, satranç tahtasının her bir karesi için bir bit saklıyoruz (a1 karesinden başlayarak, sonra b1, c1, vb. Kareye kadar h8'e kadar), boş bir karenin 0, işgal altındaki kareleri 1 ile temsil ettiği şekilde.

  • Ardından, bit tahtasında dolu olarak işaretlenmiş karelerin her biri için, o karede parçayı kodlayan 4 bitlik bir uç saklıyoruz. Dört bitin ilki, parçanın rengini kodlar (0 = beyaz, 1 = siyah), kalan üç bit ise parçanın türünü kodlar:

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

    Parça türü

    0 = (normal) piyon
    1 = (normal) kale
    2 = şövalye
    3 = piskopos
    4 = kraliçe
    5 = kral (sonraki oyuncuya geçecek)
    6 = kral (diğer oyuncuya ait)

    Hangi oyuncunun sırasını değiştireceğini belirlemek için kullanılan kralın kodlamasını not edin. (Aslında, tahtada her zaman iki kral bulunduğundan, 5 ve 6 kodlarının dört kombinasyonuna izin verdiğimiz için, burada ikinci bir bilgiyi kolayca kodlayabiliriz.)

    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                     |
    +----+----+--------------------------------+
    

    Passant ve castling kuralları için gerekli olan ekstra bilgileri kodlamak için, göründüğü satıra bağlı olarak bir piyon veya kale anlamına gelen bir ek parça türü daha tanıtıyoruz:

    7 (satır 1 ve 8’de) = hiç hareket etmemiş ve kralı da hiç hareket etmemiş ve bu nedenle oyuncu seçimi için uygun olan bir kale
    7 (4. ve 5. sıralarda) = iki kareyi daha ilerleten bir piyon ve bu nedenle passant olarak yakalanabilir

Hepsini bir araya koy:

     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) |
    +---+---------------------------------------------+

Tahtanın durumunu kodlamak için gerekli toplam bit sayısı, bu nedenle gemideki parçaların 64 + 4 × adedidir. Tahta üzerinde asla 32'den fazla parça olamayacağından, bu kodlamanın maksimum uzunluğu 192 bit'dir.

Örneğin, yukarıda açıklanan kodlamayı kullanarak, tahtanın başlangıç ​​durumu şu şekilde kodlanır (boşluk için eklenmiş boşluk):

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

veya, onaltılık olarak:

FFFF 0000 0000 FFFF 7234 5327 0000 0000 8888 8888 FABC EBAF

2
"sadece iki kareye sahip olan piyon" ve "hiç hareket etmemiş olan kale", aynı durum alanını paylaşabiliyorlardı çünkü üzerinde bulundukları sıraya bağlı olarak birbirini dışlıyorlardı. Ekstra serbest durum, "sırasını veren renk kralını" kodlamak için kullanılabilir; Bu şekilde sarkan şeyden kurtulabilmelisin.
FireFly

Ayrıca, bit tahtası için yalnızca 63 bit depolayarak ve kodlanan kişi sayısından son biti çıkartarak tartışmasız bir şekilde tasarruf edebilirsiniz. (Bana bunun hile yapıp yapmadığı belli değil, çünkü bit dizisinin uzunluğunun harici kodlamasını gerektiriyor). Ve erkekler için 6 ve 7 durumlarını atlarsanız, 6 ^ 32'ye kadar kodlamanız gerekir; bu da 82.7 bit; 83'e yuvarlayarak, 6 ve 7 durumlarını kullanarak 13 bit tasarruf sağlıyor ve aynı bilgiyi yalnızca 8 bit olarak kodlayabilirsiniz.
Peter Taylor

Teşekkürler, @FireFly! Önerinizi yerine getirdim. (Elbette Peter Taylor'ın önerisi daha da verimli, ama şimdiye kadar kullanmadım, çünkü şu anki programın basit bir ikili kodlamasını seviyorum. Her zaman ayrı bir giriş olarak sunabilirsiniz ...)
Ilmari Karonen

Tamam - bu biraz karışık. Ama beni dinle. Bir dönüş göstergesine 1 bitlik bir vuruş yaparsanız, kralı piyon1 olarak adlandırdığım bir parça ile değiştirebilirsiniz . Piyonu piyon0 olarak değiştirin. Şimdi, ne zaman (en savunmasız savunmasız) bir piyon varsa - bir sonraki parça hakkında da bir miktar bilgi edinirsiniz (piyon0 için 0 veya piyon1 için 1). 16 piyon olduğundan, dönüş göstergesi için 16 bit daha az 1 kazanırsınız. Ne zaman en passant'a karşı savunmasız bir piyon varsa, ondan sonra bir bit geri eklemelisiniz. Ancak en passant'ın hemen olması gerektiği gibi, asgari kazancınız 14 bittir.
user5957401

Piskopos gibi bir şeyle de benzer şeyler yapabilirsiniz. 'Özel bir bölgede' olmayan bir piskoposunuz olduğunu varsayalım (köşelerinde 10 nokta ve yanında orta sıra) özel olarak işaretlenmiştir. Çünkü onun yerini biliyorsun - onun bir piskopos olduğunu biliyorsun. Şimdi iki piskoposunuz var ve her birine bir sonraki parçada 0 veya 1 verebilirler. Bu, 4 bit daha verir - ama en kötü durumda tüm özel bölgelerde piskoposlar vardır ve kazançları yoktur.
user5957401

14

160 bit en kötü durum

Önceki cevabımı 22 bayta gönderdikten sonra 21 bayta indirebilir miyiz diye merak etmeye başladım. Ancak Peter Taylor’ın şaşırtıcı 166 baytını gördüğümde “Bekle, beş tane 32 bitlik kelime mümkün olabilir!” Diye düşündüm.

Bu yüzden, çok fazla düşünceden sonra, şunu buldum: 159.91936391 bytes (oldukça sıkı bir uyum!) Bu sıkıştırma seviyesi oldukça karmaşık bir programa ihtiyaç duyacaktır, ancak makul bir zamanda nasıl çalıştırılacağı hakkında düşündüm.

Bu uzun bir yazı olacak, bu yüzden lütfen yanımda ol, bugün elimden geleni göndereceğim ve yakında birkaç kod ekleyeceğim.

Yani, işte nasıl yapılacağı:

En Passant ve casting yasadışı konumlarla kodlanmış (0 bit)

En Passant

Diğer cevaplarda belirtildiği gibi, en passant'a karşı savunmasız bir piyonun dayanabileceği maksimum 5 olası kareler vardır. Bunlar, sırası olan oyuncunun piyonlarının yanındaki karelerdir.

Bunu kodlamak için, en passant'a karşı savunmasız olan piyon, ilk veya son satırdaki karelerden birinde bulunanlarla değiştirilir. Bu bir erkek ya da boş bir kare olabilir. Bu, piyonlar bu sıralarda olamayacağından yasadışı bir pozisyon oluşturur. Kod çözücünün, en güncel bilgileri çıkararak piyonu doğru konumuna getirmesi gerekir.

Bunun döküm kodlama işlemine müdahale etmemesi için, oyunun başında kralların durduğu karelerin rahatsız olmaması ve pasif kodlama prosedürünün kralları yan yana koymaması önemlidir. bu yasadışı bir kral pozisyonu olurdu. Bu noktaların ikincisini karşılamak için, enkoderin en passant piyonu hangi kare ile değiştirdiği konusunda iki seçeneğe sahiptir. En fazla 5 piyonun her biri için ilk tercih edilen kare A8, B8, C8, G8, H8'dir. İkinci seçenek: A1, B1, C1, G1, H1.

rok yapma

Kale kalmasına izin verilen bir kral, tanımı gereği hala ilk karesinde. Beyaz kralın ilk karesinde, siyah kralın dayanabileceği, 58'inin yasal olduğu toplam 63 kare var (beyaz kralın hemen yanına taşınmasına izin verilmiyor çünkü kendisini kontrol altına alacak). Beyaz kralın kaleye kalmasına izin verilirse, sol kalesine, sağ kalesine veya her ikisine birden kale yapmasına izin verilir. Böylece beyaz kralın kale kurabileceği 3x58 = 174 olasılık, siyah kralın kale yaratacağı başka bir 174 ve her ikisinin de kale olabileceği 3x3 = 9, toplam 357.

İki kralın bitişik meydanlarda olduğu 420 yasa dışı düzenleme vardır: beyaz kral köşedeyken 3x4 = 12, kenardayken 5x24 = 120 ve başka bir meydanda iken 8x36 = 288. Bu nedenle, olası tüm döküm olasılıklarını kodlayacak kadar kolay yasadışı pozisyonlar vardır.

En az bir kralın kaleye girmesine izin verilirse, kodlayıcı döküm verilerini ve bu tablolarda kaleye izin verilmeyen kralların konum verilerini arar (veya alternatif olarak burada belirtmeyeceğim bir algoritma kullanır) ve yasadışı İki kralın konumu. Daha sonra kralları bu meydanlarda olanlarla değiştirirdi.

Bunun en passanttan önce kodlanıp kodunun çözülmesi önemlidir, aksi takdirde bazı potansiyel girişimler vardır.

karşılaştırma

Şimdiye kadar hiç bit kullanmadım! Peter'ın cevabına baktığımda, hala kodlamak için aşağıdakilere sahibim:

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

Bu, 29 erkeğin en kötü vakası için (bakınız Peter'ın cevabı). Aşağıda, ** ile işaretlenen her iki noktada da marjinal bir iyileşme (en azından 29 erkek için) nasıl yapacağımı göstereceğim.

Hangi kareler işgal / sıra kimde?

Hangi karelerin işgal edildiğini kodlamanın kolay yolu 64 bitlik bir ızgaradır. Bu da bize kaç tane karenin işgal edildiğini gösteriyor. Bununla birlikte, bir miktar israf edicidir, çünkü 32'den fazla karenin işgal edilmesi mümkün değildir. Benim çözümüm, Beyaz dönüşünde işgal edilen kareleri kodlamak için 1'leri, Siyah dönüşünde ise 0'ları işgal edilen kareleri kodlamak için kullanmak. Şimdi tüm kombinasyonlar kullanılıyor ve atık yok.

Böylece dönüşü saklamak için biraz tasarruf ediyoruz: 32 1'den daha az, beyaz dönüş, 32'den fazla, siyah dönüş. Tek belirsiz durum, bütün erkekler tahtadayken ve 32 1 ve 32 0 olduğu zamandır. Bu nedenle, sadece bu durum için ekstra bir bit gerekir. Bir yakalama gerçekleşene kadar herhangi bir terfi olamayacağından, bu ekstra bit, genel olarak en kötü olayı etkilememektedir (3 kişi yakalanıp 29 kişi kalmaktadır).

Kareleri işgal eden erkeklerin rengi

Yukarıdakilerden kaç kişinin olduğunu biliyoruz. Pascal'ın üçgeninin aşağıdaki özü, siyah ve beyazın farklı dağılımları için kaç olasılık olduğunu anlatıyor. Örneğin, 3 erkek için, olasılıklar: 3 siyah adam (1 permütasyon) 2 siyah, 1 beyaz, (3 permütasyon), 1 siyah, 2 beyaz (3 permütasyon), 3 beyaz (1 permütasyon.) Toplam 2 3 = 8. Genel olarak, daha az sayıda erkek için 2 n olasılık vardır. Bununla birlikte, tüm siyah ve tüm beyaz olasılıklar yasa dışıdır (en azından her bir tarafın kralı tahtada olmalıdır), bu nedenle asıl yasal izin sayısı 2 n -2'dir (Pascals üçgeni üzerindeki 1'leri dikkate almayın).

Toplamda 16'dan fazla erkek için, tahtada her rengin 16'dan fazla erkek bulunamaması konusunda ek bir kısıtlama vardır. Bu nedenle, 32 erkeğin de tahtadayken her birinin 16'sı olmalı ve toplam sayı olasılıkları 2 32'den biraz daha az olan 601080390'dır .

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

Bu pascals üçgeni ekstresinin "sıralarını" toplayarak, olasılıkları bulmak mümkün olabilir (bunun için tablonun NE-SW köşegenlerini kastediyorum, çünkü uygun sunum için üçgeni saat yönünün tersine döndürdüm. sırayı kodlamak için, işgal edilmiş kareler ve erkeklerin rengi aşağıdaki gibidir:

En fazla 25 erkek: 64'ten biraz az (erkek sayısı)
25'ten fazla erkek için:

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

İki renk için hangi erkekler ve hangi sırayla?

Önceki cevaplara göre, bir yakalama gerçekleşene kadar hiçbir piyon terfi ettirilemez, çünkü her piyon aynı kolondaki zıt rengin bir piyonu tarafından bloke edilir. Peter'ın cevabı (bir üst sınır olarak), her yakalamanın yakalanan taraf için bir promosyona ve yan yakalama için iki tanesine yol açabileceğini düşündü. Ancak bunu birkaç vakaya bölebiliriz:

  1. Siyah piyon, beyaz piyonu yakalar: Şimdi, yakalama piyonunu, şimdi farklı bir sütunda olduğu gibi yükseltmekte özgürdür. Aynı sütunda meslektaşı da teşvik edebilir. Beyaz piyonun orijinal sütunundaki siyah piyon da teşvik edebilir. 3 promosyona izin veren tek durum budur.

  2. Siyah piyon bitişik sütunda beyaz piyonun arkasına gider ve daha sonra arkasındaki beyaz parçayı (piyon hariç) yakalar. Bu, yakalama piyonunun ve orijinal sütunda bulunan beyaz piyonun tanıtılmasını sağlar. Her taraf için bir promosyon.

  3. Beyaz piyon (piyon dışında) parça tarafından yakalanır. Bu normalde yalnızca Siyah için bir promosyona izin verir. Bunun tek istisnası, aynı sütun üzerinde hareket eden birçok pençenin neden olduğu bloklanmış bir piyon oluşumunu serbest bırakmasıdır.

Bu nedenle, temel bir durum olarak, her yakalamanın her iki taraf için de birer tanıtım yapabileceğini düşünebiliriz. Yakalanan adamın bir piyon olması durumunda, yakalama tarafı için ek bir terfi olabilir.

Peter'ınkine benzer bir program yazdım. Biraz kırıcıdır, ancak önemli bir ilavesi vardır: bir oyuncu normal 8 piyondan daha azıyla başladığında mümkün olan permütasyon sayısını hesaplayabilir. İşte program tarafından üretilen bazı veriler:

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

8 piyon, 15 erkek, 0 terfi gibi bir vaka için permütasyon sayısının 8 piyon 16 erkek, 0 terfi için sadece biraz daha düşük olduğunu görebiliriz. Bununla birlikte, 7 piyon, 15 erkek, 0 terfi (ele geçirilen adamın kesinlikle bir piyon olduğunu düşünmekle aynıdır) gibi bir durum düşünürsek, permütasyon sayısının yaklaşık yarısını alırız.

Öyleyse, Siyah'ın 16 erkek ve beyazının 15 erkek olması durumunda, Siyah için 2, Beyaz için bir promosyon için üst sınır tahminini düşünebiliriz:

5383778400 x 660810150 = 3.55766E+18 possibilities

Ancak aşağıdaki şekilde devam edersek daha iyisini yapabiliriz.

A. Beyazın kaybettiği herhangi bir türden olabileceğini varsayarak, her biri Siyah Beyaz için bir terfi düşünün:

843242400 x 660810150 = 5.57223E+17 possibilities

B. İki terfi varsa, yalnızca piyonunu kaybettiği Beyaz için olanlarla çarpılarak Siyah için ek olasılıkları düşünün.

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

Bu ikisini birlikte ekleyerek, 3.55766E + 18'den daha küçük bir sayı olan 2.25072E + 18'i elde ediyoruz. 3 kişiye kadar olan tüm olasılıklar (kalan 29 kişi) aşağıda listelenmiştir.

(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

Yani bir tarafın en kötü durumu için 15 erkek, diğerinin de 14 erkek için 67.804 bit'e ihtiyacımız var.

Bunu, hangi karelerin ve hangi rengin seçildiğini belirtmek için gereken 92.116 bit'e ekleyerek toplam 67.804 + 92.116 = 159.92 bit elde ediyoruz.


1
@Einacio'ya ondalık virgülümü ondalık virgülle değiştirdiğim için çok teşekkürler. Tablolarımı bir İspanyol bilgisayarda Excel'de yaptım ve bu ilanı göndermek büyük bir işti, bu yüzden bunu düzeltmek sonradan bıraktığım bir şeydi. Dediğim gibi, henüz bu yazıyı tamamlamadım, zamanım olduğunda permütasyon sayma programımı ve kodlama / kod çözme ile ilgili bazı kod parçalarını ekleyeceğim. PS. Hiç bir fikrim yoktu, o kadar çok insan bunu okuyordu :-)
Level River St

Sonunda, demek istediğin, okuyucularda biraz sintiğe yol açabilecek bitler yerine, baytları almayı başardın
masterX244

13

177 bit en kötü durum

Bu algoritma, neredeyse basit olmamakla birlikte, sadece 2 kral kaldığında 177 bitlik en kötü durum (pratikte 184b = 23B), 13b (16b = 2B) en iyi durum senaryosu verir.

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

Çok hoş. Bunu, 14-105 bitlerini (92 bit) multinom katsayılarını temel alan bir kodlamayla değiştirerek daha da verimli yapabilirsiniz. sum_{i=0}^{15} sum_{j=0}^{15} 62! / (i! j! (62-i-j)!) < 2^87.45.
Peter Taylor

Değiştireceğim tek şey, kuşatıcı bölge için daha basitleştirilmiş bir sürüm oluşturmak. Örneğin: 30'u 5 numaralı tabanda kodlarsanız ve maksimum 5 enpassant konumu varsa, o zaman 5 ^ 31 <2 ^ 72 olabilir. Sanki onları enpassant (13) ve enpassant olmayan (59) 'da böldünüz, fakat ekstra karmaşıklık olmadan.
Alin Stoian

Bunu yapmak aslında 1 ekstra bit kullanır. Sebep şu ki (en kötü durum) 5 elverişli olasılık olabilir, ancak yine de "elverişsiz" olma ihtimalini, yani 6. durumu açıklamam gerekiyor. Ekstra 1 bit bu durumda mümkün olan enpassantın mümkün olup olmadığını beyan eder (ve bu yaklaşımla, enpassant bloğu atlayan 30 parçanın kodlanmasıyla daha basit bir yaklaşım kullanabilirim ve enpassant bloğu kontrol etmek için ayrı ayrı 3 bit kullanabilirim) ayrıca +1 bit kullanımına yol açar). Aşağıdaki 5. sıra, 5 potansiyel işgalciye (Beyaz'ın sırası) olanak tanıyacaktır: BWBBWBBW
FIQ

Evet haklısın.
Alin Stoian

7

166 bit

  • 1 bit: kimin sırası?
  • 2bit: Hangi döküm seçenekleri açık? (Sorunun yakından okunması üzerine NB, sadece sırası olan oyuncunun döküm seçeneklerini kaydetmek için gereklidir).
  • lg 6 ~= 2.585bit: hangi en passant seçenekleri açık? (Diğer cevabımı görün)
  • lg sum_{i=1}^{16} sum_{j=1}^{16} 64! / (i! j! (64-i-j)! = lg 3629590441720924477681996172 ~= 91.552 bitler: hangi kareler hangi renkteki adamlar tarafından işgal edilir?
  • lg 451366131803622235200 ~= 68.613Hangi erkeklerin ve hangi sırada olduklarını belirtmek için en kötüsü (aşağıya bakınız)

Aritmetik kodlamayı kullanarak (her adımda tekdüze bir dağılım uyguladığımız için) ceil(3 + 2.585 + 91.552 + 68.613) = 166bit elde edebiliriz .

Erkekler için kodlama: Belirli bir rengin kaç erkek olduğunu bildiğimize göre, erkeklerin olası tüm dağılımlarını / çoklu kümelerini kolayca numaralandırabiliriz (örneğin 5 erkekle bir Kral, bir Kraliçe, iki Kale ve bir tane olabilir. Piyon) ve sonra her dağıtımın tüm olası izinlerini düşünebiliriz.

Ancak, karşılıklı bağımlılıkları dikkate alarak daha da iyisini yapabiliriz. Bunu sadece çok basit düzeyde yapıyorum: Kaç tane olası promosyon var? Bir piyon sadece “geçer” hale gelebilir ve üç yolla terfi ettirebilir: yakalar ve farklı bir sütuna geçer; veya karşıt piyonu yakalar ve böylece farklı bir sütuna geçer; veya karşıt piyonu ele geçirilir. Bu nedenle, beyaz için bir yakalama potansiyel olarak beyaz için iki ve siyah için iki geçirilmiş piyon oluşturur.

Promosyonlarda üst sınırların kısmi bir tablosunu oluşturabiliriz:

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

Ayrıca, bir oyuncunun Nerkek olduğu ve Pterfi edilen piyonlardan başka bir şey olmadığı düşünüldüğünde, permütasyon sayısını hesaplayabiliriz :

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

İkisini birleştirerek, her iki taraftaki erkek sayısı göz önüne alındığında her iki permütasyonu belirlemek için gereken bit sayısını alabiliriz:

           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

Tablonun bu bölümünde değilse, her iki tarafın da 8 promosyona sahip olduğunu varsayabiliriz ve hala en kötü durumdan daha iyisini yapıyoruz.

Bunun hala mükemmel bir temsil olmaktan çok uzak olduğunu, çünkü birçok yasadışı pozisyona izin verdiğini unutmayın.

Permütasyon tablosunu hesaplamak için kod:

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();
        }

    }
}

Kralların pozisyonlarını nasıl değerlendiriyorsunuz? Hesaplamada 15 kişi kullanıyorsun ve kral pozisyonları için özel bir parça yok.
Alin Stoian

@AlinStoian, ayy. Programımın çıktı döngüsündense <daha çok vardı <=. Gösterdiğin için teşekkürler. Tahtadaki 32 erkeğin hepsinin özel kasasını kullanarak hala önceki puanı kazanabilirim, ancak şu anda bunu yapmayacağım.
Peter Taylor

İlginç veri! 3 erkekle teorik olarak en kötü durum yakalandı
Level River St

@ steveverrill, gerçekten yapmak istediğim şey, piyon pozisyonlarını ve terfi sayısını bir "blokta" ve ardından parça pozisyonlarını ve değerlerini kodlamak. Ancak, promosyonları dikkate almadan en az 2 ^ 38 piyon pozisyonu var ve bunların verimli bir şekilde sayılması şu ana kadar kaçtı.
Peter Taylor

@petertaylor Tahtada yalnızca 16 kare varsa, 48 kare ile sınırlandırılmışsa, 48! / 32! / 8! / 8! = 29019905518636890 olasılıklarınız vardır. Biraz fazla 2 ^ 54! Bunlardan bazıları yasadışıdır, tahtanın bir tarafındaki tek renkteki tüm piyonlara sahip olamazsınız.
Seviye Nehri St

5

178 bit (bir tutamda 174!) En kötü durum

Merhaba, sadece üniversiteye gelmeden yapmadığım kodlamaya geri dönüyorum. Bu siteyi gördüm ve ilginç göründüğünü düşündüm. Biraz terorik bir kontrol yaptım ve görünen o ki, mükemmel bir algoritma için en az 146 bit gerekiyor, muhtemelen bir kaç tane daha (biraz zamanım olduğunda yorumlarda açıklayacağım).

Neyse, veriyi bu şekilde yapıyorum. Temel kavram 178 bitte gelir, ancak bazı jiggery pokery'lerinde 174'e düşebilir (21 3/4 byte). 175 programlaması biraz daha kolaydır, daha okunaklıdır ve yine de 22 bayt içindedir.

A) , beyaz ve siyah için 6 bit, her: İki kral pozisyonu 12 bit

B) Kalan 62 kareden hangisi dolu? 62 BITS'lik bir matris

C) Kimin sırası? 1 BIT

TOPLAM SO FAR: 75 BITS

D) En Passant. Beyazın hareket sırası geldiğinde, en fazla 5 siyah piyon En Passant yakalanmış gibi görünebilir. Siyah piyon satır 5'de (alttan üste sıfıra başlayarak) ve yanında beyaz bir piyona sahip olmalıdır. Maksimum yakalama sayısının olduğu bir durum şöyle görünür:

BWBBWBBW

5. sıradaki 6 siyah piyon olsaydı, beyazın üzerinde duracak sadece 2 karesi olurdu ve sadece 4 siyah piyonu tehdit edebilirdi, bu yüzden aynı anda En passant'ın tehdidi altında 5 siyahtan fazla piyona sahip olmak mümkün değildi. Bu yüzden , 5. sıradaki (5'e kadar) piyonun hangisinin yanında düşman olan (bu durumda beyaz) piyona sahip olduğunu, son turda 2 kare ilerletildiğini ( veya piyonu yoksa sıfır ) gösteren 1-5 arasında bir sayıya ihtiyacımız var. Bu durumda son dönüşünde bu şekilde hareket edildi.)

E) En fazla 30 işgal edilmiş kareden (krallar dahil değil) ne içeriyor?

Her biri ondalık sayı ile temsil edilen 10 olasılık vardır.

En az anlamlı bit rengi temsil eder.

Dolayısıyla sayılar bile beyaz, tek sayılar siyah.

Siyah beyaz

0/1 Piyonu (veya kale kalmasına izin verilen kale) *

Şövalye 2/3

Piskopos 4/5

6/7

Kraliçe 8/9

* Kale kalmasına izin verilen (ve bu nedenle asla ilk veya son satırdan hiç taşınmamış olan) 6 veya 7 yerine 0 veya 1 ile temsil edilir. Piyonlarla karıştırılamaz çünkü piyonlar ilkinde bulunamaz veya son satır.

Bu, 6 ile çarpabileceğimiz ve En passant kodunu ekleyebileceğimiz 30 basamağa kadar bir ondalık sayı verir. Elde edilen sayı 103 bitin içine sığacak ve yukarıda belirtilen 75'e eklendiğinde 103 + 75 = 178 bit olacak . Aslında, 6 yerine sadece 10 ile çarparsak, kullanılan bit sayısında bir fark olmaz ve kod çözme işlemi daha kolaydır.

Bu 22 bayttan yalnızca 2 bit. Ancak aşağıda açıklandığı gibi 174 bite kadar aşağı itebiliriz.

Herhangi bir parça ele geçirilmemişse, bir piyonun tanıtılması imkansızdır .

Kanıt aşağıdaki gibidir. Beyazın oyunun başından itibaren (örneğin) E sütununda piyonunu tanıtmaya saplantılı olduğunu hayal edin. Bu piyonun karşısında siyah bir piyon var. Bu nedenle bu piyonu tanıtmak için aşağıdakilerden birinin gerçekleşmesi gerekir:

1) Siyah piyon yakalanır.

2) Siyah piyon bir başka parçayı yakalar ve bu yüzden yoldan çekilir.

3) beyaz piyon, D sütunu gibi bitişik bir sütunda bir piyon yakalar.

4) beyaz piyon bitişik bir sütunda siyah bir piyon geçirir (veya geçer) ve daha sonra aynı pürüzlü sütun üzerinde bir parça yakalar ve beyaz piyonun sütunu değiştirmesine neden olur.

Durum 4 en ilginç olanı çünkü E sütununda başlayan ve şu anda terfi için açık bir yolu olan sadece beyaz piyon değil. E sütununda kalan siyah piyon da yükselebilir. Bu nedenle, tek bir yakalama, her rengin bir piyonunun ilerlemesinin yolunu temizleyebilir.

Her neyse, hiçbir piyonun bir parça ele geçirilinceye kadar teşvik edemeyeceği, 30. parçayı saklamak zorunda olmadığımız anlamına gelir. Bunu ortadan kaldırarak halledebiliriz (ya da çıkarma yoluyla, çünkü oyunun başlangıcındaki bütün parça kodları her zaman aynı miktara eklenir = 80.) Küçük bir nokta, karelerin bulunduğu karelerin olmasını sağlamamız gerektiğidir. Oyunun başında durmak ilk tarananlar arasındadır (çünkü eğer son olsaydı, kalenin kale yapıp kayamayacağını bilemezdik.) Bu, 0 satırını tarayarak kolayca yapılır ve sonra 7'den 1'e sıralar: r = 8 - 1 tarama satırı [r mod 8].

Bu yüzden, (B) 'deki bit matrisi bize kaç tane parça olduğunu söyleyecektir (krallar hariç). Eğer tam bir 30 varsa, kodlamada son parçayı yoksay, kod çözücü onun ne olduğunu çözecektir. Şimdi 6 ile çarptığımız ve En Passant koduna eklediğimiz 29 basamaklı bir ondalık sayıya sahibiz. Elde edilen sayı 99 bite sıkılacak ve toplamda 99 + 75 = 174 bit olacaktır.

Örnek olarak İşte gerçek bir pozisyon. White ilk hamlesini yaptı (ileri kralın piyonu) ve Black'in sırası geldi.

rnbqkbnr
pppppppp


    P

PPPP PPP
RNBQKBNR

A) Kralların konumu (Sekizlik beyaz / siyah, 12 bit ): 03 73 = 000011 111011

B) Hangi kareler dolu? Sıfır (alt sıra) satırından sonra diğer tüm satırları yukarıdan aşağıya doğru başlayarak kralları atlayın:

1111 111

1111 111
11111111
00000000
00000000
00001000
00000000
11110111 

C) Siyahın sırası: Dönüş Bit = 1

D) En Passant. Siyah bir piyonun yanında beyaz piyon yok, bu nedenle passantta alınabilecek piyon yok (bu piyon son hamle yapsa bile) D = 0. Sadece yanlarında düşman piyonu olan piyonları dikkate almak yerine, her iki tarafta da yanlarında dost parçaları olmayan tüm piyonları göz önüne alırsak, bu durumda böyle bir piyon olduğu için D 1 olacaktır. piyon gerçekten de son sırayla taşındı.

E) Yine, önce alt sıra, sonra diğer tüm sıralar yukarıdan aşağıya, kralların atlanması ve 0 ya da 1 olarak adlandırılan dört açılı çubukla (normalde piyonlar için ayrılmış sayılar).

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

30. basamak (parantez içinde) atılabilir.

Burada çok belirgin olmasa da, Beyaz'ın ilerlettiği piyon aslında satır listesinin bir ucunda, çünkü satır satır tarıyoruz.

Şimdi verilerimiz, karelerin içeriği için 29 kod ve En Passant koduyla şu şekilde görünüyor:

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

Kod çözme sırasında sağdan sola, kodlama sırasında soldan sağa (ters sıra) tarama yapmak en iyisidir. Bunun anlamı, daha az parça olduğunda daha az sayıya sahip olacağımız ve maksimum tutarlılığı koruyacağımız anlamına gelir (yani, boş alanların / sıfırların seyrek meşgul tahtaların sıkıştırılmasını sağlamak için izlemememelerini, izlememelerini istiyoruz.) Sadece 2 kralımız olduğunda tahtada yukarıda belirtilen 75 bit, artı en iyi veriyi = 3 bit en iyi durumda saklamak için 3 bit olacak. Her ilave parça 3.5 bitin altına hafifçe gelir (2 parça 7 bitte saklanabilir, çünkü 100 <128.)

99 bitlik bir tamsayı 64 bitlik bir tamsayı değişkenine sığmayacak kadar büyük olduğu için pratik bir sorun var, bu da birçok programlama dilinin bunun için destek sağlamadığı anlamına gelir (29-30 basamaklı bir dize gösterimini dönüştüremezsiniz) Bir tamsayıya sayı.) 22 byte kodlamanın kolay bir yolu olarak, her biri 50 bite sığacak (toplam 100 bit) 30 basamaklı bir sayı (29 adet kod + en passant kod) iki adet 15 basamaklı sayıya ayırabiliriz. artı yukarıda belirtilen 75 175 bit'i en kötü durumda yapar.

Yukarıda belirtildiği gibi maksimum sıkıştırma için, 29 ondalık basamak ve En Passant kodu (6 olası değer), yaklaşık 99 bite sığacak (toplam 174 bit için) ancak bu boyuttaki tamsayılar için dilden destek almadan program için karmaşık. 29 renk bitini ayırmak ve parça tipi kodlarla (5 olasılık) ve En passant kodu (6 olasılık) renklerden ayrı olarak çalışmak daha kolay olabilir (70 bit, neredeyse 64 bitlik bir değişkene uyar).


Son adamla iyi numara.
Peter Taylor

5

İşte tam bir çözüm, gerçek en kötü durum 181 bit

Buradaki odağı kolayca anlayabileceğiniz basit bir program

Giriş FEN, burada açılış pozisyonu var, altı alanı var (5 ve 6 yoksayıldı):

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

İlk alan (parça yerleştirme) ayrıştırıldı

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

Üretmek için:

rnbqkbnrpppppppp________________________________PPPPPPPPRNBQKBNR

Birinci alan: kralların konumunu kodlayın (12 bit):

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

İkinci alan: parçaları kodlayın (parça başına 5 bit'e kadar):

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//

Alan üç: aktif renk (1 bit)

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

Dördüncü alan: döküm mevcudiyeti (4 bit)

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

Beşinci alan: en passant (sıfır veya 3 bit)

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

Naif kötü durum 200 bit

  • İki kral yerleşimi - 12 bit
  • Yazı tahtası
    • QRRBBNN QQQQQQQQ - 75 bit
    • qrrbbnn qqqqqqqq - 75 bit
    • Boş kareler - 30 bit
  • Aktif renk - 1 bit
  • Castling - 4 bit
  • En Passant - 3 bit

Gerçek en kötü durum

Her oyuncu diğer parçaları ele geçirmeden tüm piyonların tanıtımını yapamaz . İşte parça yakalamanın entropi etkisi:

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

Yani aslında en kötü durum kurulu:

  • QRRBBNN QQQQQQQQ - 75 bit
  • qrrbbnn qqqq - 55 bit
  • Boş kareler - 34 bit

En kötü durum, paspu için piyon bırakmak yerine tüm parçaları teşvik etmektir.

TOPLAM GERÇEKTEN KASA KODU İLE KABUL 12 + 75 + 55 + 34 + 1 + 4 = 181 bit

FIQ bu basit şemada iki gelişme gösterdi, ancak kodlaması daha zor:

  • Piyonlar oraya gidemediği için 1. ve 8. sıralardaki parça kodlamadan bit 2'yi kaldırın (16 bit tasarruf)
  • Dökme kalıpları kodlamak için piyon kullanın (4 bit tasarruf)

Bu cevapta gösterilmeyen tek kod (kısalık için) şudur: FEN girişini fields ( split /\s/) ve değişken atamalarında kesmek.


Bir oyuncu bütün piyonlarını terfi ettirebilir (Düşman piyonlarını yakalayabildiği için); Qn4QQ / Qb6 / Qq1k4 / Qr6 / Qb6 / Qr6 / Qn4NK / RNB2B1R b - - 0 84
Krzysztof Szewczyk

@KrzysztofSzewczyk, evet yukarıda belirtilen not PPpp>>QQq_
William Entriken

4

Toplam veri ihtiyacı 33 bayt

(Bu yorumdaki birisine teşekkür ediyorum, bunun piyon terfi için işe yaramadı. Bunu çözebildiğimde güncelleyeceğim)

ilk bayt için beş bit kullanıyoruz:

  • ilk bit: oyuncunun sırası, 1 = beyaz
  • ikinci bit: kara kral tarafında kale, 1 = kale olabilir
  • üçüncü bit: kara kraliçe tarafında kale, 1 = kale olabilir
  • dördüncü bit: beyaz kral tarafında kale, 1 = kale olabilir
  • beşinci bit: beyaz kraliçe tarafında kale, 1 = kale olabilir

sonraki 32 bayt, her bir satranç taşını, önceden tanımlanmış bir sırada göstermek için kullanılır.

  • 3 bit: satırı temsil eder
  • 3 bit: sütunu temsil eder
  • 1-bit: en-passant'ı temsil eder, 1 = en-passant olabilir
  • 1-bit: "can-passant" ise 1: 1: hangi tarafın olduğunu gösterir, 0 = sola
    basılmışsa bunun yakalanıp yakalanmadığını gösterir. 0 = yakalanmadı
    (pasaport yapabiliyorsa kesinlikle yakalanmaz)

Bu fikri temsil etmek için bazı C kodları (aslında işe yaramaz)

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;
}

-1, bu ... bir cevap değil
Doorknob

1
Bir piyon sekizinci sıraya ulaştığında ve bir şövalye, fil, kale veya kraliçeye terfi ettiğinde önceden tanımlanmış düzeniniz pek kullanılmayacak .
pembemsi ossifrage

@Doorknob of Snow ok Algoritma üzerinde çalışıyorum, gece biraz geç oldu ve yoruldum, bu yüzden biraz yavaş yapıyorum
ace_HongKongIndependence

Öyleyse niçin bir çözüm bulamadınız?
Doorknob

3
siz insanlar hala bu cevabın saçma olduğunu ve burada değeri olmadığını düşünüyorsanız, devam edin ve silmek için oy verin ve oyunuzu düşürün, hesabımı da silebilirsiniz. Sadece aklımdan geçenleri paylaşmak istiyorum, neden bu kadar kaba olmak zorundasınız?
ace_HongKongIndependence

4

256 242 bit

İşte, bazı yasadışı konumları temsil etmekten dışlamadığı için muhtemelen geliştirilebilecek basit bir sıkıştırma algoritması.

Kart, aşağıdaki gibi 5 bit başlık bilgisi ile başlar:

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

Sonra, kralların pozisyonlarını temsil eden 12 bitlik bir ip.

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

Daha sonra, 11 tabanındaki 64 basamaklı büyük bir sayı, daha sonra en-passant durumunu gösteren uçtaki başka bir basamağı eklemek için 9 ile çarpılır. Tabandaki (11) her hane, aşağıdaki olası değerlere sahip, tahtadaki bir kareyi temsil eder:

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.

Ve 9 tabanındaki rakamlar:

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

11 64 × 9, kodlamak için 225 bit gerektiren yaklaşık 2 224.57'dir . Ayrıca, üstteki 17 başlık biti, toplam 242 bittir.


Gelişmeler için ugoren'e teşekkür ederiz.


Bu, as'ın algoritmasına çok benzer, ancak önceden belirlenmiş bir sıradaki parçalar yerine tahta pozisyonları kullanır, bu da her ikisi de piyon promosyon problemine sahip olmamasını engeller ve verilerin biraz kesilmesini sağlar.
Joe Z.

En-passant'ı 0 ile 8 arasında bir sayı olarak kaydedebilirsiniz (mevcut oyuncu en-passant'ı hangi sütunda yakalayabilir?). 13^64 * 9239.99, 11 bit tasarruf ediyor. Kral konumlarını ayrı ayrı kodlayarak daha fazla tasarruf edin.
Ocak'ta ugoren

Görevime yorum yapan Snow Doorknob'a göre, bu tür bir cevap "cevap değil". Sadece söylüyorum. Bilginize yorum yazılmadan önce C kodunu cevabımı ekledim.
ace_HongKongIndependence

@ugoren: Bunu unuttum. Haklısın, aynı anda sadece bir piyonun paspu olabileceğini unuttum.
Joe Z.

@ ace: Yanıtınız, kodlama ve kod çözme kodu içermediğinden geçersiz değil; piyon-promosyon davasını hesaba katmadığı için geçersizdir (bu durumda önceden tanımlanmış parça siparişiniz hiçbir şey yapmaz). Sorun, özünde, bir veri kodlama şeması ister. Program sadece bununla arayüz olacak bir şey.
Joe Z.

3

? bit

(≥ 217 en kötü durum, 17 en iyi durum, ilk yönetim kurulu için 179)


Kodlama açıklaması

Ekstra meta veriler, kimin sırası (bir bit) ve dökümden (dört bit, yani kralların tarafında beyaz kale? Kraliçelerin tarafında? Ve siyah için benzer şekilde) oluşur.

Tahtanın pozisyonu için, onu aktif parçalar kümesi olarak kodladık. Aslında, parçaları açıklayacağım sebeplerden dolayı belirli bir sıra ile numaralandırdığınızdan emin olun. Her bir parça için rengini (bir bit), türünü (6 türü kapsayan üç bit, artı "passant tarafından alınabilecek piyon" için bir ekstra tür) ve konumunu saklıyoruz.

İşte ilginç kısım: bir parçanın konumunu kodlamak, bir koordinat olarak saklamak yerine, parçaları soldan sağa, yukarıdan aşağıya sıraya dizerken son parçaya olan göreceli mesafesini saklıyoruz (A8 , B8, ..., G1, H1). Ek olarak, mesafeyi değişken uzunluktaki bir sayı olarak depolarız, 1bu parçanın hemen yanında olduğu anlamına gelir, 0xx1-3 parçayı 000xxxatlamak için , 4-10 parçayı atlamak 000000xxxxiçin, 11-25 0000000000xxxxxiçin 26-56 için ve son 000000000000000xxxolarak 57-62.

Örnekler

Ben yapılan bir özü Bu kodlama ile kodlanan başka pozisyonları ve bazı yorumlar ile başlangıç konumunda bir tane ek açıklamalı.

En kötü durum bit büyüklüğünü nasıl analiz edeceğimi bilmiyorum, ama özünde örnekler verildiğinde, algoritmanın en azından biraz verimli olması gerektiğine inanıyorum.


Kod çözücünün uygulanması

Aşağıda bu kodlama için hızlı ve kirli bir kod çözücü bulunmaktadır (yukarıdaki açıklamalı örnekte olduğu gibi metinde kodlanmış ikili verileri girerek ve '0' veya '1' olmayan şeylerin üzerine atlayarak). Stdout'a unicode satranç tahtası üretir.

#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;
}

En kötü durum bit sayınızın ne olduğu hakkında hiçbir fikrim yok, ancak bence 179 bitden fazla. Örneğin, algoritmanız bu düzeni nasıl idare eder ? (Bu arada , geçerli; satranç.com'daki editörü kullanarak yaptım )
ossifrage

@squeamishossifrage, 217 bit gerektiriyor gibi görünüyor: gist.github.com/FireyFly/8639791 (test durumu için teşekkürler, daha zorlu bir denemek istedim!)
FireFly

Hey, fena değil. Devam et!
squishish ossifrage

2

Maks: 184 bit, Min: 75 bit

@ AdamSpeight'ın Huffman'sından, kendi planımı oluşturmayı denemek için parçaları kodlayan ilhamdan ilham aldım. Bunun kazanacağından şüpheliyim ama hesaplanabilir sınırları var.

Bu şema, satranç taşları, 11 farklı parça türü varmış gibi ele alınmaktadır. Aşağıdaki kodlamaları oluşturmak için bu sınıfları frekanslarına ve gerçek tiplerine göre gruplamak için yaklaşık olarak Huffman kodlama algoritmasını takip ettim:

 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

Her bir parçanın kodundan önce hangi takıma ait olduğunu göstermek için iki bit bulunabilir ( 10Beyaz 11için, Siyah için). 0boş alanları kodlamak için kullanılabilir. Bu fikirler, istediğimiz prosedürü kullanarak tüm pano için kare kare bir kod oluşturmamıza izin veriyor. Yineleme sırasını üstleneceğim a1, b1, c1, ... f8, g8, h8. Bu, yalnızca yukarıda gösterilen şekilde bu kodların listelenmesinin, kimin sırası dışında tüm bilgileri kodladığı anlamına gelir. Çok basit bir satranç motoru, oyuncuların ve pastanın yasal olup olmadığını belirlemek için piyonlar, kaleler ve krallar için "sınıfları" kullanabilir. Ayrıca, bu program kolayca piyon promosyonlarını idare eder. Bir oyuncu bir piyonu bir kaleye terfi ettirirse, "taşınan" değişken seçili olduğu sürece kral veya kraliçe kodları kullanılabilir.

Daha önce olamayacağını düşündüğüm patolojik durumlar dışında, bu kodlamanın en kötü senaryosu, tüm taşların hala tahtada olduğu ve önceki oyuncunun iki boşlukta bir piyon ileri götürdüğü durumdur. Örnek olarak, aşağıdaki pano kodları 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

Bu, en kötü durumda kodlamanın 184 bite sahip olduğu anlamına gelir: oynatıcıyı belirtmek için 1, boş alanlar için 32, hareketsiz piyonlar için 45, iki boşluklu atlama piyonu için 6, şövalyeler için 24, piskoposlar için 24, Kancalar için 28, kraliçeler için 12 ve krallar için 12.

Parçalar hareket ettikçe ve yakalandıklarında, kodlamanın boyutu düşecektir. En iyi senaryo, tahtada tek başına iki papazla temsil edilir: oyuncuyu belirtmek için 1 bit + boş kareleri belirtmek için 62 bit + kralları belirtmek için 12 bit minimum 75 bit verir.

Geri döneceğim ve bu yanıtı bugün veya yarın için geçerli olan bu kodlamayı gösteren bir kodla düzenleyeceğim. Şimdilik, başkalarının bu kodlama hakkında ne düşündüğünü görmek istiyorum.


1
Çubuklardaki bitleri kaydedebilirsiniz. Kraliçe ve kral tarafını pozisyona göre belirleyebilir ve taşınan bir kalenin hangi tarafından geldiğini bilmenize gerek yoktur. yani kale üzerinde taşınan veya taşınmamış bir parça bilgiye ihtiyacın var.
Charles,

... Ve aslında, bu verileri bir parça düzeyinde saklamak kodlamak / kod çözmek daha kolaydır, ancak başlangıçta bir işaretleyiciyi saklarsanız, bitlerin genel olarak en kötü durumundan (örneğin, işaretleme 11001aracı B'S MOVE W CAN KSC W CANT QSC B CANT KSC B CAN QSC) tasarruf edebilirsiniz . Bu, kodlamada yandaki 5 bit yerine 4 bit veya kenarlardaki işaretleyiciyi elimine ederseniz yandaki 3 bit'dir. ( KSC= QSCKing's side castle. = Kraliçe'nin castle)
Charles değil

Ayrıca, promosyonlar nedeniyle, 9 kraliçeye veya 10 Şövalyeye (ya da diğer herhangi bir muhteşem, piyon dışı parçaya) sahip olmak oldukça mümkün
Charles Charles

1

184 bit = 23 bayt en kötü durum, ve çok karmaşık değil:

A. Hangi karelerin bulunduğu: 64 bit = 8 bayt B. <= 32 işgal edilen kareler için hangi renkler: 32 bit = 4 bayt Ve şimdi yalnızca <= 30 kareleri olmayanlar tarafından kullanılan kareler kullanarak: B. Yarıçapta kodlanmış PNBRQ kullanın 5, 30 ^ 30 olasılık için; ve 32 * 31 * 2 * 4 * 4 * 9 kral pozisyonları, taşıyıcı renk, beyaz ve siyah döküm hakları, en passant kare (8 olasılık artı hiçbiri, 9); bu sayı 5 ^ 30 * 32 * 31 * 2 * 4 * 4 * 9 = 266075134277343750000000000 = 2 ^ 87.782 kodlamanın tamamı için toplam 64 + 32 + 88 = 184 bit için 88 bit'e uyar.

Bu azaltılabilir, örneğin 32 * 31 * 2 * 4 * 4 * 9 = 285696, gerçeği kullanarak 2 * (32 * 31 + 31 * 3 + 31 * 3 + 3 * 3) * 6 = 14244'e düşürülebilir en fazla 6 en başarılı mağdur adayı (hiçbiri dahil değil) ve aynı küme içindeki döküm haklarını ve krallık pozisyonlarını kodlamak, sadece ilk meydanda kral olunca önemli olan döküm hakkı haklarını kullanarak. Bu 4 bit kazandırır.

18 bayta ulaşmanın mümkün olmadığına inanıyorum, yani toplam yasal satranç pozisyonları sayısı 2 ^ 144'ü aşıyor.

160-bit planınız çok zekicedir ancak bunda tamamen kendime güvenmeden önce kodlama / kod çözme programları olarak verilmesi gerektiğini düşünüyorum.


1

171 bit en kötü durum:

Birkaç düşünceyi ve bazı düşüncelerimi birleştirdim.

64 bit kartla başlayacağız. Her bir bit, tahtadaki dolu bir alanı temsil eder. Satırları dolduruyorlar. Yani başlangıç ​​gibi görünüyor:1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111

Şimdi, her bir parça 4 bit ile temsil edilecek. 1. bit: renk ( 0=white, 1=black) 2.-4. bit: 8 türden biri.

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

Sonunda dönüşü belirten bir parça dahil edeceğiz. 0=white, 1=black.

4 bit * 32 adet = 128 bit ve dönüşte ve tahtadan 64 + 1 aldım. Bu toplam 128 + 64 + 1 = 193 veriyor. En passant veya castling ile başlamadım bile. Limitimin üzerinde hiçbir şey yok - dönüş bile yok. Burası hilelerin başladığı yer.

Tamam - yukarıdaki tipleri gördünüz mü? Piskopos0 ve Piskopos1? Piyon0 ve piyon1? Bu tipler çok belirgindir, çünkü bize bu parçadan sonra biraz eklememizi söylerler. Öyleyse Bishop0, ondan sonra 0 olacağı anlamına gelir - yani bir sonraki parça beyazdır. Piskopos1 bize bir sonraki parçanın siyah olduğunu ve piyon0 ile piyon1'in aynı şekilde çalıştığını söylüyor. (Bu parça numaralandırılan son parça ise, o zaman bize bir sonraki dönüş hakkında bilgi verir).

En kötü durum, tahtadaki tüm parçaları içeriyor, yani 16 piyon ve 4 piskopos, bu bana 20 bit kazandırıyor. 173'e düştüm.

Tamam. En kötü durumumdaki bir başka bit için - bir kez kodlanmış bir rengin 16'sı varken, ileriye doğru gittiğini bildiğimiz gibi renk kodlamasını durdururuz. Benim en kötü durumum şimdi hiç yakalamadan uzak köşeye götüren beyaz bir parça içeriyor. Orada sadece bir bit biriktiriyorum. 172.

Şimdi parçaları adlandırdığım sırayı değiştireceğim. Onları dışarıya doğru hareket ederek başlayan sütunlar boyunca isimlendireceğiz. Başında belirtilen tahta aynı kalacak, ancak üzerine parçalar yerleştirdiğimde sağ alttan beyaz başlıyorum ve o sütuna geçiyorum. Sonra siyahın sağ alt bölümüne atlıyorum ve o sütuna giriyorum. Beyazın sağ alt tarafındaki bilinmeyen hücreye atladım ve bunun gibi - bu benim en kötü durumumun tekrar başlangıç ​​olduğu anlamına geliyor. Sebebim, en aldatıcı numaramla, sonraki iki parçamla kaybettiğim ve aldatmacamla alakalı.

Şimdi, bir piyonun tanıtılması için (uzunca tartışıldığı gibi) bir parça ele geçirilmelidir. Bu nedenle, 32 adet olduğunu bildiğimizde, sadece 31 tanesini göstermemiz gerekir. Son parça benzersiz bir şekilde tanımlanmıştır. Görünüşe göre, benim için, bu sadece 2 bit kazandırıyor - çünkü son parçam bir piyon / piskopos (normalde bana 3 bit mal oluyor çünkü bir sonraki parçada bir tane biriktiriyorum) kimin rengi belirlendi ve sadece 2 bit. 170 bite düştüm.

Piyonlar terfi ettiğinde, sadece türünü değiştirir. Tahtadan çıkan her parça için kendimi (en az) 3 bitten kurtardım ve iki piyon promosyonu bana 2 bite mal oldu, bu yüzden promosyonlarda (yavaşça) düşüyorum.

Rok. Döküm yapmak için, ne kral ne de ilgili kale taşınmış olabilir. Böylece, bir kale hem onu ​​hem de döküm yapabiliyorsa, kral orijinal yerlerinde olacaktır. Böylece, döküm yapabilen kaleler, bu rengin kralları ile aynı yerde listelenir. Bu yasadışı olduğundan (tahtadaki aynı renkten iki papaz veya üç papaz) ve sadece her renk için üç olası kurulumda gerçekleşebilir (sol, sağ, her iki çubuk papaz olarak listelenir) - kod çözme tamamen mümkündür. Böylece, hiçbir bit için, döküm yapmayı kodladık.

En Passant Burada yasadışı konumları da kullanacağız. Bir seferde sadece bir piyon en passant tehlikesinde olabilir. Dördüncü sırada olmalı. Korunmasız olan piyon, ana sırasına geri çevrilir - orada ne varsa değiştirilir. Bu piyon kendi ilk sırasına girdiği için - yasadışı bir pozisyon, durum kod çözücüye açık olacaktır - pozisyonları tersine çevirecek ve piyonu en passant'a karşı savunmasız olarak işaretleyecektir.

Son parça 'benzersiz bir şekilde tanımlanmalı' çünkü siparişle uğraşmamız gerekiyordu. Standart bir düzende, arka köşedeki kalenin kale olup olmayacağını söyleyemeyiz - bu bilinmiyor. Dışarıdan çalıştığımız zaman, kalenin kendi köşesinde ya da tahtanın ortasında 'sıralı' olduğu yerlerde, pasif ve savunmasız bir piyonla değiştirildiğinden emin olduktan sonra, listelenen bir parça olacağını garanti ediyoruz. o - bize kalenin türü söylendi. Bundan sonra bir parça olacağını biliyoruz, çünkü, bir piyonun savunmasız kalması için içeride bir piyon olması gerekir (bu, yukarıdaki talimatlara göre çok daha sonra kodlanacaktır).

Ah, ve en kötü durumun tahtadaki tüm parçaları içerdiğinden emin olmak için, 32 parçadan daha az bir zaman sonra, beyazı kullanırken parçaları temsil etmek için 0'ları kullanarak, sıraları ve kullanılan pozisyonları tanımlamak için 64 bitlik kartı kullanabiliriz. açmak ve 1s siyah olunca.

Böylece passant ve bedava oyuncu bulduk. Son parçayı bedavaya aldık, ancak en passant ve casting kurallarına göre bu oyunu güzel kılmak için biraz kandırmaya başladı. Standart parçalara 20 bit ayırdık. Buradaki en kötü durumun, bütün parçalar tahtadayken, ortada beyaz bir piyonun ileriye doğru hareket ettiği ve içinde kraliçesi arasında siyah bir parça bulunduğuna inanıyorum. Hızlı çift kontrol: ilk parça ele geçirilir - piyon olarak adlandırılır, tahtada piyonda 3 bit, piyonda tahtadan 3 bit, son işaretleyici olarak tahtada 3 bit, sivri uçta bir bit kaybolur. İki piyonu tahtaya 2 bit geri getirin. Kahretsin, 171'deyim.

EDIT (Çalışıyor?) Kod çözücünün kodunu R - in - altında ekledim. Boole vektörlerini girdi olarak alır - (üzgünüm - aslında bitleri kullanmama izin verecek hiçbir şeyi iyi bir şekilde kodlayamıyorum) Ayrıca başlangıç ​​pozisyonunu da ekledim.

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))

Bu kod 4 fonksiyon oluşturur. Parçaların ve tahta yapıların bir miktar temel ayrılmasının yanı sıra parça tipini ve herhangi bir 'örtülü' parçayı ortaya çıkaran bir tanesi. Bir sonraki fonksiyon tahta yapısını bu parçalarla biraz tuhaf (ve ilk algoritmamınkilerden farklı) bir sırada [kod açıklamalarında açıklanmıştır] doldurur. Bir sonraki fonksiyon doldurulmuş levhayı alır ve yasadışı pozisyonları algılar - daha sonra bunları düzeltir ve en "x piyon-e" ya ve "x rook-c" yi kale edebilen kalelere karşı savunmasız piyonları yeniden adlandırır. Son işlev, bu işlevleri sırayla çalıştıran ve geçerli pano ve sırayla bir çıktı veren bir sarıcıdır.

Ayrıca başlangıç ​​konumunun kodlamasını da ekledim (onu görmeniz gerekecek olsa c(startboard,newpieces)da kodun sarmalayıcı işlevini bu konumda çağırması gerekir .


Bu ilginç. Çalışan bir uygulamayı kavramın kanıtı olarak görmeyi çok isterim.
Mego

Uygulama genellikle kavram kanıtının ötesinde birkaç adımdır, ancak bir kod çözücü ekledim. R'dedir ve bu nedenle bitlerden ziyade Boolean'ları kullanır (üzgünüm - çok fazla zaman kullanmak istemiyordu). Ama bunun kavramın kanıtı olması gerektiğine inanıyorum.
user5957401

0

229/226 bit

Bu, çok başarılı olamadığı, aynı zamanda diğer insanları da aynı yoldan kurtaracağı anlamına gelebilir.

Basit versiyon:

  • 1 kimin sırası onun için
  • 4 dört döküm tesisi için bit
  • 3en uygun olasılıklar için bit . Bu ilk başta anladığımdan daha fazla derinliğe sahip. En passant , yakalanan piyon ile aynı sırada (sıra) hareket eden bir piyon ile yapılmalıdır. Vaka analizi, en son taşınan rengin kaç piyonunun tam olarak iki kareye sahip olduğunu bildiğimizde, en fazla 6 en passant vakanın olacağını ( en passant için savunmasız bir piyonun olmadığı durum da dahil ) olacağını gösterir . En kötü durum 5 piyondur (potansiyel olarak tüm savunmasız: örn . PpPPpPPpBeş hassas güvenlik açığı var P). 6 piyon ile en fazla 2 piyon tehdit edebilir, her biri aynı sıralamada en fazla 2 düşman piyonlar vardır gelmişken . Bu yüzden ceil(lg 6) = 3burada bitlere ihtiyacımız var.

Sonra tahta. Kartın 64 karesi vardır, böylece bir kare indeks 6 bit olarak kodlanabilir. Erkekleri rütbeye göre sıralayıp rengine göre kraldan başlayarak sıralıyoruz.

  • 6bit: beyaz kralın konumu. (Gemide olması garantilidir).
  • 6bit: kara kralın konumu. (Tahtanın üzerinde olması garantilidir. Beyaz kralın bir köşesinde olması en kötü durumda, olabileceği 60 olası yer vardır; en iyi durumda beyazın bir kenarında olmaması 55).
  • 6bit: beyaz kraliçenin konumu. Beyaz kraliçe yoksa, beyaz kralın konumunu bir sinyal olarak tekrarlayın.
  • Her ek beyaz kraliçe için, 1biraz pozisyonu için 6 bit izledi.
  • Bir 0ısırdı.
  • Kara kraliçe (ler) için aynen.
  • Aynı renkte, 16 tane erkeğimiz varsa, piyonlar, piskoposlar, şövalyeler ve piyonlar için benzer bir işlem olsa da, bir renk için piyonları atlayabiliriz.
  • Son 0parçayı silin .

Bu 12, krallar için belirli bir bit 2*7*5-1 = 69, diğer erkekler için de bit. Gemide 32 erkeğin de bulunduğu en kötü durumda 7, krallar dışındaki her erkek için toplam maliyet 12 + 7*30 - 1 = 221 bits. Dolayısıyla, 8küresel devlet için ilk bitlerde, 229 bitimiz var .


Gelişmiş versiyon:

Aritmetik kodlamayı kullanarak lg num_possibilitiesyerine ceil(lg num_possibilities)sadece çalışabilir ceilve sonunda bir tane alabiliriz .

  • 1 kimin sırası onun için
  • 4 dört döküm tesisi için bit
  • lg 6en uygun olanaklar için bitler .
  • 6 beyaz kral için bit
  • lg 60 siyah kral için bit (en kötü durum)
  • lg 63 beyaz kraliçe için bitler (çekleri kontrol etme seviyesini zorlaştırmak istemiyorum), eğer yoksa beyaz kralın konumunu kullanarak
  • Her ek beyaz kraliçe, bir 1bit takiben lg 62, lg 61onun pozisyonu için, vb bit.
  • Bir 0ısırdı.
  • lg 63 Kara kraliçe için (beyaz kraliçe varsa) daha az bit.
  • vb.

Aslında mevcut olan ns erkeğin 66-nolası değerleri var. Bir renk için bir tür yoksa, bunu 66-#men so farkaydetmek için bit harcadık (artı ayırıcı için bir bit). Aşırı durumlar:

  1. Her erkek, her iki taraftan da en az bir unpototed piyon dahil olmak üzere, mevcut. 5+lg 6Küresel devlete, 6+lg 60krallara, 29ayırıcı bitlere ve SUM_{n=32}^{63} lg npozisyonlara bit harcıyoruz . Genel toplam: ceil(225.82)bit. Hayal kırıklığı.
  2. Yalnız kaldırılmamış piyonlar kaldı. Biz harcamak 5+lg 6, küresel durumuna 6+lg 60, kralların üzerinde 29, ayırıcı bit üzerinde 8*lg 63başka hiçbir parça olduğunu söyleyerek, ve SUM_{n=48}^{63} lg npiyon pozisyonlarına. Genel toplam: ceil(188.94)bit. Daha iyi - her kale için ikinci kale, şövalye ve piskoposu kurtarırken biraz öne çektik.

Bu yüzden en kötü durum , 3'lük bir tasarruf için 226 bit gibi görünüyor .

Parçalar halinde piyonları kodlayarak kesinlikle ortalamada daha iyisini yapabiliriz, çünkü bunlar tam 64 yerine 48 kare ile sınırlıdır. bu, 2 bit daha pahalıya mal olacak çünkü erkekleri saymak yerine "piyon yok" bayrağına ihtiyacımız olacak.


0

Satranç çevrelerinde bir tartışma konusu bu.

164 bitlik çok basit bir kanıt burada https://groups.google.com/forum/#!topic/rec.games.chess.computer/vmvI0ePH2kI 155 burada gösterilmektedir http://homepages.cwi.nl/~tromp /chess/chess.html

Basitleştirilmiş stratejinin üzerinde:

  • Piyonları, piyonların bulunabileceği yerle sınırlandırın
  • Orduyu orijinal parçaları ve olası piyon promosyonlarını göz önüne alarak sınırlayın
  • Promosyonları ve promosyonların mümkün olmadığı durumları düşünün

2
Sadece link cevapları iyi cevaplar değildir. Yalnızca cevabın bazı linklerini değil, yazınızın içinde tam cevap vermelisiniz. Cevabınız kendi işiniz değilse, muhtemelen yayınınızı topluluk wiki yapmalısınız.
ace_HongKongIndependence

Yayın orijinal. Cevaplamak için detay ekleme.
William Entriken

1
Bu, cevabınıza içeriği neden eklediğinize bir örnektir. 2. bağlantı öldü. Bu mu? tromp.github.io/chess/chess.html
mbomb007 4:16

-2

Min: 0 bit

Max: 1734 243 bit (4,335 4.401 bit / tahta itfa edildi

Beklenen: 351 177 bit (4,376 4.430 bit / tahta itfa edildi)

Girdi ve çıktıyı belirleyebildiğim için ancak istediğim kadarıyla oyunun tarihini kodlayana kadar devam etmeye karar verdim. Bir avantaj, sıranın kim olduğuna, pasaplayan ve kim türetilip kodlanamayacağına kale yapma kabiliyetine sahip olmasıdır.

Girişimi 1:

Naif bir şekilde her hareketi 12 bit, formun 4 üçlüsü (başlangıç ​​x, başlangıç ​​y, bitiş x, son y) olarak kodlayabileceğimi düşündüm, burada her biri 3 bit.

Başlama pozisyonunu alır ve parçaları önce beyaz olacak şekilde hareket ettirirdik. Tahta (0, 0) beyazın sol alt köşesinde olacak şekilde düzenlenmiştir.

Örneğin oyun:

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

Olarak kodlanmış olur:

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

Bu, 12 m bitlik bir kodlamaya yol açar, burada m yapılan hareketlerin sayısıdır

Bir yandan bu diğer yandan her kodlama gerçekten kodlar yüzden kendi oyun olması her hamleyi düşünebiliriz, gerçekten büyük alabilir m "satranç tahtaları". Eğer bunu itfa etmişseniz, her "satranç tahtasının" 12 bit olduğunu görürsünüz. Ama bunun biraz aldatma olduğunu hissediyorum ...

2. girişimi:

Önceki denemedeki her hareketin birçok yasadışı hareketi kodladığını fark ettim. Bu yüzden sadece yasal hareketleri kodlamaya karar verdim. Olası hamleleri şu şekilde sıralarız; her kareyi (0, 0) → 0, (1, 0) → 1, (x, y) → x + 8 y olacak şekilde numaralandırın. Döşemeler arasında yineleyin ve bir parçanın olup olmadığını ve hareket edip etmediğini kontrol edin. Eğer öyleyse pozisyonları ekleyin bir listeye gidebilirsiniz. Yapmak istediğiniz hareketin liste dizinini seçin. Bu sayıyı, 1 artı ağırlıklı hareketlerin toplam hareketine ve olası hareketlerin sayısına ekleyin.

Yukarıdaki gibi örnek: Başlangıç ​​konumundan hareket edebilen ilk parça, kare 1'deki şövalyedir, kare 16 veya 18'e gidebilir, bu yüzden bunları listeye ekleyin [(1,16),(1,18)]. Sırada karede 6 olan şövalye, hareketlerini ekle. Genel olarak biz alırız:

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

Hareketi istediğimizden (12, 28), 20 olası hareket olduğundan, bunu üs 20'de 13 olarak kodladık.

Şimdi oyun numarasını g 0 = 13 alıyoruz

Daha sonra siyah için de aynısını yaparız, ancak hamlelerin listesini almak için karoları ters olarak numaralandırırız (kolaylaştırmak, gerekli değildir):

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

Hareketi istediğimizden (11, 27), 20 olası hareket olduğundan, bunu üs 20'de 11 olarak kodladık.

Şimdi oyun numarasını g 1 = (11 11 20) + 13 = 233 olarak alıyoruz.

Sonra beyaz için aşağıdaki hamle listesini alırız:

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

Hareketi istediğimizden (6, 21), 29 olası hamle olduğundan bunu taban 29'da 13 olarak kodladık.

Öyleyse şimdi g 2 = ((13 ⋅ 20) + 11) 20 + 13 = 5433

Sonra kara için aşağıdaki hamle listesini alırız: [(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)]

Harekete geçmek istediğimiz için $ (10, 18) $ (10, 18)

Öyleyse şimdi g 3 = (((19 ⋅ 29 + 13) 20) + 11) 20 + 13 = 225833

Ve kalan tüm hareketler için bu işleme devam edin. G işlevini g (x, y, z) = x y + z işlevi olarak düşünebilirsiniz . Böylece g 0 = gr (1, 1, 13), g 1 = gr (g (1, 1, 11), 20, 13), g 2 = gr (g (g (1, 1, 13), 20, 11), 20, 13), g 3 = gr (g (g (g (1, 1, 19), 29, 13), 20, 11), 20, 13)

Bir oyun numarasını g 0 kodunu çözmek için , başlangıç ​​pozisyonundan başlıyoruz ve tüm olası hareketleri numaralandırıyoruz. Sonra hesaplarsak g 1 = g 0 // l , m 0 = g % 0 l , burada l olası hareketlerin sayısıdır, '//' tamsayı bölme işleci ve '%' modulus işlecidir. Şunu tutmalı ki g 0 = g 1 + m 0 olmalıdır . Sonra m 0 hamlesini yaparız ve tekrar ederiz .

Örneğin yukarıda eğer g 0 = 225.833 sonra gr 1 = 225.833 // 20 = 11291 ve m, 0 = 225.833% 20 = 13. Sonraki g 2 = 11291 // 20 = 564 ve m, 1 20 = 11. O = 11291% g 3 = 11291 // 20 = 564 ve m, 2 = 11291% 20 = 11. Bu nedenle g 4 = 564 // = 19 29 and_m_ 3 = 564% 29 = 13. Son olarak gr 5 = 19 // 29 = 0 ve m 4 =% 19 29 = 19.

Peki bu şekilde bir oyunu kodlamak için kaç bit kullanılır?

Sadelik için, her seferinde 20 hamle olduğunu ve en kötü senaryoda her zaman en büyük olanı seçtiğimizi varsayalım, 19 alacağımız sayı 19 ⋅ 20 m

+ 19 ⋅ 20 m-1 + 19 ⋅ 20 m-2 + ⋯ + 19 ⋅ 20 + 19 = 20 m + 1 - 1, burada _m, hareket sayısıdır. 20 m + 1 - 1 kodlamak için log 2'ye (20 m + 1) ihtiyacımız var. ) bit (yaklaşık + m) olan ∗ log 2 (20) = 4.3219 ∗ (m + 1) değerine ihtiyacımız vardır.

Ortalamada m = 80 (oyuncu başına 40 hamle) bu yüzden kodlaması 351 bit alacaktı. Eğer birçok oyun kaydedersek, evrensel bir kodlamaya ihtiyacımız olurdu, çünkü her bir numaranın kaç bit'ine ihtiyacı olacağını bilmiyoruz.

En kötü durum ne zaman M = 400 (oyuncu başına 200 hamle) bu yüzden kodlamak için 1734 bit alacaktır.

Kodlamak istediğimiz konumun, kuralları izleyerek oraya ulaşmak için en kısa yoldan bize verilmesi gerektiğini unutmayın. Mesela oyun burada teorik son konumu kodlamak için m = 11741'e ihtiyacı yoktur . Bunun yerine, o konuma giden en kısa yolu bulmak ve bunun yerine onu kodlamak için bir Genişlik-Birinci araştırması yaparız. Tüm satranç pozisyonlarını sıralamak için ne kadar derine ihtiyacımız olacağını bilmiyorum, ama 400'ün fazla tahmin edildiğinden şüpheleniyorum.

Hızlı hesaplama:

12 benzersiz parça var ya da kare boş olabilir, böylece onları bir satranç tahtasında konumlandırmak için 13 64'tür . Bu, çok fazla geçersiz pozisyon içerdiğinden çok fazla abartılıyor. Biz ne zaman m oyuna hamle biz 20 hakkında oluşturduk m pozisyonları. Yani 20 m = 13 64 olanı arıyoruz . Her iki tarafa da giriş yaparak m = 64 * log 20 (13) = 54.797 kaydedin. Bu, 55 hamlede herhangi bir pozisyona geçmemiz gerektiğini gösteriyor.

Şimdi en kötü durumda hesapladım m = 55 değil m = 400 olarak sonuçlarımı düzenleyeceğim. M = 55'in 243 bit aldığı bir pozisyonu kodlamak için . Ayrıca ortalama bir durumun olduğunu söyleyebilirim. m = 40 bunun kodlanmasının 177 bit .

Eğer amortisman argümanını eskiden kullanırsak, 1734 bitte 400 "satranç tahtasını" kodluyoruz, böylece her "satranç tahtasının" en kötü durumda 4.335 bit aldığı anlaşılıyor.

Bunu not et gr = 0, geçerli bir oyun, tek göstermekte olup burada olabildiğince düşük kareye en düşük kare hamle üzerine parça.

Ek Notlar:

Oyunda belirli bir pozisyona atıf yapmak istiyorsanız endeksi kodlamanız gerekebilir. Bu, manuel olarak eklenebilir, örneğin, dizini oyuna birleştirmek veya her turda mümkün olan en son hamle olarak ek bir "son" hareketi eklemek olabilir. Bu şimdi oyuna katılan oyuncuları ya da berabere kabul edilen oyuncuları belirtmek için art arda 2 hesabı oluşturabilir. Bu, yalnızca oyun pozisyona göre bir çek arkadaşı veya çıkmazla bitmediyse gereklidir, bu durumda ima edilir. Bu durumda, ortalama olarak 356'ya ve en kötü durumda 1762'ye ihtiyaç duyulan bit sayısını getirir.


1
Amortisman argümanınız çalışmıyor. Amaç, kullanıcı tarafından verilen bir kartı kodlamaktır. Bu kartı kodlamanın maliyetini, yol boyunca oluşturabileceğiniz 400 yardımcı kart arasında bölmezsiniz. (Bu 400 tahtanın kullanıcı tarafından bağımsız olarak seçilmesine izin verildiyse ve bir satranç oyunu oluşturma zorunluluğuyla sınırlandırılmadıysa bu sorun olmazdı.) Ayrıca, bir satranç oyunu teorik olarak binlerce hamle yapabilir ve OP En kötü durumla ilgilenme konusunda net olun.
Anders Kaseorg

@AndersKaseorg: Çok doğru. Bu gerçekten hedefe bağlı. Bütün bir oyunu diğer algoritmalarla birlikte kaydetmeye çalışıyorsanız, m * c bayt alır, burada m hamle sayısıdır ve c onların çıktısının büyüklüğüdür. Bu yüzden, 160 bitlik bir çözümü kullanarak 80 hamlelik bir oyunun tümünü saklamaya çalışıyorsanız, benimki sadece 351 alırken, 12800 bit alacaktı. Tüm panoları değil sadece panoları depolamak istemek çok yaygın olduğu için bunu belirtmek gerekir.
edggy

Amaç belli değil. “Amaç, bir sıradaki bir oyuncunun tüm hareket imkanlarını belirlemek için kullanılabilecek (bir kez kodu çözülmüş) kullanılabilecek bir satranç tahtasının en küçük gösterimini yapmaktır. … Puanınız en kötü senaryo olarak belirlenmiştir - bit
cinsinden

@AndersKaseorg: Belirsiz olduğunu iddia etmedim. Sadece farklı bir yaklaşım almaya karar verdim. Unutulmaması gereken bir şey, algoritmamı kullanarak en küçük tahtayı bulmak için bu konuma ulaşmak için en küçük yola ihtiyacım var. Mesela, aynı tahta pozisyonuna geçmek için bağladığınız 11741 turnuvasında, tek umursadığımız şey tahta ise, bu yolu izlememe gerek yok. Bu yüzden bağlantılı oyunu kodlamak için sadece 200 tur ya da daha az olabilecek karelerde 2 papazla kalan en kısa oyunu buldum. Bu derinlik ilk arama ile yapılabilir.
edggy

Daha kısa bir eşdeğer oyun kullanmak gayet iyi, eğer aslında her pozisyonun 200 turda veya daha kısa sürede ulaşılabilir olduğunu ispatlayabilirseniz (şu anda bu bir tahmin gibi gözüküyor). Ayrıca , inşaatınızda ortaya çıkmadıklarını kanıtlayamazsanız, 100'den fazla yasal hamle olan satranç pozisyonlarını da hesaba katmanız gerekecektir . Sonucunuzu oyundaki hamlelerin sayısına bölmek, bu zorluğun kurallarına hala izin verilmez.
Anders Kaseorg
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.