กระดานหมากรุกที่เล็กที่สุดในการบีบอัด


38

เขียนอัลกอริทึมหรือโปรแกรมที่สามารถเข้ารหัสและถอดรหัสกระดานหมากรุก เป้าหมายคือการทำให้การเป็นตัวแทนที่เล็กที่สุดของกระดานหมากรุกที่สามารถนำมาใช้ (ถอดรหัสครั้งเดียว) เพื่อกำหนดความเป็นไปได้การเคลื่อนไหวทั้งหมดสำหรับผู้เล่นที่เปิด

การเข้ารหัสจะต้องสามารถแสดง:

  • ใครหันมาทางไหน
  • ไม่ว่าจะเป็นผู้เล่นสามารถปราสาทในแต่ละด้าน
  • ไม่ว่าผู้เล่นจะสามารถดำเนินการ en-passant และถ้าเป็นเช่นนั้นซึ่งเบี้ยของพวกเขา?
  • ตำแหน่งของชิ้นงานทั้งหมด

หมายเหตุสำคัญเกี่ยวกับการขว้างปา:หากขาวขยับกษัตริย์ของพวกเขาในคราวเดียวแล้วย้ายกลับไปอีกครั้งมันจะต้องชัดเจนว่าพวกเขาไม่สามารถปราสาททั้งสองข้างหลังจากนั้น ถ้าพวกเขาย้ายไปทางซ้ายหรือขวาของพวกเขาเหมือนกัน แม้ว่ากระดานจะอยู่ในสภาพเดียวกันเมื่อสองตาก่อน แต่สภาพเกมก็เปลี่ยนไป ข้อมูลเพิ่มเติมที่นี่: http://en.wikipedia.org/wiki/Chess#Castling

หมายเหตุสำคัญเกี่ยวกับผู้สัญจร:นี่คือการย้ายที่ละเอียดอ่อน อ่านกฎสำหรับข้อมูลเพิ่มเติม http://en.wikipedia.org/wiki/Chess#En_passant

กำหนดอินพุตและเอาต์พุตตามต้องการ อุปกรณ์ประกอบฉากสำคัญสำหรับใครก็ตามที่สามารถบีบอัดมันได้มากที่สุด!

คะแนนของคุณจะถูกกำหนดสถานการณ์กรณีที่เลวร้ายที่สุด - ขนาดที่เป็นไปได้สูงสุดในบิต ตรวจสอบให้แน่ใจว่าคุณแสดงให้เห็นว่าคุณคำนวณจำนวนนั้นอย่างไรและคิดอย่างไร ยิงเพื่อใส่เคสที่แย่ที่สุด!


"bitwise" คุณหมายถึงอะไร?
ปีเตอร์เทย์เลอร์

รหัสนี้เล็กที่สุดหรือบีบอัดมากที่สุดหรือไม่ บีบอัดส่วนใหญ่น่าสนใจยิ่งขึ้น
Justin

ขออภัยที่ไม่ชี้แจง Bitwise ในแง่ที่ว่าคุณสามารถบีบอัดได้ก็ต่อเมื่อคุณเริ่มแทนมันเป็นบิตซึ่งจะต้องใช้การดำเนินการระดับบิต ใช้ไม่ดีในส่วนของฉัน ยังถูกบีบอัดส่วนใหญ่ไม่ใช่รหัสที่เล็กที่สุด
Seltzer

1
@GeekWithALife ใช่มันเป็นไปได้ที่จะมี 18 ควีนส์บนกระดานในเวลาเดียวกัน ตามลิงค์นี้แล้วคลิกปุ่มเล่นเพื่อดูตัวอย่าง
ossifrage คลื่นไส้

1
@AJMansfield ซึ่งอาจเป็นประโยชน์สำหรับบอร์ดที่มีชายประมาณ 28 คน แต่ฉันคำนวณว่า 117 บิตนั้นมีมากมายสำหรับบอร์ดที่มีชายทั้งหมด 32 คนซึ่งน้อยกว่าเป้าหมายประมาณ 50 บิต ภาวะแทรกซ้อนคือเมื่อคุณไปต่ำกว่า 32 คนโปรโมชั่นสามารถให้ผู้เล่นบิชอปมากขึ้น
ปีเตอร์เทย์เลอร์

คำตอบ:


27

ต่ำสุด: 12 บิต
สูงสุด:
เฉลี่ย:

มีและคิดว่าเมื่อคืนนี้ที่ฉันสามารถทำให้มันเล็กลงได้

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)

ผลลัพธ์คือขนาดที่น่าประทับใจ12 บิต !

แล้วชิ้นส่วนอื่นของ K +1 ล่ะ

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

มี 2 ​​การจัดเรียงที่เป็นไปได้ของต้นไม้ย่อย

   /\      /\
  +  K    K  +

ทั้งคู่ทำให้ขนาดบิตเท่ากันทุกชิ้น ดังนั้นมันจึงไม่ต่างกับที่เราใช้ฉันจะเลือกอันแรก

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

ดังนั้นใน King +2 ชิ้นส่วนอื่น ๆ

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 ต้น (ฉันจะใช้ 1 และ 2 เพื่อระบุว่าชิ้นส่วนใด)

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

ดังนั้นเราจะต้องใช้ 3 บิตในการเข้ารหัสทรีย่อยที่จะใช้

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

ยังคงทำการวิเคราะห์สำหรับชิ้นส่วนเพิ่มเติม

+3 อื่น ๆ

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

+4 อื่น ๆ

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

+5 อื่น ๆ

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

สูงสุด: 208?


เป็นไปได้ไหมที่จะเข้ารหัสต้นไม้ย่อยทั้งหมดเหล่านี้เป็น 9 บิต?

ถ้าเรารวมต้นไม้ย่อยที่เป็นไปได้ทั้งหมดเราจะได้ต้นไม้ย่อยที่เป็นไปได้ 392 อัน

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

ใช้ Freq ID

เนื่องจากมี 164,603 ความถี่ชิ้นส่วนที่ไม่ซ้ำกัน

Log2( 164603) = 17.3286110452
             ~ 18 bits

0
 0000 0000 0000 0000 00  Freq ID

(+000) (+00) การขว้าง

สูงสุด: = 204 บิต


รอบ 3

ต่ำสุด: 82 สูงสุด: 199 ราคาเฉลี่ย: 160

ในที่สุดก็ทำการวิเคราะห์เพื่อหาขนาดบิตสูงสุด ด้วยการเข้ารหัส Huffman ที่ดีที่สุดสำหรับแต่ละความถี่ชิ้นส่วนที่ไม่ซ้ำกัน

               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 

โปรดทราบว่านี่เป็นขนาดที่เลวร้ายที่สุดซึ่งคอลัมน์ En-Passant บิตหากจำนวนการจำนำมากกว่าหนึ่ง โดยไม่คำนึงถึงสีและตำแหน่งที่จำนำเหล่านั้นจะมีศักยภาพสำหรับบอร์ดบางบอร์ดที่มีขนาดเล็กลง 3 บิต

นอกจากนี้ยังมีขนาดที่แตกต่างกันเพียง144ขนาด (กรณีที่แย่ที่สุด) สำหรับขนาดของกระดาน


75 - 216 บิต (v2) v1 ขนาดต่ำสุดคือ 98 บิต (12.25 ไบต์) เพียงสองกษัตริย์บนกระดาน

ขนาดสูงสุดเพียง 216 บิต (27 ไบต์) ในรูปแบบที่ไม่ชอบ: -

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

โดยเฉลี่ยแล้วขนาดจะอยู่ที่ 157 บิต (19.625 ไบต์)

ชิ้น

เมื่อต้องการเข้ารหัสบอร์ดฉันใช้รูปแบบการเข้ารหัสแผนภูมิต้นไม้ สี่เหลี่ยมจัตุรัสที่ว่างเปล่าเป็นความถี่ที่พบบ่อยที่สุดจากทุก ๆ ที่ที่ปรากฏระหว่าง 32 และ 62 ถัดไปคือเบี้ยจากนั้น Rooks อัศวิน Bishops และบ่อยที่สุดคือ Queen และ King

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

บอร์ดเริ่มต้นสามารถเข้ารหัสได้ใน 166 บิต (20.75 ไบต์)

  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

เพื่อระบุว่าใครย้ายมันใช้เวลาเพียงบิตเดียว

0-> Black , 1-> White

Castling สามารถเข้ารหัสได้ 4 บิต

 B  W
LR LR
00 00

ดังนั้นฉันใช้ 171 บิต (21.375 ไบต์)

En-Passe สามารถเข้ารหัสเป็น 16 บิต (2 ไบต์)

ดังนั้นทั้งหมด 187 บิต (23.375 ไบต์)

แบบ

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

ยังไม่ได้เขียนรหัสใด ๆ

ขอให้สังเกตว่า 3 ของบิตที่ไม่ได้ใช้ ดังนั้นสูงสุดคือ213bits


การปรับปรุงที่เป็นไปได้

1)ลดรูปแบบบล็อกส่วนหัว 24 ถึง 8 บิต (พร้อมคำแนะนำ @Peter Taylor)

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

2)ส่วนหัวความยาวผันแปร

ส่วนหัวคงที่ขนาดเล็ก 4 บิต

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

บล็อกถัดไปของบิตเพิ่มเติม (หากยังมีความสามารถในการหล่อ)

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

บล็อกถัดไปของบิตเพิ่มเติม (ถ้ามีเบี้ย)

000--> En-Passant column Position

ตอนนี้ฉันมีส่วนหัวที่มีความยาวผันแปรได้ 4 - 11 บิต


3)ใช้รูปแบบการเข้ารหัสที่แตกต่างกันขึ้นอยู่กับสิ่งที่เหลืออยู่บนกระดาน

โดยการเปลี่ยนการเข้ารหัสต้นไม้ขึ้นอยู่กับสิ่งที่ชิ้นส่วนบนกระดานและมีความถี่

หนึ่งการเข้ารหัสที่เป็นไปได้สำหรับสถานะเกมสิ้นสุด (ไม่มีการจำนำ)

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

ซึ่งประมาณ ~ 4 บิตต่อชิ้น

บอร์ดประเภทใดบ้างที่ปรากฏบนกระดาน

RBNQK Permutation
11111 (11111)

การเปลี่ยนแปลงคือความยาวผันแปร 0-5 บิต หากเหลือชิ้นส่วนประเภทเดียวไว้อย่ารวมไว้

การเรียงสับเปลี่ยนของชิ้นส่วนเหล่านั้นที่จะใช้สำหรับต้นไม้? นี่คือแฟคทอเรียลของจำนวนชิ้นในตัวอย่างข้างต้นมันคือ 5 ชิ้นดังนั้นมีการเปลี่ยนลำดับที่เป็นไปได้ 120 แบบที่สามารถเข้ารหัสได้

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

โปรดจำไว้ว่ามีบิตเพิ่มเติมสำหรับสี่เหลี่ยมและสีที่ว่างเปล่า


ตัวอย่าง

ลองยกตัวอย่างของ QK ที่เหลือเท่านั้น

RBNKQ
00011

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

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

0000 00011 Header ==> 9 bits

รวม81 บิต


ให้และตัวอย่างของกษัตริย์ที่เหลืออยู่เท่านั้น

 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

รวมทั้งหมดเข้าด้วยกัน

 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

ดังนั้นฉันจึงคำนวณการเข้ารหัสที่เล็กที่สุดสำหรับบอร์ดที่75บิต (9 บิต 3 บิต)

ยังไม่ได้คำนวณว่ารูปแบบการเข้ารหัสนี้มีผลต่อขนาดสูงสุดอย่างไร


การปรับปรุง 4

ลดจำนวนบิตสำหรับการหล่อเป็น 2 บิต เพียงแค่เหวี่ยงใส่ผู้เล่นที่เป็นไปได้

 0 Castling possible (from header block)
 LR 
 00

คิดเกี่ยวกับมันอาจจะดีกว่าที่จะรวม 2 บิตในบล็อกส่วนหัว


คุณไม่ต้องการ 16 บิตสำหรับผู้ที่ผ่านไป อย่างน้อยที่สุดคนหนึ่งจำนำก็หันไปรอบสุดท้ายดังนั้นสี่บิตพอเพียง (เช่น1111สำหรับ "ไม่มีทางผ่านได้" หรือคอลัมน์เป็นเลขฐานสองเป็นอย่างอื่น)
Peter Taylor

ทำไมเบี้ยถึงได้ตำแหน่งที่ดีขึ้นในต้นไม้? ในกรณีทั่วไปพวกเขาพบมากที่สุด แต่ในกรณีที่รุนแรง R / B / N สามารถปรากฏ 10 ครั้ง
ugoren

@PeterTaylor จริง ๆ แล้ว 3 บิตก็เพียงพอสำหรับ en passant หากคุณนับเฉพาะคอลัมน์ที่มีการจำนำอันดับที่ 5 เป็นสีดำ (สมมติว่าเป็นการย้ายแบบสีขาว) 8 จะไม่ถูกต้อง
ugoren

1
โปรดทราบว่ากรณีที่เลวร้ายที่สุดของคุณเป็นไปไม่ได้ การส่งเสริมเป็นไปไม่ได้หากไม่มีการรวบรวม (จำเป็นต้องมีการจับอย่างน้อยหนึ่งรายการต่อ 2 การส่งเสริมการขาย)
ugoren

2
หมายเหตุในการเข้ารหัส 64 ตำแหน่ง (สำหรับราชาสีขาวหรือดำ) คุณต้องการ 6 บิต (2 ** 6 = 64)
lambruscoAcido

17

192 บิต (กรณีที่เลวร้ายที่สุด)

นี่คือรูปแบบการจัดเก็บข้อมูลที่ง่ายมากที่ควรรับมือกับการส่งเสริมการจำนำโดยพลการและไม่ต้องการมากกว่า 64 + 4 × 32 = 192 บิต:

  • 64 บิตแรกเก็บbitboardที่บอกที่ชิ้นส่วนที่มี ( แต่ไม่ใช่สิ่งที่พวกเขามี) นั่นคือเราเก็บหนึ่งบิตสำหรับแต่ละตารางของกระดานหมากรุก (เริ่มต้นที่ตาราง a1 จากนั้น b1, c1 ฯลฯ จนถึง h8 ตาราง) เช่นที่ว่างจะถูกแทนด้วย 0 และตารางที่ถูกครอบครองโดย 1

  • ต่อไปสำหรับแต่ละสี่เหลี่ยมที่ทำเครื่องหมายว่าถูกครอบครองบน ​​bitboard เราจะจัดเก็บแทะเข้ารหัส 4 บิตที่ส่วนบนตารางนั้น ตัวแรกของบิตทั้งสี่เข้ารหัสสีของชิ้นส่วน (0 = สีขาว, 1 = สีดำ) ในขณะที่สามบิตที่เหลือเข้ารหัสประเภทของชิ้นส่วน:

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

    ประเภทชิ้น

    0 = (ปกติ) เบี้ย
    1 = (ปกติ) โกง
    2 = อัศวิน
    3 = บิชอป
    4 = ราชินี
    5 = ราชา (ของผู้เล่นที่จะย้ายต่อไป)
    6 = ราชา (จากผู้เล่นอื่น)

    สังเกตการเข้ารหัสทั้งสองของกษัตริย์ซึ่งใช้ในการพิจารณาว่าผู้เล่นคนใดที่จะทำการเลี้ยว (อันที่จริงเนื่องจากมีกษัตริย์สองคนบนกระดานเสมอเพื่อให้สามารถรวมรหัส 5 และ 6 ได้สี่ชุดเราจึงสามารถเข้ารหัสข้อมูลที่สองได้อย่างง่ายดายที่นี่)

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

    ในการเข้ารหัสข้อมูลพิเศษที่จำเป็นสำหรับกฎen passantและ castling เราแนะนำประเภทของส่วนเพิ่มเติมหนึ่งประเภทซึ่งหมายถึงการจำนำหรือการโกงโดยขึ้นอยู่กับแถวที่ปรากฏใน:

    7 (แถวที่ 1 และ 8) = แถวที่ไม่เคยขยับและกษัตริย์ก็ไม่เคยขยับและดังนั้นจึงเหมาะสำหรับการขว้างปา
    7 (แถวที่ 4 และ 5) = เบี้ยที่เพิ่งผ่านไปสองสี่เหลี่ยมและ ดังนั้นจึงอาจจะถูกจับการกิน

วางมันทั้งหมดเข้าด้วยกัน:

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

จำนวนบิตทั้งหมดที่ต้องใช้ในการเข้ารหัสสถานะของบอร์ดจึงเป็น 64 + 4 × # ของจำนวนชิ้นบนกระดาน บนบอร์ดไม่มีสิ่งใดเกิน 32 ชิ้นความยาวสูงสุดของการเข้ารหัสนี้คือ 192 บิต

ตัวอย่างเช่นการใช้การเข้ารหัสตามที่อธิบายไว้ข้างต้นสถานะเริ่มต้นของบอร์ดจะถูกเข้ารหัสเป็น (ช่องว่างแทรกเพื่อให้สามารถอ่านได้):

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

หรือเป็นเลขฐานสิบหก:

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

2
"การจำนำที่เพิ่งผ่านไปสองสแควร์ส" และ "โกงที่ไม่เคยย้าย" สามารถแชร์สล็อตสเตตเดียวกันได้เนื่องจากพวกเขาไม่สามารถใช้ร่วมกันได้ รัฐอิสระพิเศษสามารถใช้ในการเข้ารหัส "ราชาแห่งสีซึ่งเป็น"; คุณควรกำจัดบิตที่ห้อยต่องแต่งในแบบนั้นได้
FireFly

นอกจากนี้คุณยังสามารถบันทึกบิตโดยการจัดเก็บบิต 63 สำหรับบิตบอร์ดและอนุมานบิตสุดท้ายจากจำนวนผู้ชายที่เข้ารหัส (ไม่ชัดเจนสำหรับฉันว่านี่เป็นการโกงหรือไม่เพราะต้องใช้การเข้ารหัสภายนอกของความยาวของลำดับบิต) และถ้าคุณทิ้งสถานะ 6 และ 7 สำหรับผู้ชายคุณต้องเข้ารหัสสูงสุด 6 ^ 32 ซึ่งใช้เวลา 82.7 บิต การปัดเศษขึ้นเป็น 83 จะเป็นการประหยัด 13 บิตโดยใช้สถานะ 6 และ 7 และคุณสามารถเข้ารหัสข้อมูลเดียวกันนั้นใน 8 บิตเท่านั้น
Peter Taylor

ขอบคุณ @FireFly! ฉันได้ดำเนินการตามคำแนะนำของคุณแล้ว (คำแนะนำของ Peter Taylor มีประสิทธิภาพมากขึ้นแน่นอน แต่ฉันไม่ได้ใช้จนถึงตอนนี้เพราะฉันชอบการเข้ารหัสเลขฐานสองแบบธรรมดาของโครงการปัจจุบันคุณสามารถส่งเป็นรายการแยกต่างหาก ... )
Ilmari Karonen

โอเค - มันซับซ้อนเล็กน้อย แต่ได้ยินฉันออกไป หากคุณเพียงแค่กด 1 ครั้งที่ไฟเลี้ยวคุณสามารถเปลี่ยนกษัตริย์ด้วยเทิร์นด้วยชิ้นที่ฉันเรียกว่าเบี้ย 1 เปลี่ยนจำนำเป็นจำนำ 0 ตอนนี้เมื่อใดก็ตามที่มีการจำนำ (ไม่มีความเสี่ยงทางอ้อม) - คุณยังได้รับข้อมูลเล็กน้อยในชิ้นถัดไป (เช่น 0 สำหรับจำนำ 0 หรือ 1 สำหรับจำนำ 1) เนื่องจากมีเบี้ย 16 ตัวคุณจะได้รับน้อยกว่า 16 บิตสำหรับตัวบ่งชี้การเลี้ยว เมื่อใดก็ตามที่มีการจำนำที่มีความเสี่ยงต่อการสัญจรคุณต้องเพิ่มหนึ่งบิตหลังจากนั้น แต่เมื่อคนเดินผ่านต้องเกิดขึ้นทันทีกำไรขั้นต่ำของคุณคือ 14 บิต
user5957401

คุณสามารถทำสิ่งที่คล้ายกันกับบางสิ่งเช่นบิชอป สมมติว่าคุณมีอธิการที่ไม่ได้อยู่ใน 'โซนพิเศษ' (10 จุดในมุมและแถวกลางด้านข้าง) ถูกทำเครื่องหมายเป็นพิเศษ เพราะคุณรู้ตำแหน่งของมัน - คุณรู้จักอธิการ ตอนนี้คุณมีบิชอปสองตัวและสามารถให้ 0 หรือ 1 แต่ละชิ้นในชิ้นถัดไป สิ่งนี้ยอมแพ้ต่ออีก 4 บิต - แต่กรณีที่เลวร้ายที่สุดนั้นมีบิชอปอยู่ทั่วโซนพิเศษและไม่ได้กำไร
user5957401

14

กรณีที่เลวร้ายที่สุด 160 บิต

หลังจากโพสต์คำตอบก่อนหน้าของฉัน 22 ไบต์ฉันเริ่มสงสัยว่าเราจะสามารถลดลงได้ถึง 21 ไบต์ อย่างไรก็ตามเมื่อฉันเห็นปีเตอร์เทย์เลอร์ที่น่าทึ่ง 166 ไบต์ฉันคิดว่า "วางสายมันดูเหมือนว่าจะเป็นไปได้ที่จะมีคำศัพท์ 32 บิตห้าคำ!"

ดังนั้นหลังจากคิดมากฉันจึงคิดว่า: 159.91936391 ไบต์ (ค่อนข้างแน่น!) การบีบอัดในระดับนี้จะต้องใช้โปรแกรมที่ค่อนข้างซับซ้อน แต่ฉันคิดว่าจะทำให้มันทำงานได้ในเวลาที่เหมาะสม

นี่จะเป็นการโพสต์ที่ยาวนานดังนั้นโปรดอดทนกับฉันฉันจะโพสต์สิ่งที่ฉันสามารถทำได้วันนี้และเพิ่มรหัสเล็กน้อยในไม่ช้า

ดังนั้นนี่คือวิธีการ:

En Passant และ castling ถูกเข้ารหัสโดยตำแหน่งที่ผิดกฎหมาย (0 บิต)

En Passant

ดังที่ได้กล่าวไว้ในคำตอบอื่น ๆ มีช่องสี่เหลี่ยมที่เป็นไปได้สูงสุด 5 ช่องซึ่งโรงรับจำนำที่เสี่ยงต่อการถูกคนเดินผ่านยืนได้ นี่คือช่องสี่เหลี่ยมที่อยู่ถัดจากเบี้ยของผู้เล่นที่เปิดอยู่

เมื่อต้องการเข้ารหัสสิ่งนี้เบี้ยที่อ่อนไหวต่อผู้สัญจรจะถูกแลกเปลี่ยนกับสิ่งใดก็ตามที่อยู่บนหนึ่งในสี่เหลี่ยมในแถวแรกหรือแถวสุดท้าย อาจเป็นได้ทั้งชายหรือสี่เหลี่ยมจัตุรัส สิ่งนี้สร้างตำแหน่งที่ผิดกฎหมายเนื่องจากเบี้ยไม่สามารถอยู่ในแถวเหล่านี้ได้ ตัวถอดรหัสจะต้องส่งคืนตัวจำนำไปยังตำแหน่งที่ถูกต้องโดยแยกข้อมูล en passant

เพื่อไม่ให้ยุ่งเกี่ยวกับการเข้ารหัสปราสาทมันเป็นสิ่งสำคัญที่สี่เหลี่ยมที่กษัตริย์ยืนอยู่ที่จุดเริ่มต้นของเกมจะไม่ถูกรบกวนและขั้นตอนการเข้ารหัส en passant ไม่ได้วางกษัตริย์ไว้ติดกัน ซึ่งจะเป็นตำแหน่งกษัตริย์ที่ผิดกฎหมาย เพื่อตอบสนองจุดที่สองของจุดเหล่านี้ตัวเข้ารหัสมีสองตัวเลือกว่าจะให้สี่เหลี่ยมจัตุรัสทำหน้าที่แลกเปลี่ยนจำนำคนเดิน ตัวเลือกแรกสำหรับผู้ที่จำนำสูงสุด 5 คนคือ A8, B8, C8, G8, H8 ตัวเลือกที่สอง: A1, B1, C1, G1, H1

ขุน

กษัตริย์ที่ได้รับอนุญาตให้ปราสาทได้โดยนิยามยังคงอยู่ในตารางแรกของเขา เมื่อมีกษัตริย์สีขาวอยู่ที่จตุรัสเริ่มต้นของเขามีพื้นที่ทั้งหมด 63 ช่องซึ่งกษัตริย์สีดำสามารถยืนได้ 58 ซึ่งถูกกฎหมาย (เขาไม่ได้รับอนุญาตให้ย้ายไปอยู่ถัดจากกษัตริย์สีขาวเพราะเขาจะตรวจสอบตัวเอง) หากกษัตริย์สีขาวได้รับอนุญาตให้ปราสาทเขาก็ได้รับอนุญาตให้ปราสาทด้วยเกมโกงด้านซ้ายของเขาเป็นเกมขวาของเขาหรือทั้งสองอย่าง จึงมีความเป็นไปได้ที่ 3x58 = 174 ซึ่งกษัตริย์สีขาวสามารถปราสาทได้อีก 174 แห่งที่กษัตริย์สีดำสามารถปราสาทและอีก 3x3 = 9 ที่ทั้งคู่สามารถปราสาทรวมเป็น 357

มีการจัดการที่ผิดกฎหมายของกษัตริย์ทั้งสองที่ 420 อยู่ในพื้นที่สี่เหลี่ยมที่อยู่ติดกัน: 3x4 = 12 เมื่อพระราชาสีขาวอยู่ที่มุม 5x24 = 120 เมื่อเขาอยู่บนขอบและ 8x36 = 288 เมื่อเขาอยู่ในตารางอื่น ดังนั้นจึงมีตำแหน่งที่ผิดกฎหมายได้ง่ายพอที่จะเข้ารหัสความเป็นไปได้ทั้งหมดของการโยน

ถ้าอย่างน้อยหนึ่งกษัตริย์ได้รับอนุญาตให้ปราสาทตัวเข้ารหัสจะค้นหาข้อมูลปราสาทและข้อมูลตำแหน่งของกษัตริย์เหล่านั้นที่ไม่ได้รับอนุญาตให้ปราสาทในตาราง (หรืออีกวิธีหนึ่งใช้อัลกอริทึมที่ฉันจะไม่ระบุที่นี่) และผลิตผิดกฎหมาย ตำแหน่งของกษัตริย์ทั้งสอง จากนั้นจะแลกเปลี่ยนกษัตริย์กับสิ่งที่เกิดขึ้นกับสี่เหลี่ยมเหล่านี้

สิ่งสำคัญคือสิ่งนี้จะถูกเข้ารหัสหลังจากและถอดรหัสก่อนที่ผู้สัญจรจะผ่านพ้นไปไม่เช่นนั้นจะมีการรบกวนที่อาจเกิดขึ้นได้

การเปรียบเทียบ

ดังนั้นฉันยังไม่ได้ใช้บิตเลย! เมื่อดูคำตอบของปีเตอร์ฉันยังคงเข้ารหัสต่อไปนี้:

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

นี่เป็นกรณีที่เลวร้ายที่สุดของผู้ชาย 29 คน (ดูคำตอบของปีเตอร์) ด้านล่างฉันจะแสดงให้เห็นว่าฉันได้ปรับปรุงเล็กน้อย (อย่างน้อยสำหรับกรณีของผู้ชาย 29 คน) ทั้งสองประเด็นที่ระบุไว้ใน **

ช่องสี่เหลี่ยมใดที่ถูกครอบครอง / มีการเลี้ยวของใคร

วิธีที่ง่ายในการเข้ารหัสที่กำลังถูกจับคู่กับตาราง 64 บิต สิ่งนี้ยังบอกเราว่ามีจำนวนช่องว่างกี่ช่อง อย่างไรก็ตามมันค่อนข้างสิ้นเปลืองเพราะเป็นไปไม่ได้ที่จะมีพื้นที่มากกว่า 32 ช่อง ทางออกของฉันคือการใช้ 1 เพื่อเข้ารหัสสี่เหลี่ยมที่ถูกครอบครองเมื่อมันเป็นเทิร์นของไวท์และ 0 จะเข้ารหัสสำหรับสแควร์ที่ถูกครอบครองเมื่อมันเป็นเทิร์นของ Black ตอนนี้มีการใช้ชุดค่าผสมทั้งหมดและไม่ต้องเสียเปล่า

ดังนั้นเราจึงประหยัดได้นิดหน่อยสำหรับการเก็บเทิร์น: น้อยกว่า 32 1, มันคือเทิร์นสีขาว, มากกว่า 32 1, มันเป็นเทิร์นของสีดำ กรณีที่คลุมเครือเพียงอย่างเดียวคือเมื่อผู้ชายทุกคนอยู่บนกระดานและมี 32 1 และ 32 0 ดังนั้นจำเป็นต้องใช้บิตพิเศษสำหรับกรณีนี้เท่านั้น เนื่องจากไม่มีการส่งเสริมการขายจนกว่าจะมีการจับเกิดขึ้นบิตพิเศษนี้จึงไม่ส่งผลกระทบต่อกรณีที่เลวร้ายที่สุดโดยรวม (ซึ่งเกิดขึ้นกับผู้ชาย 3 คนที่เหลือ 29 คน

สีของชายที่กำลังครองพื้นที่

เรารู้จากข้างต้นว่ามีผู้ชายกี่คน สารสกัดจากสามเหลี่ยม Pascal ต่อไปนี้จะบอกถึงความเป็นไปได้มากมายที่มีสำหรับการแจกแจงที่ต่างกันของขาวดำ ตัวอย่างเช่นสำหรับผู้ชาย 3 คนความเป็นไปได้คือ: 3 ชายผิวดำ (1 การเปลี่ยนแปลง) 2 สีดำ, 1 สีขาว, (3 การเปลี่ยนลำดับ), 1 สีดำ, 2 สีขาว (3 การเปลี่ยนลำดับ), 3 สีขาว (1 การเปลี่ยนแปลง) จำนวนทั้งหมด 2 3 = 8 โดยทั่วไปสำหรับผู้ชายที่มีตัวเลขต่ำกว่าจะมีความเป็นไปได้2 n อย่างไรก็ตามความเป็นไปได้ของสีดำและสีขาวทั้งหมดนั้นผิดกฎหมาย (อย่างน้อยก็ราชาของแต่ละด้านจะต้องอยู่บนกระดาน) ดังนั้นจำนวนที่แท้จริงของการเปลี่ยนลำดับทางกฎหมายคือ 2 n -2 (ไม่สนใจ 1 ของสามเหลี่ยม Pascals)

สำหรับผู้ชายทั้งหมดมากกว่า 16 คนมีข้อ จำกัด เพิ่มเติมที่สามารถมีได้ไม่เกิน 16 คนในแต่ละสีบนกระดาน ดังนั้นเมื่อทุก 32 คนอยู่ในคณะกรรมการต้องมี 16 ของแต่ละคนและความเป็นไปได้จำนวนรวม 601,080,390 ซึ่งค่อนข้างบิตน้อยกว่า 2 32

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

จำนวนความเป็นไปได้สามารถหาได้โดยการสรุป "แถว" ของสารสกัดของสามเหลี่ยมปาสคาลนี้ (ซึ่งฉันหมายถึงเส้นทแยงมุม NE-SW ของตารางเพราะฉันหมุนสามเหลี่ยม 45 องศาทวนเข็มนาฬิกาเพื่อการนำเสนอที่สะดวกจำนวนบิตที่ต้องการ เพื่อเข้ารหัสการเปิด, สี่เหลี่ยมที่ถูกครอบครองและสีของผู้ชายจึงเป็นดังนี้:

มากถึง 25 คน: น้อยกว่า 64+ (จำนวนคน)
สำหรับผู้ชายมากกว่า 25 คน:

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

สำหรับสองสีที่ผู้ชายและในลำดับที่?

ตามคำตอบก่อนหน้านี้ไม่สามารถเลื่อนเบี้ยได้จนกว่าการจับจะเกิดขึ้นเนื่องจากการจำนำแต่ละครั้งจะถูกบล็อกโดยการจำนำสีตรงข้ามในคอลัมน์เดียวกัน คำตอบของปีเตอร์ถือว่า (เป็นขอบเขตสูงสุด) ว่าการจับกุมทุกครั้งจะนำไปสู่การเลื่อนตำแหน่งหนึ่งครั้งสำหรับการจับด้านข้างและอีกสองครั้งสำหรับการจับด้านข้าง อย่างไรก็ตามเราสามารถแบ่งออกเป็นหลายกรณี:

  1. โรงรับจำนำสีดำจับโรงรับจำนำสีขาว: ตอนนี้โรงรับจำนำมีอิสระที่จะส่งเสริมขณะที่เขาอยู่ในคอลัมน์ที่แตกต่างกัน เพื่อนร่วมงานของเขาในคอลัมน์เดียวกันยังสามารถโปรโมต จำนำสีดำในคอลัมน์ดั้งเดิมของจำนำสีขาวยังสามารถส่งเสริม นี่เป็นกรณีเดียวที่อนุญาตให้มี 3 การส่งเสริมการขาย

  2. จำนำสีดำผ่านจำนำสีขาวในคอลัมน์ที่อยู่ติดกันแล้วจับชิ้นส่วนสีขาว (นอกเหนือจากจำนำ) ด้านหลัง สิ่งนี้ช่วยให้จำนำจับและจำนำสีขาวที่อยู่ในคอลัมน์เดิมเพื่อส่งเสริม หนึ่งโปรโมชั่นสำหรับแต่ละด้าน

  3. จำนำสีขาวถูกจับเป็นชิ้น ๆ (นอกเหนือจากจำนำ) ซึ่งโดยปกติจะอนุญาตให้มีการส่งเสริมการขายหนึ่งรายการสำหรับดำเท่านั้น ข้อยกเว้นเพียงอย่างเดียวคือเมื่อมันปลดปล่อยรูปแบบการจำนำที่ถูกบล็อกซึ่งเกิดขึ้นแล้วจากการจับกุมหลายครั้งที่ย้ายเบี้ยไปไว้ในคอลัมน์เดียวกัน

ดังนั้นในกรณีพื้นฐานเราสามารถพิจารณาได้ว่าการจับแต่ละครั้งจะอนุญาตให้มีการส่งเสริมหนึ่งรายการสำหรับทั้งสองฝ่าย ในกรณีที่ชายถูกจับเป็นเบี้ยอาจมีการส่งเสริมเพิ่มเติมสำหรับด้านการจับ

ฉันได้เขียนโปรแกรมคล้ายกับของปีเตอร์ มันค่อนข้าง cruder แต่มีการเพิ่มที่สำคัญ: มันสามารถคำนวณจำนวน permutations ที่เป็นไปได้เมื่อผู้เล่นเริ่มต้นด้วยน้อยกว่า 8 เบี้ยปกติ นี่คือข้อมูลบางส่วนที่ผลิตโดยโปรแกรม:

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 เบี้ย, 15 คน, 0 โปรโมชั่น, จำนวนการเปลี่ยนลำดับจะน้อยกว่า 8 เบี้ยเพียง 16 คน, 0 โปรโมชั่น อย่างไรก็ตามหากเราพิจารณากรณีเช่น 7 เบี้ย 15 คนโปรโมชั่น 0 รายการ (ซึ่งเหมือนกับการพิจารณาว่าชายที่ถูกจับเป็นเบี้ยแน่นอน) เราได้รับการเปลี่ยนลำดับประมาณครึ่งหนึ่ง

ดังนั้นสำหรับกรณีที่ Black มี 16 คนและสีขาวมี 15 คนเราสามารถพิจารณาการประเมินขอบเขตสูงสุด 2 โปรโมชั่นสำหรับ Black และโปรโมชั่นเดียวสำหรับ White:

5383778400 x 660810150 = 3.55766E+18 possibilities

อย่างไรก็ตามเราสามารถทำได้ดีกว่าถ้าเราดำเนินการดังนี้

A. พิจารณาหนึ่งโปรโมชันสำหรับขาวดำโดยสมมติว่าชายผิวขาวที่แพ้อาจเป็นประเภทใดก็ได้:

843242400 x 660810150 = 5.57223E+17 possibilities

B. พิจารณาความเป็นไปได้เพิ่มเติมสำหรับคนผิวดำถ้าเขามีสองโปรโมชันคูณด้วยความเป็นไปได้เหล่านั้นสำหรับไวท์ซึ่งเขาเสียเงินจำนำ

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

เมื่อรวมสองตัวนี้เข้าด้วยกันเราจะได้ 2.25072E + 18 ซึ่งน้อยกว่า 3.55766E + 18 ความเป็นไปได้ทั้งหมดสำหรับการบันทึกสูงสุด 3 รายการ (เหลือ 29 คน) อยู่ด้านล่าง

(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

ดังนั้นสำหรับกรณีที่แย่ที่สุดของด้านหนึ่งที่มี 15 คนและอีก 14 คนที่มี 67.804 บิต

การเพิ่มสิ่งนี้ไปยังบิต 92.116 ที่จำเป็นเพื่อระบุสี่เหลี่ยมและสีใดที่เราได้รับทั้งหมด67.804 + 92.116 = 159.92 บิต


1
ขอขอบคุณ @Einacio สำหรับการเปลี่ยนเครื่องหมายจุลภาคเป็นทศนิยม ฉันทำตารางของฉันมากมายบน Excel ในคอมพิวเตอร์สเปนและการโพสต์สิ่งนี้เป็นงานที่ยิ่งใหญ่ดังนั้นการแก้ไขนี่เป็นสิ่งที่ฉันทิ้งไว้ในภายหลัง อย่างที่ฉันบอกว่าฉันยังไม่จบโพสต์นี้ฉันจะเพิ่มโปรแกรมการนับการเปลี่ยนลำดับของฉันและบางส่วนของรหัสเกี่ยวกับการเข้ารหัส / ถอดรหัสเมื่อฉันมีเวลา PS ฉันไม่รู้เลยว่ามีผู้คนมากมายที่อ่านข้อความนี้ :-)
ระดับแม่น้ำเซนต์

ในตอนท้ายคุณสามารถจัดการไบต์แทนบิตซึ่งเป็นสิ่งที่คุณหมายถึงซึ่งอาจทำให้ cinfusion บางอย่างแก่ผู้อ่าน
masterX244

13

177 บิตกรณีเลวร้ายที่สุด

algoritm นี้ในขณะที่แทบจะไม่ง่ายทำให้กรณีที่เลวร้ายที่สุด 177 บิต (184b = 23B ในทางปฏิบัติ), 13b (16b = 2B) สถานการณ์กรณีที่ดีที่สุดเมื่อเหลือเพียง 2 กษัตริย์

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

ดีมาก. คุณสามารถทำให้มีประสิทธิภาพยิ่งขึ้นโดยการแทนที่บิต 14-105 (92 บิต) ด้วยการเข้ารหัสตามค่าสัมประสิทธิ์ multinomial sum_{i=0}^{15} sum_{j=0}^{15} 62! / (i! j! (62-i-j)!) < 2^87.45.
Peter Taylor

สิ่งเดียวที่ฉันจะเปลี่ยนคือการสร้างเวอร์ชันที่ง่ายขึ้นสำหรับพื้นที่ที่กว้างใหญ่ ตัวอย่างเช่น: หากคุณเข้ารหัส 30 ชิ้นในฐาน 5 และมีตำแหน่งสูงสุด 5 ตำแหน่งคุณสามารถมี 5 ^ 31 <2 ^ 72 ได้ เช่นเดียวกับถ้าคุณแยกพวกเขาเป็นคู่ (13) และไม่คู่ (59) แต่ไม่มีความซับซ้อนพิเศษ
Alin Stoian

การทำเช่นนั้นจะใช้ 1 บิตเพิ่มจริง ๆ เหตุผลก็คือสามารถมีความเป็นไปได้ 5 อย่าง แต่ฉันยังต้องประกาศความเป็นไปได้สำหรับ "ไม่มีทางอ้อม" เช่นสถานะที่ 6 1 บิตพิเศษในกรณีนี้จะประกาศว่าเป็นไปได้มากหรือไม่ (และด้วยวิธีนี้ฉันสามารถใช้วิธีการที่เรียบง่ายยิ่งขึ้นด้วยการเข้ารหัส 30 ชิ้นที่ข้ามบล็อกที่ข้ามและใช้ 3 บิตแยกกันเพื่อตรวจสอบแบบอ้อมซึ่งจะ ยังนำไปสู่การใช้ +1 บิต) แถวที่ 5 ต่อไปนี้จะเปิดใช้งานผู้ที่อาจเป็น 5 คน (เทิร์นไวท์): BWBBWBBW
FIQ

ใช่คุณพูดถูก.
Alin Stoian

7

166 บิต

  • 1 บิต: เลี้ยวของใคร?
  • 2บิต: ตัวเลือกการเปิดใช้งานซึ่งเปิดอยู่ (หมายเหตุเกี่ยวกับการอ่านคำถามอย่างใกล้ชิดมีความจำเป็นเพียงบันทึกตัวเลือกสำหรับผู้เล่นที่มีเทิร์น)
  • lg 6 ~= 2.585บิต: ซึ่งการกินตัวเลือกที่มีการเปิด? (ดูคำตอบอื่น ๆ ของฉัน)
  • lg sum_{i=1}^{16} sum_{j=1}^{16} 64! / (i! j! (64-i-j)! = lg 3629590441720924477681996172 ~= 91.552 บิต: สี่เหลี่ยมที่ถูกครอบครองโดยคนที่มีสีใด?
  • อย่างlg 451366131803622235200 ~= 68.613น้อยที่สุดเพื่อระบุว่าผู้ชายคนไหนและลำดับ (ดูด้านล่าง)

การใช้การเข้ารหัสทางเลขคณิต (เนื่องจากในแต่ละขั้นตอนเราใช้การกระจายแบบสม่ำเสมอ) เราสามารถบรรลุceil(3 + 2.585 + 91.552 + 68.613) = 166บิต

การเข้ารหัสสำหรับผู้ชาย: เนื่องจากเรารู้ว่ามีผู้ชายกี่คนในสีที่กำหนดเราสามารถแจกแจงการแจกแจง / หลายชุดของผู้ชายได้อย่างง่ายดาย (เช่นมี 5 คนเราอาจมีกษัตริย์องค์หนึ่งราชินีหนึ่งสองคน Rooks และ จำนำ) และจากนั้นเราสามารถพิจารณาพีชคณิตที่เป็นไปได้ทั้งหมดของการแจกแจงแต่ละครั้ง

อย่างไรก็ตามเราสามารถทำได้ดียิ่งขึ้นโดยคำนึงถึงการพึ่งพาซึ่งกันและกัน ฉันทำสิ่งนี้ในระดับพื้นฐานมาก: มีโปรโมชันที่เป็นไปได้กี่รายการ จำนำสามารถกลายเป็น "ผ่าน" และสามารถส่งเสริมในสามวิธี: จับและย้ายไปยังคอลัมน์ที่แตกต่างกัน หรือจับตัวประกันจำนำของมันและเพื่อย้ายเข้าไปในคอลัมน์ที่แตกต่างกัน; หรือจำนำปฏิปักษ์ของมันถูกจับ ดังนั้นการจับภาพสีขาวอาจสร้างเบี้ยที่ผ่านไปสองใบสำหรับสีขาวและอีกอันสำหรับสีดำ

เราสามารถสร้างตารางบางส่วนของขอบเขตบนของโปรโมชั่น:

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

นอกจากนี้เรายังสามารถคำนวณจำนวนการเปลี่ยนลำดับเนื่องจากผู้เล่นมีNผู้ชายและไม่ต้องPจำนำมากกว่า:

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

เมื่อรวมทั้งสองเข้าด้วยกันเราจะได้จำนวนบิตที่ต้องการเพื่อระบุการเปลี่ยนลำดับทั้งสองที่กำหนดจำนวนผู้ชายทั้งสองด้าน:

           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

หากมันไม่ได้อยู่ในตารางนี้เราสามารถสรุปได้ว่าทั้งสองฝ่ายมีโปรโมชันสูงสุด 8 รายการและเรายังคงทำได้ดีกว่ากรณีที่แย่ที่สุดคือ 68.613 บิตเมื่อหนึ่งมี 14 คนและอีก 15 คนมี

โปรดทราบว่านี่ยังห่างไกลจากการเป็นตัวแทนที่สมบูรณ์แบบเพราะมันช่วยให้ตำแหน่งที่ผิดกฎหมายจำนวนมาก

รหัสสำหรับการคำนวณตารางการเปลี่ยนแปลง:

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

    }
}

คุณสรุปตำแหน่งของกษัตริย์ได้อย่างไร คุณใช้ผู้ชาย 15 คนในการคำนวณของคุณและไม่มีบิตพิเศษสำหรับตำแหน่งกษัตริย์
Alin Stoian

@AlinStoian อ๊ะ ฉันมี<มากกว่า<=ในวงเอาท์พุทของโปรแกรมของฉัน ขอบคุณที่ชี้นำ ฉันยังสามารถกู้คะแนนก่อนหน้านี้ได้โดยการใส่เคสพิเศษทั้ง 32 คนบนกระดาน แต่ตอนนี้ฉันจะไม่ทำเช่นนั้น
Peter Taylor

ข้อมูลที่น่าสนใจ! กรณีเลวร้ายที่สุดทางทฤษฎีที่มีผู้ชาย 3 คนถูกจับกุม
เลเวลริเวอร์เซนต์

@ สตีฟเวอร์ริลล์สิ่งที่ฉันอยากทำจริงๆคือเข้ารหัสตำแหน่งเบี้ยและจำนวนโปรโมชันใน "บล็อก" หนึ่งรายการจากนั้นตำแหน่งชิ้นส่วนและค่านิยม อย่างไรก็ตามมีตำแหน่งจำนำอย่างน้อย 2 ^ 38 โดยไม่คำนึงถึงการส่งเสริมการขายและการระบุพวกเขาอย่างมีประสิทธิภาพทำให้ฉันรอดพ้นไปได้แล้ว
Peter Taylor

@petertaylor หากคุณมีเบี้ยเพียง 16 ตัวบนกระดานซึ่ง จำกัด ไว้ที่ 48 ตารางเมตรคุณมี 48! / 32! / 8! / 8! = 8,819905518636890 มากกว่า 2 ^ 54 เล็กน้อย! ของเหล่านี้บางอย่างผิดกฎหมายคุณไม่สามารถมีเบี้ยทั้งหมดของสีเดียวที่ด้านหนึ่งของกระดาน
เลเวลริเวอร์เซนต์

5

กรณีที่แย่ที่สุด 178 บิต (174 นิดหน่อย!)

สวัสดีเพิ่งกลับไปเขียนโปรแกรมซึ่งฉันไม่ได้ทำตั้งแต่เรียนมหาวิทยาลัยจริงๆ ฉันเห็นไซต์นี้และคิดว่าสิ่งนี้ดูน่าสนใจ ฉันทำการตรวจสอบทางประสาทวิทยาเล็กน้อยและปรากฏว่าอย่างน้อย 146 บิตเป็นสิ่งจำเป็นสำหรับอัลกอริธึมที่สมบูรณ์แบบอาจจะค่อนข้างมากกว่านี้เล็กน้อย (ฉันจะอธิบายในความคิดเห็นเมื่อฉันมีเวลา)

อย่างไรก็ตามนี่คือวิธีที่ฉันจัดโครงสร้างข้อมูล แนวคิดพื้นฐานมาที่ 178 บิต แต่ด้วย pokery jiggery บางมันสามารถนำมาลง 174 (นั่นคือ 21 3/4 bytes) โปรแกรม 175 นั้นง่ายกว่าเล็กน้อยสามารถอ่านได้ง่ายกว่ามนุษย์และยังอยู่ในระยะ 22 ไบต์

A)ตำแหน่งของกษัตริย์ทั้งสอง: 6 บิตสำหรับขาวและดำ12 BITS

B)ของสี่เหลี่ยม 62 ที่เหลือซึ่งถูกครอบครอง? เมทริกซ์62 BITS

C)มันเลี้ยวไปไหน? 1 BIT

ยอดรวมทั้งหมด: 75 BITS

D) En Passant หากตาขาวเคลื่อนที่ไปได้เบี้ยสีดำมากถึง 5 ตัวอาจดูเหมือนว่าพวกมันจะถูกจับ En Passant เบี้ยสีดำจะต้องอยู่ในแถวที่ 5 (จากล่างขึ้นบนเริ่มต้นที่ศูนย์) และมีจำนำสีขาวอยู่ข้างๆ สถานการณ์หนึ่งที่มีจำนวนการจับกุมที่เป็นไปได้สูงสุดจะเป็นดังนี้

BWBBWBBW

หากมีเบี้ยสีดำ 6 ตัวในแถวที่ 5 สีขาวจะมีเพียง 2 สี่เหลี่ยมที่จะยืนและสามารถคุกคามเบี้ยสีดำได้เพียง 4 ตัวดังนั้นจึงไม่สามารถมีเบี้ยสีดำได้มากกว่า 5 ตัวภายใต้การคุกคามจาก En passant ในเวลาเดียวกัน ดังนั้นเราจำเป็นต้องมีหมายเลข 1 ถึง 5 เพื่อระบุว่าเบี้ย (ขึ้นไป 5) ในแถว 5 ที่มีศัตรู (ในกรณีนี้สีขาว) จำนำถัดจากมันเป็นขั้นสูง 2 สี่เหลี่ยมในรอบสุดท้าย ( หรือศูนย์ถ้าไม่มีจำนำ ในสถานการณ์นี้ถูกย้ายในลักษณะนี้ในเทิร์นสุดท้าย)

E) ของพื้นที่สี่เหลี่ยมที่ถูกครอบครองมากถึง 30 (ไม่รวมราชา) พวกมันมีอะไร

มีความเป็นไปได้ 10 ข้อแต่ละค่าจะแสดงเป็นจำนวนทศนิยม

บิตที่มีนัยสำคัญน้อยที่สุดแสดงถึงสี

ดังนั้นตัวเลขจึงเป็นสีขาวตัวเลขคี่จะเป็นสีดำ

ขาวดำ

จำนำ 0/1 (หรือโกงที่ได้รับอนุญาตให้ปราสาท *)

อัศวิน 2/3

อธิการ 4/5

โกง 6/7

ราชินี 8/9

* rook ที่อนุญาตให้ปราสาท (และไม่เคยถูกย้ายจากแถวแรกหรือแถวสุดท้าย) ถูกแทนด้วย 0 หรือ 1 แทน 6 หรือ 7 มันไม่สามารถสับสนกับเบี้ยได้เพราะไม่สามารถพบเบี้ยบนแรกได้ หรือแถวสุดท้าย

นี่จะให้จำนวนทศนิยมสูงสุด 30 หลักซึ่งเราสามารถคูณด้วย 6 แล้วเพิ่มรหัสสำหรับ En passant จำนวนที่เกิดจะพอดีกับ 103 บิตซึ่งเมื่อเข้ามา 75 ดังกล่าวข้างต้นเป็น 103 + 75 = 178 บิต ที่จริงแล้วถ้าเราคูณด้วย 10 แทน 6 มันก็ไม่ได้ทำให้จำนวนบิตที่ใช้แตกต่างกันและการถอดรหัสนั้นง่ายกว่า

นี่เป็นเพียง 2 บิตมากกว่า 22 ไบต์ อย่างไรก็ตามเราสามารถกดลงไปที่ 174 bits ดังที่อธิบายไว้ด้านล่าง

หากไม่มีการจับชิ้นส่วนจะไม่สามารถเลื่อนตำแหน่งได้

หลักฐานมีดังนี้ ลองนึกภาพสีขาวหมกมุ่นอยู่กับการส่งเสริมการจำนำของเขาใน (เช่น) คอลัมน์ E จากจุดเริ่มต้นของเกม มีเบี้ยสีดำตรงข้ามกับตัวจำนำนี้ที่อยู่ระหว่างทาง ดังนั้นเพื่อส่งเสริมการจำนำนี้อย่างใดอย่างหนึ่งต่อไปนี้จะต้องเกิดขึ้น:

1) จำนำดำถูกจับ

2) โรงรับจำนำสีดำจับชิ้นส่วนอื่นและดังนั้นจึงย้ายออกจากทาง

3) จำนำสีขาวจับจำนำในคอลัมน์ที่อยู่ติดกันเช่นคอลัมน์ D

4) จำนำสีขาวผ่าน (หรือผ่าน) จำนำสีดำในคอลัมน์ที่อยู่ติดกันแล้วจับชิ้นส่วนในคอลัมน์ที่อยู่ติดกันเดียวกันที่ทำให้เกิดจำนำสีขาวเพื่อเปลี่ยนคอลัมน์

กรณีที่ 4 เป็นสิ่งที่น่าสนใจที่สุดเพราะมันไม่ใช่แค่จำนำสีขาวที่เริ่มต้นในคอลัมน์ E ซึ่งตอนนี้มีเส้นทางที่ชัดเจนในการโปรโมต จำนำสีดำในคอลัมน์ที่ยังคงอยู่ในคอลัมน์ E ยังสามารถส่งเสริม ดังนั้นการจับภาพครั้งเดียวสามารถล้างวิธีสำหรับการจำนำหนึ่งสีของแต่ละสีเพื่อส่งเสริม

อย่างไรก็ตามความจริงที่ว่าไม่มีการจำนำสามารถเลื่อนจนกว่าจะมีการจับชิ้นหนึ่งหมายความว่าเราไม่จำเป็นต้องเก็บชิ้นส่วนที่ 30 เราสามารถทำมันออกมาได้ด้วยการกำจัด (หรือโดยการลบเพราะเซตของรหัสชิ้นที่สมบูรณ์เมื่อเริ่มเกมเพิ่มขึ้นเสมอในจำนวนเดียวกัน = 80)จุดเล็ก ๆ จุดหนึ่งคือเราต้องมั่นใจว่าสี่เหลี่ยมที่ rooks ยืนที่จุดเริ่มต้นของเกมอยู่ในหมู่สแกนครั้งแรก (เพราะถ้าพวกเขาล่าสุดเราจะไม่ทราบว่าโกงสามารถปราสาทหรือไม่) สิ่งนี้ทำได้ง่ายโดยการสแกนแถว 0 แล้วแถว 7 ถึง 1: สำหรับ r = แถวสแกน 8 ถึง 1 [r mod 8]

ดังนั้นเมทริกซ์ของบิตใน (B) จะบอกเราว่ามีกี่ชิ้น (ไม่รวมราชา) หากมีเต็ม 30 ให้ละเว้นชิ้นสุดท้ายเมื่อเข้ารหัสตัวถอดรหัสจะทำงานตามที่มันเป็น ตอนนี้เรามีตัวเลขทศนิยมสูงสุด 29 หลักซึ่งเราคูณด้วย 6 และเพิ่มไปยังรหัส En Passant จำนวนผลลัพธ์จะบีบเป็น 99 บิตโดยให้ผลรวม 99 + 75 = 174 บิต

ดังตัวอย่างนี่คือตำแหน่งจริง ขาวเพิ่งจะย้ายครั้งแรกของเขา (จำนำของกษัตริย์ขั้นสูง) และมันเป็นตาดำ

rnbqkbnr
pppppppp


    P

PPPP PPP
RNBQKBNR

A) ตำแหน่งของราชา(ขาว / ดำเป็นฐานแปด, 12 บิต ): 03 73 = 000011 111011

B) ช่องสี่เหลี่ยมใดบ้าง เริ่มต้นด้วยแถวศูนย์ (แถวล่าง) จากนั้นแถวอื่น ๆ ทั้งหมดจากบนลงล่างข้ามกษัตริย์:

1111 111

1111 111
11111111
00000000
00000000
00001000
00000000
11110111 

C) เทิร์นของ Black: Turn Bit = 1

D) En Passant ไม่มีเบี้ยสีขาวติดกับตัวจำนำสีดำดังนั้นจึงไม่มีเบี้ยจำนำใด ๆ ที่สามารถพาคนเดินผ่านได้ (แม้ว่าเบี้ยนี้จะเลื่อนไปก่อนหน้านี้แล้ว) ดังนั้น D = 0 หากแทนที่จะพิจารณาเพียงเบี้ยที่มีศัตรูจำนำอยู่ข้างเราพิจารณาเบี้ยทั้งหมดที่ไม่มีชิ้นมิตรข้างพวกเขาทั้งสองข้างแล้ว D จะเป็น 1 เนื่องจากมีเบี้ยตัวหนึ่งในสถานการณ์เช่นนี้และโดยเฉพาะ จำนำถูกย้ายในรอบสุดท้าย

E) อีกครั้งแถวด้านล่างก่อนจากนั้นแถวอื่น ๆ ทั้งหมดจากบนลงล่างข้ามกษัตริย์และมี rooks ที่ไม่ได้คาสติ้งสี่ตัวเรียกว่า 0 หรือ 1 (ตัวเลขปกติสงวนไว้สำหรับเบี้ย)

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

สามารถลบทิ้งเลข 30 หลัก (ในวงเล็บ)

แม้ว่าจะไม่ปรากฏชัดเจนมากนักการจำนำที่ White มีความก้าวหน้านั้นแท้จริงแล้วอยู่ที่ปลายด้านหนึ่งของรายการเบี้ยเนื่องจากเราสแกนทีละแถว

ขณะนี้ข้อมูลของเรามีลักษณะเช่นนี้โดยมี 29 รหัสสำหรับเนื้อหาของช่องสี่เหลี่ยมรวมถึงรหัส En Passant:

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

เป็นการดีที่สุดในการสแกนจากขวาไปซ้ายเมื่อถอดรหัสและจากซ้ายไปขวา (เรียงกลับกัน) เมื่อทำการเข้ารหัส ซึ่งหมายความว่าเมื่อมีชิ้นส่วนน้อยเราจะมีจำนวนน้อยลงในขณะที่รักษาความสอดคล้องสูงสุด (เช่นเราต้องการให้ช่องว่าง / เลขศูนย์นำหน้าไม่ใช่ส่วนท้ายเพื่อเปิดใช้งานการบีบอัดของบอร์ดที่ยึดครองเบาบาง) เมื่อเรามีเพียง 2 ราชา บนกระดานเราจะมี 75 บิตดังกล่าวข้างต้นบวก 3 บิตเพื่อเก็บข้อมูล en passant = 78 บิตในกรณีที่ดีที่สุด ชิ้นส่วนเพิ่มเติมแต่ละชิ้นจะมีขนาดต่ำกว่า 3.5 บิต (สามารถเก็บ 2 ชิ้นใน 7 บิตเนื่องจาก 100 <128)

มีปัญหาในทางปฏิบัติที่ว่าจำนวนเต็ม 99 บิตมีขนาดใหญ่เกินไปที่จะพอดีกับตัวแปรจำนวนเต็ม 64 บิตซึ่งหมายความว่าภาษาการเขียนโปรแกรมจำนวนมากไม่ให้การสนับสนุน (คุณไม่สามารถแปลงการแทนค่าสตริงเป็น 29-30 หลักได้ number เป็นจำนวนเต็ม) เป็นวิธีที่ง่ายในการเข้ารหัส 22 ไบต์เราสามารถแบ่งตัวเลข 30 หลัก (29 รหัสรหัส + รหัส passant) เป็นสอง 15 หลักตัวเลขแต่ละซึ่งจะพอดีใน 50 บิตแต่ละ (รวม 100 บิต บวก 75 ที่กล่าวถึงข้างต้นทำให้ 175 บิตกรณีที่เลวร้ายที่สุด)

สำหรับการบีบอัดสูงสุดตามที่ระบุไว้ข้างต้น 29 หลักทศนิยมบวกรหัส En Passant (6 ค่าที่เป็นไปได้) จะพอดีกับ 99 บิต (รวมเป็น 174 บิต)แต่ไม่สนับสนุนภาษาสำหรับจำนวนเต็มที่มีขนาดนี้ ซับซ้อนในการเขียนโปรแกรม อาจเป็นการง่ายกว่าที่จะแยกบิต 29 สีออกและทำงานกับรหัสชิ้นส่วน (5 ความเป็นไปได้) และรหัส En passant (6 ความเป็นไปได้) แยกต่างหากจากสี (70 บิตเกือบเหมาะกับตัวแปร 64 บิต)


เคล็ดลับดีกับชายคนสุดท้าย
ปีเตอร์เทย์เลอร์

5

นี่คือวิธีแก้ปัญหากรณี 181 บิตที่แย่ที่สุด

โฟกัสที่นี่เป็นโปรแกรมง่ายๆที่คุณสามารถเข้าใจได้ง่าย

ข้อมูลที่ป้อนคือ FEN นี่คือตำแหน่งเปิดมีหกฟิลด์ (ละเว้น 5 & 6):

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

สนามแรก (ตำแหน่งชิ้นขึ้นไป) จะแยกกัน

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

ผลิต:

rnbqkbnrpppppppp________________________________PPPPPPPPRNBQKBNR

สนามที่หนึ่ง: เข้ารหัสตำแหน่งของกษัตริย์ (12 บิต):

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

ฟิลด์ที่สอง: เข้ารหัสชิ้น (สูงสุด 5 บิตต่อชิ้น):

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

ฟิลด์ที่สาม: สีที่ใช้งาน (1 บิต)

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

ฟิลด์ที่สี่: ความพร้อมใช้งานของการหล่อ (4 บิต)

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

ฟิลด์ที่ห้า: en passant (ศูนย์หรือ 3 บิต)

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

ไร้เดียงสากรณีที่เลวร้ายที่สุด 200 บิต

  • ตำแหน่งกษัตริย์สองตำแหน่ง- 12 บิต
  • คณะกรรมการ
    • QRRBBNN QQQQQQQQ - 75 บิต
    • qrrbbnn qqqqqqqq - 75 บิต
    • ช่องสี่เหลี่ยมว่าง- 30 บิต
  • สีที่ใช้งาน- 1 บิต
  • Castling - 4 บิต
  • En Passant - 3 บิต

กรณีที่เลวร้ายที่สุดที่เกิดขึ้นจริง

ผู้เล่นแต่ละคนไม่สามารถส่งเสริมเบี้ยทั้งหมดโดยไม่ต้องจับชิ้นอื่นนี่คือผลของเอนโทรปีของการจับชิ้น:

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

ดังนั้นจริงๆแล้วบอร์ดกรณีเลวร้ายที่สุดคือ:

  • QRRBBNN QQQQQQQQ - 75 บิต
  • qrrbbnn qqqq - 55 บิต
  • ช่องว่างเปล่า- 34 บิต

กรณีที่เลวร้ายที่สุดคือการส่งเสริมทุกชิ้นแทนที่จะปล่อยให้จำนำสำหรับ en passant

จำนวนที่เกิดขึ้นจริงทั้งหมดกับ SHOWN CODE 12 + 75 + 55 + 34 + 1 + 4 = 181 bits

FIQ แสดงการปรับปรุงสองแบบสำหรับชุดรูปแบบที่เรียบง่าย แต่รหัสเหล่านี้ยากขึ้น:

  • ลบบิต 2 จากการเข้ารหัสชิ้นในแถวที่ 1 และ 8 เนื่องจากเบี้ยไม่สามารถไปที่นั่นได้ (ประหยัดมากถึง 16 บิต)
  • ใช้เบี้ยเพื่อเข้ารหัส rooks ที่สามารถ castable ได้ (ประหยัด 4 บิต)

รหัสที่เหลืออยู่เท่านั้นที่ไม่แสดงในคำตอบนี้ (สำหรับความกะทัดรัด) คือ: การแบ่ง FEN อินพุตในฟิลด์ ( split /\s/) และการกำหนดตัวแปร


ผู้เล่นสามารถส่งเสริมเบี้ยทั้งหมดของเขา (ระบุว่าเขาสามารถจับเบี้ยของศัตรู); Qn4QQ / Qb6 / Qq1k4 / Qr6 / Qb6 / Qr6 / Qn4NK / RNB2B1R b - - 0 84
Krzysztof Szewczyk

@KrzysztofSzewczyk ใช่ว่ามีการระบุไว้ข้างต้นที่PPpp=>QQq_
William Entriken

4

ข้อมูลทั้งหมดต้องการ 33 ไบต์

(ต้องขอบคุณใครบางคนในความคิดเห็นที่ฉันรู้ว่านี่ไม่ได้ผลสำหรับการเลื่อนตำแหน่งจำนำจะอัปเดตเมื่อฉันสามารถแก้ไขได้)

สำหรับไบต์แรกเราใช้ห้าบิต:

  • บิตแรก: เทิร์นของผู้เล่น 1 = สีขาว
  • บิตที่สอง: ปราสาทกษัตริย์ด้านดำ 1 = ปราสาทสามารถ
  • บิตที่สาม: ปราสาทราชินีด้านดำ 1 = ปราสาทสามารถ
  • บิตที่สี่: ปราสาทกษัตริย์ด้านสีขาว 1 = ปราสาทสามารถ
  • บิตที่ห้า: ปราสาทราชินีด้านสีขาว 1 = ปราสาทสามารถ

32 ไบต์ถัดไปจะถูกใช้เพื่อเป็นตัวแทนของแต่ละชิ้นหมากรุกตามลำดับที่กำหนดไว้ล่วงหน้า

  • 3 บิต: แสดงถึงแถว
  • 3 บิต: แทนคอลัมน์
  • 1-bit: แทน en-passant, 1 = สามารถ en-passant
  • 1-bit: ถ้า "สามารถ en-passant" bit เป็น 1: หมายถึงด้านใดด้านหนึ่ง 0 = left
    จะแสดงว่าถูกจับหรือไม่ 0 = ไม่ถูกจับ
    (ถ้าสามารถผ่านได้ก็จะไม่ถูกบันทึกอย่างแน่นอน)

รหัส C บางตัวที่ใช้แทนแนวคิดนี้

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 นี่ไม่ใช่คำตอบ ...
Doorknob

1
คำสั่งซื้อที่กำหนดไว้ล่วงหน้าของคุณจะไม่ถูกใช้งานมากนักเมื่อเบี้ยถึงอันดับแปดและได้รับการเลื่อนตำแหน่งให้เป็นอัศวินบิชอปโกงหรือราชินี
ossifrage คลื่นไส้

@Doorknob ของ Snow ok ฉันทำงานเกี่ยวกับอัลกอริทึมมันเป็นเพียงเล็กน้อยในตอนกลางคืนและฉันเหนื่อยดังนั้นฉันทำมันช้าลงเล็กน้อย
ace_HongKongIndependence

ถ้าอย่างนั้นทำไมคุณถึงโพสต์สิ่งนี้ถ้าคุณไม่มีทางออก?
ลูกบิด

3
หากคนของคุณยังคิดว่าคำตอบนี้ไร้สาระและไม่มีค่าที่นี่ให้ไปข้างหน้าและลงคะแนนเพื่อลบและโหวตมันและคุณอาจลบบัญชีของฉันที่นี่ ฉันแค่อยากจะแบ่งปันสิ่งที่ฉันคิดว่าทำไมพวกคุณถึงต้องเป็นเช่นนั้น?
ace_HongKong การพึ่งพากัน

4

256 242 บิต

ต่อไปนี้เป็นอัลกอริทึมการบีบอัดขั้นพื้นฐานที่อาจปรับปรุงได้เนื่องจากไม่ได้ยกเว้นตำแหน่งที่ผิดกฎหมายบางอย่างจากการถูกแสดง

บอร์ดเริ่มต้นด้วยข้อมูลส่วนหัว 5 บิตดังนี้:

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

จากนั้นสตริง 12 บิตแสดงถึงตำแหน่งของราชา

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

จากนั้นตัวเลข 64 หลักขนาดใหญ่ในฐาน 11 ซึ่งจะถูกคูณด้วย 9 เพื่อเพิ่มตัวเลขอื่นในตอนท้ายที่แสดงถึงสถานะของผู้ผ่านการทดสอบ ตัวเลขแต่ละตัวในฐาน 11 แทนตารางในกระดานโดยมีค่าที่เป็นไปได้ดังต่อไปนี้:

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.

และตัวเลขในฐาน 9:

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

11 64 × 9 ประมาณ 2 224.57ซึ่งต้องการ 225 บิตในการเข้ารหัส บวกส่วนหัว 17 บิตที่ด้านบนมีทั้งหมด 242 บิต


ขอบคุณ ugoren สำหรับการปรับปรุง


สิ่งนี้คล้ายกับอัลกอริธึมของ ace แต่ใช้ตำแหน่งกระดานแทนชิ้นส่วนตามลำดับที่กำหนดไว้ล่วงหน้าซึ่งทั้งคู่แยกออกจากปัญหาการเลื่อนตำแหน่งและช่วยให้ข้อมูลถูกสับออกไปเล็กน้อย
Joe Z.

คุณสามารถบันทึก en-passant เป็นตัวเลขหนึ่งระหว่าง 0 และ 8 (ซึ่งผู้เล่นปัจจุบันสามารถจับภาพ en-passant ได้ไหม 13^64 * 9คือ 239.99, ประหยัด 11 บิต ประหยัดมากขึ้นโดยการเข้ารหัสตำแหน่งกษัตริย์แยกต่างหาก
ugoren

ตาม Doorknob of Snow ที่แสดงความคิดเห็นในโพสต์ของฉันคำตอบแบบนี้คือ "ไม่ใช่คำตอบ" แค่พูด. FYI ความคิดเห็นของเขาถูกโพสต์ก่อนที่ฉันจะเพิ่มรหัส C ในคำตอบของฉัน
ace_HongKong การพึ่งพากัน

@ugoren: ฉันลืมไปแล้ว คุณพูดถูกฉันลืมไปว่ามีคนจำนำเพียงคนเดียวเท่านั้นที่สามารถเข้าร่วมในเวลาเดียวกันได้
Joe Z.

@ace: คำตอบของคุณไม่ถูกต้องเนื่องจากไม่มีรหัสการเข้ารหัสและถอดรหัส มันไม่ถูกต้องเพราะมันไม่ได้คำนึงถึงกรณีการส่งเสริมการจำนำ ปัญหาหลักของมันจะถามหารูปแบบการเข้ารหัสข้อมูล โปรแกรมนี้เป็นเพียงส่วนต่อประสานกับสิ่งนั้น
Joe Z.

3

? เกร็ด

(worst 217 กรณีที่เลวร้ายที่สุด, 17 กรณีที่ดีที่สุด, 179 สำหรับบอร์ดเริ่มต้น)


คำอธิบายการเข้ารหัส

ข้อมูลเมตาเพิ่มเติมประกอบไปด้วยการเปิดซึ่งเป็น (หนึ่งบิต) และปราสาท (สี่บิตคือปราสาทสีขาวอาจในด้านของกษัตริย์ในด้านราชินีและคล้ายกันสำหรับสีดำ)

สำหรับตำแหน่งกระดานเราเข้ารหัสเป็นชุดของชิ้นส่วนที่ใช้งานอยู่ อันที่จริงเราตรวจสอบให้แน่ใจว่าได้แจกแจงชิ้นส่วนตามลำดับโดยเฉพาะอย่างยิ่งด้วยเหตุผลที่ฉันจะอธิบายในไม่ช้า สำหรับแต่ละชิ้นเราเก็บสีของมัน (หนึ่งบิต) ชนิดของมัน (สามบิตเพื่อรวม 6 ชนิดบวกอีกหนึ่งชนิดพิเศษสำหรับ "จำนำที่อาจต้องดำเนินการโดย en passant") เช่นเดียวกับตำแหน่งของมัน

นี่คือส่วนที่น่าสนใจ: ในการเข้ารหัสตำแหน่งของชิ้นส่วนแทนที่จะเก็บไว้เป็นพิกัดเราจะจัดเก็บระยะห่างสัมพัทธ์จากชิ้นสุดท้ายเมื่อระบุจำนวนชิ้นในลำดับจากซ้ายไปขวาบนลงล่าง (เช่น A8 , B8, ... , G1, H1) นอกจากนี้เราจัดเก็บระยะทางเป็นหมายเลขความยาวผันแปรโดยใช้1เพื่อหมายความว่าชิ้นส่วนนี้อยู่ถัดจากก่อนหน้า0xxสำหรับการข้าม 1-3 ชิ้น000xxxสำหรับการข้าม 4-10 ชิ้น000000xxxxสำหรับ 11-25 0000000000xxxxxสำหรับ 26-56 และสุดท้าย000000000000000xxxสำหรับ 57-62

ตัวอย่าง

ฉันทำส่วนหนึ่งของบางตำแหน่งที่เข้ารหัสด้วยการเข้ารหัสนี้และใส่คำอธิบายประกอบสำหรับตำแหน่งเริ่มต้นพร้อมความคิดเห็นบางส่วน

ฉันไม่ทราบวิธีการวิเคราะห์ขนาดบิตที่แย่ที่สุด แต่ไปตามตัวอย่างในส่วนสำคัญฉันเชื่อว่าอัลกอริทึมควรมีประสิทธิภาพค่อนข้างน้อย


การใช้งานตัวถอดรหัส

ด้านล่างเป็นตัวถอดรหัสที่รวดเร็วและสกปรกสำหรับการเข้ารหัสนี้ (ใช้เป็นข้อมูลไบนารี่ที่เข้ารหัสในข้อความเช่นเดียวกับในตัวอย่างข้อเขียนข้างต้นและข้ามสิ่งที่ไม่ใช่ '0' หรือ '1') สร้างบอร์ดหมากรุกยูนิโคดเพื่อ stdout

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

ฉันไม่รู้ว่าการนับบิตที่แย่ที่สุดของคุณคืออะไร แต่ฉันสงสัยว่ามันมีมากกว่า 179 บิต ตัวอย่างเช่นอัลกอริทึมของคุณจัดการเค้าโครงนี้อย่างไร (มันเป็นที่ถูกต้องโดยวิธีการที่ผมทำมันโดยใช้โปรแกรมแก้ไขที่chess.com )
ossifrage คลื่นไส้

@squeamishossifrage ที่ดูเหมือนว่าจะต้องใช้ 217 บิต: gist.github.com/FireyFly/8639791 (ขอบคุณสำหรับกรณีทดสอบฉันต้องการลองด้วยเล่ห์เหลี่ยม!)
FireFly

เฮ้นั่นไม่เลวเลย ทำต่อไป!
ossifrage คลื่นไส้

2

สูงสุด: 184 บิตขั้นต่ำ: 75 บิต

ฉันได้รับแรงบันดาลใจจากการเข้ารหัส Huffman ของ @ AdamSpeight สำหรับชิ้นส่วนที่จะลองสร้างโครงร่างของฉันเอง ฉันสงสัยว่ามันจะชนะ แต่ก็มีข้อ จำกัด ที่คำนวณได้

โครงการนี้ปฏิบัติต่อชิ้นหมากรุกราวกับว่ามี 11 ประเภทที่แตกต่างกัน ฉันประมาณตามอัลกอริทึมการเข้ารหัส Huffman เพื่อจัดกลุ่มคลาสเหล่านี้ตามความถี่และชนิดของจริงเพื่อสร้างการเข้ารหัสต่อไปนี้:

 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

โค้ดของแต่ละชิ้นสามารถนำหน้าด้วยสองบิตเพื่อแสดงให้เห็นว่าทีมใดเป็นของมัน ( 10สำหรับสีขาว11สำหรับสีดำ) 0สามารถใช้ในการเข้ารหัสช่องว่าง ความคิดเหล่านี้ช่วยให้เราสามารถสร้างการเข้ารหัสแบบสี่เหลี่ยมต่อตารางสี่เหลี่ยมสำหรับทั้งบอร์ดโดยใช้ขั้นตอนที่เราต้องการ ฉันจะถือว่าคำสั่งการทำซ้ำa1, b1, c1, ... f8, g8, h8ฉันจะถือว่าการสั่งซื้อซ้ำซึ่งหมายความว่าเพียงแค่แสดงรหัสเหล่านี้ตามที่แสดงด้านบนเข้ารหัสข้อมูลทั้งหมดยกเว้นว่าเป็นรหัส เอ็นจิ้นหมากรุกที่ง่ายมากสามารถใช้ "คลาส" สำหรับการจำนำ, rooks และพระมหากษัตริย์เพื่อพิจารณาว่าการขว้างและการขว้างเป็นสิ่งที่ถูกกฎหมายหรือไม่ นอกจากนี้รูปแบบนี้จัดการโปรโมชั่นจำนำได้อย่างง่ายดาย หากผู้เล่นโปรโมตการจำนำเป็นโกงทั้งรหัสกษัตริย์หรือราชินีอาจถูกนำมาใช้ตราบใดที่ตัวแปร "ย้าย" ถูกเลือก

ยกเว้นตำแหน่งทางพยาธิวิทยาที่ฉันไม่คิดว่าจะเกิดขึ้นสถานการณ์สมมติที่เลวร้ายที่สุดสำหรับการเข้ารหัสนี้คือเมื่อทุกส่วนยังคงอยู่บนกระดานและผู้เล่นคนก่อนย้ายไปจำนำสองช่องว่าง ตัวอย่างเช่นบอร์ดด้านล่างเข้ารหัส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

ซึ่งหมายความว่าการเข้ารหัสที่เลวร้ายที่สุดมี 184 บิต: 1 เพื่อระบุผู้เล่น, 32 สำหรับพื้นที่ว่างเปล่า, 45 สำหรับเบี้ยไม่ไหวติง, 6 สำหรับเบี้ยสองกระโดดอวกาศ, 24 สำหรับอัศวิน, 24 สำหรับอัศวิน, 28 สำหรับ rooks 12 สำหรับ queens และ 12 สำหรับ kings

เมื่อชิ้นส่วนเคลื่อนที่ไปและถูกจับขนาดของการเข้ารหัสจะลดลง สถานการณ์กรณีที่ดีที่สุดจะถูกแสดงโดยกษัตริย์สององค์เพียงคนเดียวบนกระดาน: 1 บิตสำหรับการระบุผู้เล่น + 62 บิตสำหรับการระบุสี่เหลี่ยมที่ว่างเปล่า + 12 บิตเพื่อระบุว่ากษัตริย์ให้ความยาวขั้นต่ำ 75 บิต

ฉันจะกลับมาและแก้ไขการตอบสนองนี้ด้วยรหัสที่แสดงให้เห็นถึงการเข้ารหัสนี้ในการดำเนินการในวันนี้หรือวันพรุ่งนี้ สำหรับตอนนี้ฉันอยากรู้ว่าคนอื่นคิดอย่างไรกับการเข้ารหัสนี้


1
คุณสามารถบันทึกบิตในรูค คุณสามารถกำหนดราชินี - และฝั่งกษัตริย์ขึ้นอยู่กับตำแหน่งและคุณไม่จำเป็นต้องรู้ว่าด้านใดที่มีการย้ายมา ดังนั้นคุณเพียงแค่ต้องการข้อมูลหนึ่งบิตเกี่ยวกับเกมโกง - ย้ายหรือไม่ไหวติง
ไม่ใช่ Charles

... และที่จริงแล้วการจัดเก็บข้อมูลในระดับชิ้นนั้นง่ายกว่าในการเข้ารหัส / ถอดรหัส แต่ถ้าคุณเพิ่งเก็บเครื่องหมายในตอนเริ่มต้นคุณอาจบันทึกบิตกรณีเลวร้ายที่สุดโดยรวม (เช่นเครื่องหมาย11001หมายถึงB'S MOVE W CAN KSC W CANT QSC B CANT KSC B CAN QSC) นั่นคือ 4 บิตแทนที่จะเป็น 5 บิตต่อด้านในการเข้ารหัสของคุณหรือ 3 บิตต่อด้านหากคุณกำจัดเครื่องหมายด้านข้างบน rooks ( KSC= ปราสาทของกษัตริย์ = ปราสาทด้านข้างของ QSCพระราชินี)
ไม่ใช่ Charles

นอกจากนี้เนื่องจากการโปรโมตจึงเป็นไปได้ที่จะมีมากถึง 9 ควีนส์หรือ 10 อัศวิน (หรือสิ่งอื่นใดที่ไม่ใช่ของกษัตริย์ไม่จำนำ)
ไม่ใช่ชาร์ลส์ที่

1

184 บิต = 23 ไบต์กรณีที่เลวร้ายที่สุดและไม่ซับซ้อนเกินไป:

A. สี่เหลี่ยมใดที่ครอบครอง: 64 บิต = 8 ไบต์ B. สีใดสำหรับ <= 32 สี่เหลี่ยมที่ถูกครอบครอง: 32 บิต = 4 ไบต์และตอนนี้ใช้เฉพาะ <= 30 สี่เหลี่ยมที่ครอบครองโดยผู้ที่ไม่ใช่กษัตริย์: B. ใช้ PNBRQ เข้ารหัสในฐาน 5 สำหรับความเป็นไปได้ 5 ^ 30; และ 32 * 31 * 2 * 4 * 4 * 9 สำหรับตำแหน่งกษัตริย์ผู้มีอิทธิพลสีขาวและดำสิทธิในการโยนปราสาทสี่เหลี่ยมจตุรัส (ใน 8 ความเป็นไปได้รวมทั้งไม่มีที่ 9) จำนวนนี้ 5 ^ 30 * 32 * 31 * 2 * 4 * 4 * 9 = 266075134277343750000000000 = 2 ^ 87.782 พอดีใน 88 บิตรวม 64 + 32 + 88 = 184 บิตสำหรับการเข้ารหัสทั้งหมด

สิ่งนี้สามารถลดลงได้เช่น 32 * 31 * 2 * 4 * 4 * 9 = 285696 สามารถลดเป็น 2 * (32 * 31 + 31 * 3 + 31 * 3 + 3 * 3) * 6 = 14244 โดยใช้ข้อเท็จจริง อย่างน้อยที่สุด 6 ผู้ที่ตกเป็นเหยื่อผู้ผ่านการคัดเลือก (รวมถึงไม่มี) และการเข้ารหัสสิทธิการใช้งานและตำแหน่งของกษัตริย์ในชุดเดียวกันโดยใช้สิทธิ์การใช้งานความเป็นจริงเฉพาะเมื่อกษัตริย์บนจตุรัสเริ่มต้น วิธีนี้ช่วยประหยัด 4 บิต

ฉันมีเหตุผลที่เชื่อได้ว่าเป็นไปไม่ได้ที่จะบรรลุถึง 18 ไบต์เช่นจำนวนตำแหน่งหมากรุกทางกฎหมายทั้งหมดเกิน 2 ^ 144

แบบแผน 160 บิตของคุณมีความคิดสร้างสรรค์มาก แต่ฉันคิดว่ามันต้องได้รับการเข้ารหัส / ถอดรหัสโปรแกรมก่อนที่ฉันจะมั่นใจอย่างสมบูรณ์เกี่ยวกับเรื่องนี้


1

171 บิตกรณีที่เลวร้ายที่สุด:

ฉันได้รวบรวมแนวคิดสองสามข้อรวมถึงความคิดของฉันเอง

เราจะเริ่มด้วยบอร์ด 64 บิต แต่ละบิตแสดงพื้นที่ว่างบนกระดาน พวกเขาเติมเต็มตามแนว ดังนั้นการเริ่มต้นดูเหมือนว่า:1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111

ตอนนี้แต่ละชิ้นจะถูกแทนด้วย 4 บิต บิตที่ 1: สี ( 0=white, 1=black) บิตที่ 2-4 ที่: หนึ่งใน 8 ชนิด

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

ในตอนท้ายเราจะรวมถึงการกำหนดเทิร์น 0=white, 1=black.

4 บิต * 32 ชิ้น = 128 บิตและฉันได้รับ 64 + 1 จากเทิร์นและบอร์ดแล้ว นั่นให้ทั้งหมด 128 + 64 + 1 = 193 ฉันยังไม่ได้เริ่มด้วย en passant หรือ castling เหนือขีด จำกัด ของฉันโดยที่ไม่มีอะไรเลยแม้แต่น้อย นี่คือจุดเริ่มต้นของเทคนิค

โอเค - คุณเห็นประเภทข้างต้นเหรอ? Bishop0 และ Bishop1 จำนำ 0 และจำนำ 1? ประเภทเหล่านั้นได้รับการกำหนดเพราะพวกเขาบอกให้เราใส่เล็กน้อยหลังจากชิ้นนี้ ดังนั้น Bishop0 หมายความว่าหลังจากนั้นจะมี 0 - นั่นคือชิ้นถัดไปเป็นสีขาว อธิการ 1 บอกเราชิ้นต่อไปคือสีดำและเบี้ย 0 และจำนำ 1 ทำงานเหมือนกัน (หากชิ้นนี้เป็นชิ้นสุดท้ายที่ระบุแล้วมันจะบอกเราเกี่ยวกับเทิร์นถัดไปแทน)

กรณีที่แย่ที่สุดของฉันเกี่ยวข้องกับชิ้นส่วนทั้งหมดบนกระดานดังนั้นด้วยเบี้ย 16 ตัวและบิชอป 4 ตัวนี่ช่วยฉันได้ 20 บิต ฉันลงไปที่ 173

ถูก อีกบิตในกรณีที่แย่ที่สุดของฉัน - เมื่อมี 16 สีที่เข้ารหัสแล้วเราจะหยุดการเข้ารหัสสีเมื่อเรารู้ว่ามันกำลังจะส่งต่อ กรณีที่เลวร้ายที่สุดของฉันตอนนี้เกี่ยวข้องกับชิ้นส่วนสีขาวทำให้มันไปยังมุมไกลโดยไม่มีการจับกุม ที่นั่นฉันบันทึกเพียงหนึ่งบิต 172

ตอนนี้ฉันจะเปลี่ยนลำดับที่ฉันตั้งชื่อชิ้นส่วน เราจะตั้งชื่อพวกมันตามแนวคอลัมน์โดยเริ่มจากด้านนอกที่ย้ายบอร์ดที่ตั้งชื่อไว้ที่จุดเริ่มต้นจะยังคงเหมือนเดิม แต่เมื่อฉันวางหมากบนมันฉันเริ่มจากด้านล่างขวาล่างและขึ้นคอลัมน์นั้น จากนั้นฉันกระโดดไปที่ด้านล่างขวาของสีดำและขึ้นไปบนคอลัมน์นั้น ฉันข้ามไปยังเซลล์ที่ไม่รู้จักด้านล่างขวาของไวท์และอื่น ๆ - นี่หมายถึงกรณีที่แย่ที่สุดของฉันคือการเริ่มต้นอีกครั้ง เหตุผลของฉันเกี่ยวข้องกับเคล็ดลับระหว่างทางของฉันสองบิตถัดไปที่ฉันแพ้และการขว้าง

ตอนนี้เพื่อให้จำนำได้รับการเลื่อนตำแหน่ง (ตามที่ได้มีการหารือกันตามความยาว) ชิ้นส่วนจะต้องถูกจับ ดังนั้นเมื่อเรารู้ว่ามี 32 ชิ้นเราเพียงแค่แสดงถึง 31 ชิ้น ชิ้นส่วนสุดท้ายมีการระบุที่ไม่ซ้ำกัน ตามที่ปรากฎสำหรับฉันเพียงแค่นี้ประหยัด 2 บิต - เพราะชิ้นสุดท้ายของฉันอาจเป็นเบี้ย / บิชอป (ซึ่งปกติฉันเสียค่าใช้จ่าย 3 บิตเพราะฉันบันทึกหนึ่งชิ้นในชิ้นถัดไป) ที่กำหนดสีแล้วและเป็นเพียง 2 บิต ฉันลงไปที่ 170 บิต

เมื่อผู้จำนำได้รับการส่งเสริมพวกเขาเพียงแค่เปลี่ยนประเภทของพวกเขา สำหรับแต่ละชิ้นที่หลุดออกจากกระดานฉันกำจัดตัวเอง (ขั้นต่ำ) 3 บิตและโปรโมชั่นจำนำสองราคาฉัน 2 บิตดังนั้นฉันจึงปฏิเสธ (ช้า) ในการส่งเสริมการขาย

ขุน สำหรับการโยนให้เกิดขึ้นไม่ว่าจะเป็นกษัตริย์หรือนักโกงที่เกี่ยวข้อง ดังนั้นเมื่อ rook สามารถขว้างมันได้ทั้งตัวและกษัตริย์ก็จะอยู่ในตำแหน่งเดิม ดังนั้น rooks ที่มีความสามารถในการ castling จะถูกแสดงในที่เดียวกับราชาของสีนั้น เนื่องจากนี่เป็นสิ่งผิดกฎหมาย (สองกษัตริย์หรือสามกษัตริย์ที่มีสีเดียวกันบนกระดาน) และสามารถเกิดขึ้นได้ในสามการตั้งค่าที่เป็นไปได้สำหรับแต่ละสี (ซ้าย, ขวา, ทั้งคู่ rooks จะถูกระบุว่าเป็นราชา) - การถอดรหัสเป็นไปได้อย่างเต็มที่ ดังนั้นสำหรับเราไม่มีการเข้ารหัสบิต castling

En Passant ที่นี่เราจะใช้ตำแหน่งที่ผิดกฎหมาย จำนำเพียงครั้งเดียวเท่านั้นที่อาจตกอยู่ในอันตรายของผู้คนในเวลาเดียวกัน มันจะต้องอยู่ในแถวที่สี่ จำนำที่มีความเสี่ยงจะถูก 'พลิก' กลับไปที่แถวบ้าน - สลับกับสิ่งที่มี เนื่องจากการจำนำนั้นอยู่ในแถวแรกของตัวเอง - ตำแหน่งที่ผิดกฎหมายสถานการณ์จะเห็นได้ชัดเจนกับตัวถอดรหัส - มันจะย้อนกลับตำแหน่งและทำเครื่องหมายจำนำว่ามีความเสี่ยงต่อผู้เดินผ่าน

เราต้องยุ่งกับคำสั่งเพราะชิ้นสุดท้ายจะต้องมีการระบุที่ไม่ซ้ำกัน ตามลำดับมาตรฐานเราจะไม่สามารถบอกได้ว่ารูที่มุมด้านหลังอาจเป็นปราสาทได้หรือไม่ - เมื่อเราทำงานจากด้านนอกเรารับประกันได้ว่าทุกที่ที่โกง 'รายการ' ไม่ว่าจะเป็นในมุมของตัวเองหรือในช่วงกลางของกระดานเพราะมันถูกเปลี่ยนเป็นเบี้ยเสี่ยง en Passant จะมีชิ้นส่วนที่ระบุไว้หลังจาก มัน - ดังนั้นเราจะบอกประเภทของโกง เรารู้ว่าจะมีชิ้นส่วนหลังจากนั้นเพราะสำหรับการจำนำที่จะมีความเสี่ยงจะต้องมีการจำนำภายในของมัน (ซึ่งจะถูกเข้ารหัสอย่างใหญ่หลวงในภายหลังตามคำแนะนำข้างต้น)

โอ้และเพื่อช่วยให้แน่ใจว่ากรณีที่เลวร้ายที่สุดเกี่ยวข้องกับทุกชิ้นส่วนบนกระดานเมื่อเรามีน้อยกว่า 32 ชิ้นเราสามารถใช้กระดาน 64 บิตเพื่อระบุตำแหน่งเทิร์นและตำแหน่งว่างโดยใช้ 0 เพื่อแทนชิ้นส่วนเมื่อสีขาวของมัน เทิร์นและ 1 ของเมื่อมันเป็นสีดำ

ดังนั้นเราจึงมีสัญชาตญาณและสามารถขว้างได้ฟรี เราหยิบชิ้นสุดท้ายขึ้นมาฟรีแม้ว่าจะต้องใช้เวลาในการปรับปรุงเพื่อให้การเล่นนั้นเป็นไปตามกฎ en and passant และ castling เราทิ้ง 20 บิตบนชิ้นส่วนมาตรฐาน ฉันเชื่อว่ากรณีที่เลวร้ายที่สุดที่นี่เกี่ยวข้องกับการจำนำสีขาว midde ย้ายไปข้างหน้าและชิ้นสีดำในระหว่างมันและราชินีในขณะที่ทุกชิ้นอยู่บนกระดาน ตรวจสอบอย่างรวดเร็ว: ชิ้นแรกถูกจับ - เรียกว่าเบี้ย 3 บิตออกจากคณะกรรมการในการจำนำ 3 บิตบนกระดานในรูปแบบของชิ้นสุดท้ายชิ้นหนึ่งปิดในเครื่องหมายเทิร์นหายไป โปรโมตสองเบี้ยสองบิตบนกระดาน อ่าฉันอยู่ที่ 171

แก้ไขฉันได้เพิ่มรหัสสำหรับตัวถอดรหัส (ทำงานอยู่) ใน R - ด้านล่าง ต้องใช้เวกเตอร์ของบูลีนเป็นอินพุต - (ขอโทษด้วย - ฉันไม่สามารถเขียนโค้ดได้ดีในทุกสิ่งที่จะทำให้ฉันใช้บิตได้จริง ๆ ) ฉันได้รวมตำแหน่งเริ่มต้นแล้ว

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

รหัสนี้สร้าง 4 ฟังก์ชั่น หนึ่งที่จะแยกพื้นฐานของชิ้นส่วนและโครงสร้างกระดานเช่นเดียวกับการหาประเภทชิ้นส่วนและชิ้นส่วนใด ๆ 'โดยนัย' ฟังก์ชั่นถัดไปเติมในโครงสร้างบอร์ดด้วยชิ้นส่วนเหล่านั้นในลำดับ bizzarre เล็กน้อย (และแตกต่างจากลำดับอัลกอริทึมเริ่มต้นของฉัน) ฟังก์ชั่นถัดไปจะบรรจุในบอร์ดและตรวจจับตำแหน่งผิดกฎหมาย - จากนั้นแก้ไขและเปลี่ยนชื่อเบี้ยที่เสี่ยงต่อการผ่าน "x pawn-e" และ rooks ใด ๆ ที่สามารถปราสาท "x rook-c" ฟังก์ชั่นสุดท้ายคือเสื้อคลุมที่ทำงานฟังก์ชั่นเหล่านั้นตามลำดับและให้การส่งออกซึ่งเป็นคณะกรรมการในปัจจุบันเช่นเดียวกับการเปิด

ฉันยังได้รวมการเข้ารหัสของตำแหน่งเริ่มต้น (แม้ว่าจะเห็นคุณจะต้องโทรc(startboard,newpieces)และรหัสเรียกฟังก์ชัน wrapper ในตำแหน่งนั้น


สิ่งนี้น่าสนใจ ฉันชอบที่จะเห็นการใช้งานเป็นหลักฐานของแนวคิด
Mego

การใช้งานนั้นมักจะไม่กี่ขั้นตอนนอกเหนือจากการพิสูจน์แนวคิด แต่ฉันได้เพิ่มตัวถอดรหัส มันอยู่ใน R ดังนั้นจึงใช้ Booleans มากกว่าบิต (ขออภัย - ไม่ต้องการใช้เวลามากเกินไป) แต่ฉันเชื่อว่ามันควรจะพิสูจน์แนวคิด
user5957401

0

229/226 บิต

สิ่งนี้กลายเป็นว่าไม่ประสบความสำเร็จมากนัก แต่อาจช่วยคนอื่น ๆ ให้เดินไปในเส้นทางเดียวกัน

รุ่นง่าย:

  • 1 บิตสำหรับผู้ที่มันเป็น
  • 4 บิตสำหรับความเป็นไปได้สี่แบบ
  • 3บิตสำหรับการกินความเป็นไปได้ นี่เป็นครั้งแรกที่ฉันเข้าใจอย่างลึกซึ้งยิ่งขึ้น ผู้ที่เดินทางจะต้องกระทำโดยการจำนำที่ย้ายจากแถวเดียวกันกับเบี้ยที่ถูกยึด การวิเคราะห์กรณีระบุว่าเมื่อเรารู้จำนวนเบี้ยสีที่ย้ายล่าสุดมีขั้นสูงสองสแควร์อย่างแน่นอนจะมีอย่างน้อย 6 en passant case (รวมถึงกรณีที่ไม่มี pawn เสี่ยงต่อen passant ) กรณีที่เลวร้ายก็คือ 5 เบี้ย (อาจมีช่องโหว่ทั้งหมด: เช่นPpPPpPPpมีห้าช่องโหว่Ps) มี 6 เบี้ยมีที่มากที่สุด 2 เบี้ยศัตรูในตำแหน่งเดียวกันซึ่งแต่ละสามารถคุกคามที่มากที่สุด 2 เบี้ยการกิน ดังนั้นเราต้องการceil(lg 6) = 3บิตที่นี่

จากนั้นคณะกรรมการ กระดานมี 64 ช่องดังนั้นดัชนีสี่เหลี่ยมสามารถเข้ารหัสใน 6 บิต เราแสดงผู้ชายตามลำดับสลับสีเริ่มต้นด้วยราชา

  • 6บิต: ตำแหน่งของราชาขาว (รับประกันว่าจะอยู่บนกระดาน)
  • 6บิต: ตำแหน่งของราชาสีดำ (รับประกันว่าจะอยู่บนกระดานในกรณีที่เลวร้ายที่สุดที่ราชาขาวอยู่ตรงมุมมีสถานที่ที่เป็นไปได้ 60 แห่งในกรณีที่ดีที่สุดที่สีขาวไม่ได้อยู่บนขอบมี 55)
  • 6บิต: ตำแหน่งของพระราชินีขาว หากไม่มีราชินีขาวให้ทำซ้ำตำแหน่งของกษัตริย์ขาวเป็นสัญญาณ
  • สำหรับราชินีสีขาวเพิ่มเติมแต่ละคน1ตามด้วย 6 บิตสำหรับตำแหน่ง
  • 0บิต
  • เหมือนกันสำหรับราชินีสีดำ
  • กระบวนการที่คล้ายกันสำหรับ rooks, bishops, knights และ pawns แม้ว่าเราสามารถข้าม pawns เป็นสีได้ถ้าเรามีชาย 16 คนในสีนั้น
  • ลบ0บิตสุดท้าย

ค่าใช้จ่ายนี้เป็น12บิตที่แน่นอนสำหรับพระมหากษัตริย์และ2*7*5-1 = 69บิตสำหรับคนอื่น ๆ ในกรณีที่เลวร้ายที่สุดที่ชายทั้ง 32 คนอยู่บนกระดานมันมีค่าใช้จ่าย7สำหรับคนแต่ละคนที่ไม่ใช่กษัตริย์รวม12 + 7*30 - 1 = 221 bitsกัน ดังนั้นด้วยเริ่มต้น8บิตของรัฐทั่วโลกเรามี229 บิต


รุ่นขั้นสูง:

ด้วยการใช้การเข้ารหัสทางเลขคณิตทำให้เราสามารถใช้งานได้lg num_possibilitiesมากกว่าceil(lg num_possibilities)และเพียงแค่ใช้รหัสceilในตอนท้าย

  • 1 บิตสำหรับผู้ที่มันเป็น
  • 4 บิตสำหรับความเป็นไปได้สี่แบบ
  • lg 6บิตสำหรับการกินความเป็นไปได้
  • 6 บิตสำหรับกษัตริย์สีขาว
  • lg 60 บิต (กรณีที่เลวร้ายที่สุด) สำหรับราชาดำ
  • lg 63 บิต (เพราะฉันไม่ต้องการที่จะทำให้ซับซ้อนขึ้นไปถึงระดับของการตรวจสอบ) สำหรับราชินีสีขาวโดยใช้ตำแหน่งของราชาขาวถ้าไม่มี
  • สำหรับแต่ละราชินีสีขาวเพิ่มเติมเป็น1บิตตามด้วยlg 62, lg 61ฯลฯ บิตสำหรับตำแหน่งของเธอ
  • 0บิต
  • lg 63 บิต (หรือน้อยกว่าหากมีราชินีสีขาว) สำหรับราชินีสีดำ
  • เป็นต้น

ชายคนที่ n ที่มีอยู่จริงมี66-nค่าที่เป็นไปได้ หากประเภทขาดสีเราใช้66-#men so farบิตในการบันทึกนั้น (บวกหนึ่งบิตสำหรับตัวคั่น) กรณีที่รุนแรงคือ:

  1. มนุษย์ทุกคนอยู่รวมทั้งจำนำอย่างน้อยหนึ่งตัวที่ไม่ได้รับการสนับสนุนจากแต่ละด้าน เราใช้เวลา5+lg 6กับสถานะโลก6+lg 60บนราชา29บิตแยกและSUM_{n=32}^{63} lg nบิตบนตำแหน่ง ผลรวมทั้งหมด: ceil(225.82)บิต ที่น่าผิดหวัง
  2. เหลือเบี้ยที่ไม่ได้รับการสนับสนุนเท่านั้น เราใช้เวลา5+lg 6กับสถานะโลก6+lg 60ในราชา29ในบิตแยก8*lg 63บอกว่าไม่มีชิ้นอื่น ๆ และSUM_{n=48}^{63} lg nในตำแหน่งของเบี้ย ผลรวมทั้งหมด: ceil(188.94)บิต ดีกว่า - ด้วยการบันทึกเกมโกงอัศวินและอธิการที่สองสำหรับแต่ละด้าน

ดังนั้นกรณีที่เลวร้ายที่สุดน่าจะเป็น226 บิตสำหรับการบันทึก 3 อย่างเลวทราม

เราสามารถทำได้ดีกว่าในกรณีทั่วไปโดยการเข้ารหัสเบี้ยก่อนชิ้นเพราะพวกเขาถูก จำกัด ไว้ที่ 48 สี่เหลี่ยมจัตุรัสมากกว่า 64 เต็มอย่างไรก็ตามในกรณีที่เลวร้ายที่สุดที่มนุษย์ทุกคนอยู่บนกระดานและเบี้ยทั้งหมดได้รับการเลื่อนตำแหน่งฉันคิดว่า สิ่งนี้จะจบลงด้วยการคิดต้นทุนเพิ่มอีก 2 บิตเพราะเราต้องการธง "ไม่มีเบี้ย" แทนที่จะสามารถนับคนได้


0

นี่คือหัวข้อสนทนาในแวดวงหมากรุก

นี่คือข้อพิสูจน์อย่างง่าย ๆ หนึ่งข้อที่มี 164 บิต https://groups.google.com/forum/#!topic/rec.games.chess.computer/vmvI0ePH2kI 155 แสดงไว้ที่นี่http://homepages.cwi.nl/~tromp /chess/chess.html

ผ่านกลยุทธ์ที่ง่ายกว่า:

  • จำกัด การจำนำไปยังสถานที่ที่อาจพบการจำนำ
  • จำกัด กองทัพที่จะต้องพิจารณาชิ้นต้นฉบับและการส่งเสริมการจำนำที่เป็นไปได้
  • คิดถึงการโปรโมตและสถานการณ์ที่ไม่สามารถทำการโปรโมตได้

2
คำตอบสำหรับลิงค์เท่านั้นไม่ใช่คำตอบที่ดี คุณควรให้คำตอบที่สมบูรณ์ภายในโพสต์ของคุณไม่ใช่แค่ลิงค์ไปยังคำตอบ และหากคำตอบของคุณไม่ใช่งานของคุณเองคุณอาจทำให้โพสต์ของคุณเป็นวิกิชุมชน
ace_HongKongIndependence

โพสต์เป็นต้นฉบับ การเพิ่มรายละเอียดที่จะตอบ
William Entriken

1
นี่คือตัวอย่างของสาเหตุที่คุณรวมเนื้อหาในคำตอบของคุณ ลิงค์ที่ 2 เสียชีวิต มันคืออะไร tromp.github.io/chess/chess.html
mbomb007

-2

ต่ำสุด: 0 บิต

แม็กซ์: 1734 243 บิต (4.335 4.401 บิต / บอร์ดตัดจำหน่าย)

ที่คาดว่าจะ 351 177 บิต (4.376 4.430 บิต / คณะตัดจำหน่าย)

เนื่องจากฉันสามารถกำหนดอินพุทและเอาท์พุทได้อย่างไรก็ตามฉันต้องการฉันตัดสินใจที่จะเข้ารหัสประวัติศาสตร์ของเกมจนถึงจุดนี้ ข้อได้เปรียบอย่างหนึ่งคือข้อมูลเพิ่มเติมของผู้ที่กลับมาเป็น en-passant และผู้ที่มีความสามารถในการสร้างปราสาทที่สามารถรับและไม่เข้ารหัส

ความพยายามที่ 1:

อย่างไร้เดียงสาฉันคิดว่าฉันสามารถเข้ารหัสแต่ละการเคลื่อนไหวใน 12 บิต, 4 Triplets ของรูปแบบ (เริ่มต้น x, เริ่มต้น y, สิ้นสุด x, สิ้นสุด y) โดยที่แต่ละ 3 บิต

เราจะถือว่าตำแหน่งเริ่มต้นและย้ายชิ้นส่วนจากที่นั่นด้วยสีขาวไปก่อน กระดานถูกจัดวางไว้เพื่อให้ (0, 0) เป็นมุมซ้ายล่างของสีขาว

ตัวอย่างเช่นเกม:

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

จะถูกเข้ารหัสเป็น:

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

สิ่งนี้นำไปสู่การเข้ารหัสบิต12 ม.โดยที่mคือจำนวนการเคลื่อนไหว

ในอีกด้านหนึ่งนี้อาจมีขนาดใหญ่มากในทางกลับกันคุณสามารถพิจารณาแต่ละการเคลื่อนไหวว่าเป็นเกมของตัวเองดังนั้นการเข้ารหัสแต่ละครั้งจะเข้ารหัสm "กระดานหมากรุก" หากคุณตัดจำหน่ายคุณจะได้รับ "กระดานหมากรุก" แต่ละอันคือ 12 บิต แต่ฉันรู้สึกว่านี่เป็นการโกง ...

พยายาม 2:

ฉันตระหนักว่าการเคลื่อนไหวแต่ละครั้งในความพยายามก่อนหน้านี้เป็นการเข้ารหัสการเคลื่อนไหวที่ผิดกฎหมายจำนวนมาก ดังนั้นฉันจึงตัดสินใจเข้ารหัสการเคลื่อนไหวทางกฎหมายเท่านั้น เราแจกแจงการเคลื่อนไหวที่เป็นไปได้ดังต่อไปนี้ให้ระบุจำนวนแต่ละช่องเช่น (0, 0) → 0, (1, 0) → 1, (x, y) → x + 8 y วนซ้ำผ่านแผ่นกระเบื้องและตรวจสอบว่ามีชิ้นส่วนใดบ้างและสามารถเคลื่อนที่ได้หรือไม่ ถ้าเป็นเช่นนั้นเพิ่มตำแหน่งก็สามารถไปที่รายการ เลือกดัชนีรายการที่คุณต้องการย้าย เพิ่มหมายเลขนั้นในจำนวนการเคลื่อนย้ายทั้งหมดที่ถ่วงน้ำหนักโดย 1 บวกกับจำนวนการเคลื่อนไหวที่เป็นไปได้

ตัวอย่างข้างต้น: จากตำแหน่งเริ่มต้นชิ้นแรกที่ย้ายสามารถเป็นอัศวินในตารางที่ 1 ก็สามารถย้ายไปยังตาราง 16 หรือ 18 [(1,16),(1,18)]เพื่อเพิ่มเหล่านั้นไปยังรายการ ถัดไปคืออัศวินในตารางที่ 6 เพิ่มการเคลื่อนไหวของมัน โดยรวมแล้วเราได้รับ:

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

เนื่องจากเราต้องการการเคลื่อนไหว (12, 28) เราเข้ารหัสสิ่งนี้เป็น 13 ในฐาน 20 เนื่องจากมีการเคลื่อนไหวที่เป็นไปได้ 20 รายการ

ดังนั้นตอนนี้เราได้รับหมายเลขเกม g 0 = 13

ต่อไปเราทำเช่นเดียวกันสำหรับสีดำยกเว้นเราเรียงหมายเลขไพ่ในลำดับย้อนกลับ (เพื่อให้ง่ายขึ้นไม่จำเป็นต้องใช้) เพื่อรับรายการการเคลื่อนไหว:

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

เนื่องจากเราต้องการการเคลื่อนไหว (11, 27) เราเข้ารหัสสิ่งนี้เป็น 11 ในฐาน 20 เนื่องจากมีการเคลื่อนไหวที่เป็นไปได้ 20 รายการ

ตอนนี้เราได้หมายเลขเกม g 1 = (11 ⋅ 20) + 13 = 233

ต่อไปเราจะได้รับรายการการเคลื่อนไหวต่อไปนี้สำหรับสีขาว:

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

เนื่องจากเราต้องการการเคลื่อนไหว (6, 21) เราเข้ารหัสสิ่งนี้เป็น 13 ในฐาน 29 เนื่องจากมีการเคลื่อนไหวที่เป็นไปได้ 29 รายการ

ดังนั้นตอนนี้เราได้รับหมายเลขเกม g 2 = ((13 ⋅ 20) + 11) 20 + 13 = 5433

ต่อไปเราจะได้รับรายการการเคลื่อนไหวต่อไปนี้สำหรับสีดำ: [(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)]

เนื่องจากเราต้องการการย้าย $ (10, 18) $ (10, 18)

ดังนั้นตอนนี้เราได้รับหมายเลขเกม g 3 = ((((19 ⋅ 29 + 13) 20) + 11) 20 + 13 = 225833

และทำกระบวนการนี้ต่อไปสำหรับการเคลื่อนไหวที่เหลือทั้งหมด คุณคิดว่าgเป็นฟังก์ชัน g (x, y, z) = x y + z ดังนั้น g 0 = g (1, 1, 13), g 1 = g (g (1, 1, 11), 20, 13), g 2 = g (g (g (1, 1, 13), 20, 11), 20, 13), g 3 = g (g (g (g (1, 1, 19), 29, 13), 20, 11), 20, 13)

ในการถอดรหัสเกมหมายเลขg 0เราเริ่มต้นที่ตำแหน่งเริ่มต้นและระบุการเคลื่อนไหวที่เป็นไปได้ทั้งหมด จากนั้นเราคำนวณg 1 = g 0 // l , m 0 = g 0 % l , ที่lคือจำนวนของการเคลื่อนไหวที่เป็นไปได้, '//' เป็นตัวดำเนินการหารจำนวนเต็มและ '%' เป็นตัวดำเนินการโมดูลัส มันควรจะถือได้ว่ากรัม0 = กรัม1 + ม. 0 ต่อไปเราทำการย้ายm 0และทำซ้ำ

จากตัวอย่างข้างต้นถ้าg 0 = 225833 ดังนั้นg 1 = 225833 // 20 = 11291 และm 0 = 225833% 20 = 13 ถัดไปg 2 = 11291 // 20 = 564 และm 1 = 11291% 20 = 11 จากนั้นg 3 = 11291 // 20 = 564 และm 2 = 11291% 20 = 11 ดังนั้นg 4 = 564 // 29 = 19 and_m_ 3 = 564% 29 = 13. ในที่สุดg 5 = 19 // 29 = 0 และm 4 = 19% 29 = 19

ดังนั้นใช้บิตจำนวนเท่าใดในการเข้ารหัสเกมด้วยวิธีนี้

สำหรับความเรียบง่ายสมมติว่ามีการเคลื่อนไหว 20 ครั้งต่อรอบและสำหรับกรณีสถานการณ์ที่เลวร้ายที่สุดเราเลือกหนึ่งที่ยิ่งใหญ่ที่สุดเสมอ 19. จำนวนที่เราจะได้รับคือ 19 ⋅ 20 m

+ 19 ⋅ 20 m-1 + 19 ⋅ 20 m-2 + ⋯ + 19 ⋅ 20 + 19 = 20 m + 1 - 1 โดยที่ _m คือจำนวนการเคลื่อนไหว ในการเข้ารหัส 20 m + 1 - 1 เราต้องการ บิตlog 2 (20 m + 1 ) บิตซึ่งเป็น (m + 1) ∗ log 2 (20) = 4.3219 ∗ (m + 1)

โดยเฉลี่ยm = 80 (40 ย้ายต่อผู้เล่น) ดังนั้นจะใช้เวลา 351 บิตในการเข้ารหัส หากเราบันทึกหลายเกมเราจะต้องใช้การเข้ารหัสสากลเนื่องจากเราไม่ทราบว่าต้องใช้จำนวนบิตเท่าใดในแต่ละหมายเลข

กรณีที่เลวร้ายที่สุดเมื่อm = 400 (200 ย้ายต่อผู้เล่น) ดังนั้นจะใช้เวลา 1734 บิตในการเข้ารหัส

โปรดทราบว่าเราต้องให้ตำแหน่งที่เราต้องการเข้ารหัสผ่านเส้นทางที่สั้นที่สุดเพื่อไปที่นั่นโดยทำตามกฎ ตัวอย่างเช่นเกมที่สร้างทฤษฎีที่นี่ไม่ต้องการm = 11741 เพื่อเข้ารหัสตำแหน่งสุดท้าย แต่เราเรียกใช้การค้นหาแบบกว้างแรกเพื่อค้นหาเส้นทางที่สั้นที่สุดไปยังตำแหน่งนั้นและเข้ารหัสนั้นแทน ฉันไม่รู้ว่าเราจะต้องเจาะลึกตำแหน่งหมากรุกทั้งหมดเท่าไหร่ แต่ฉันคิดว่า 400 เป็นค่าประเมินค่าสูงไป

การคำนวณอย่างรวดเร็ว:

มี 12 ชิ้นไม่ซ้ำกันตารางที่สามารถล้างเพื่อตำแหน่งพวกเขาบนกระดานหมากรุกหรือ 13 64 นี่เป็นค่าประเมินที่สูงเกินไปเนื่องจากมีตำแหน่งที่ไม่ถูกต้องจำนวนมาก เมื่อเราอยู่ม.ย้ายเข้ามาในเกมที่เราได้สร้างขึ้นประมาณ 20 เมตรตำแหน่ง ดังนั้นเราจึงกำลังมองหาเมื่อ 20 เมตร = 13 64 บันทึกทั้งสองด้านเพื่อรับm = 64 * บันทึก20 (13) = 54.797 นี่แสดงให้เห็นว่าเราควรจะไปถึงตำแหน่งใดก็ได้ใน 55 ท่า

ตอนนี้ฉันได้คำนวณกรณีที่แย่ที่สุดที่จะเป็นm = 55 ไม่ใช่m = 400 ฉันจะแก้ไขผลลัพธ์ของฉัน เพื่อเข้ารหัสตำแหน่งที่m = 55 ใช้เวลา 243 บิต ฉันจะบอกว่ากรณีเฉลี่ยอยู่ที่ประมาณm = 40 ซึ่งใช้เวลา 177 บิตในการเข้ารหัส

หากเราใช้อาร์กิวเมนต์การตัดจำหน่ายจากก่อนหน้านี้เรากำลังเข้ารหัส 400 "กระดานหมากรุก" ใน 1734 บิตดังนั้นเราจึงเข้าใจว่า "กระดานหมากรุก" แต่ละอันใช้เวลา 4.335 บิตในกรณีที่เลวร้ายที่สุด

โปรดทราบว่าg = 0 หมายถึงเกมที่ใช้ได้เกมที่ชิ้นส่วนของสี่เหลี่ยมจัตุรัสต่ำสุดเคลื่อนไปยังสี่เหลี่ยมจัตุรัสต่ำสุดที่สามารถทำได้

หมายเหตุเพิ่มเติม:

หากคุณต้องการอ้างถึงตำแหน่งเฉพาะในเกมคุณอาจต้องเข้ารหัสดัชนี สิ่งนี้สามารถเพิ่มได้ด้วยตนเองเช่นเชื่อมดัชนีเข้ากับเกมหรือเพิ่มการย้าย "จบ" เพิ่มเติมเป็นการย้ายครั้งสุดท้ายที่เป็นไปได้ในแต่ละเทิร์น ตอนนี้สามารถบัญชีสำหรับผู้เล่นที่ยอมรับหรือ 2 ในแถวเพื่อแสดงว่าผู้เล่นตกลงที่จะเสมอกัน นี่เป็นสิ่งจำเป็นเฉพาะหากเกมไม่ได้จบในการรุกฆาตหรือจนมุมตามตำแหน่งในกรณีนี้มันจะบอกเป็นนัย ในกรณีนี้มันจะนำจำนวนบิตที่ต้องการโดยเฉลี่ยถึง 356 และในกรณีที่เลวร้ายที่สุด 1762


1
อาร์กิวเมนต์“ การตัดจำหน่าย” ของคุณไม่ทำงาน เป้าหมายคือการเข้ารหัสบอร์ดที่กำหนดโดยผู้ใช้ คุณไม่ต้องแบ่งค่าใช้จ่ายในการเข้ารหัสบอร์ดนี้ใน 400 บอร์ดเสริมที่คุณอาจสร้างขึ้นระหว่างทาง (นี่จะโอเคถ้าบอร์ด 400 คนที่ได้รับอนุญาตให้เลือกโดยผู้ใช้อย่างอิสระและไม่ถูก จำกัด โดยความต้องการในการสร้างเกมหมากรุก) นอกจากนี้เกมหมากรุกสามารถใช้เวลาหลายพันการเคลื่อนไหวในทางทฤษฎีและ OP คือ ชัดเจนเกี่ยวกับการมีความสนใจในกรณีที่เลวร้ายที่สุด
Anders Kaseorg

@AndersKaseorg: จริงมาก มันขึ้นอยู่กับวัตถุประสงค์จริงๆ หากคุณพยายามจัดเก็บทั้งเกมด้วยอัลกอริธึมอื่นทั้งหมดมันจะใช้ m * c ไบต์ที่ m คือจำนวนการเคลื่อนไหวและ c คือขนาดของเอาต์พุต ดังนั้นถ้าคุณพยายามจัดเก็บเกมย้ายทั้งหมด 80 เกมโดยใช้โซลูชัน 160 บิตจะใช้เวลา 12800 บิตในขณะที่ของฉันจะใช้เพียง 351 เพื่อประโยชน์ของการแข่งขันฉันยอมรับว่าคุณถูกต้อง แต่ฉันคิดว่ามันเป็นคุณสมบัติที่ดี เพื่อชี้ให้เห็นเนื่องจากเป็นเรื่องธรรมดามากที่ต้องการจัดเก็บทั้งเกมและไม่ใช่แค่บอร์ด
edggy

วัตถุประสงค์มีความชัดเจน “ เป้าหมายคือการทำให้การเป็นตัวแทนที่เล็กที่สุดของกระดานหมากรุกที่สามารถนำมาใช้ (ถอดรหัสครั้งเดียว) เพื่อกำหนดความเป็นไปได้ในการเคลื่อนไหวทั้งหมดสำหรับผู้เล่นในเทิร์นนั้น …คะแนนของคุณได้รับการพิจารณาสถานการณ์กรณีเลวร้ายที่สุด - ขนาดที่เป็นไปได้สูงสุดในหน่วยบิต”
Anders Kaseorg

@AndersKaseorg: ฉันไม่เคยอ้างว่ามันคลุมเครือ ฉันเพิ่งตัดสินใจที่จะใช้วิธีการอื่น สิ่งหนึ่งที่ควรทราบคือเพื่อหากระดานที่เล็กที่สุดโดยใช้อัลกอริทึมของฉันฉันต้องการเส้นทางที่เล็กที่สุดเพื่อไปยังตำแหน่งนี้ ตัวอย่างเช่นในเกมเปิด 11741 ที่คุณเชื่อมโยงเพื่อไปยังตำแหน่งกระดานเดียวกันฉันไม่จำเป็นต้องทำตามเส้นทางนั้นถ้าทุกอย่างที่เราใส่ใจคือกระดาน ดังนั้นในการเข้ารหัสเกมที่เชื่อมโยงฉันเพิ่งพบกับเกมที่สั้นที่สุดซึ่งเหลือ 2 กษัตริย์ในสี่เหลี่ยมเหล่านั้นซึ่งอาจจะมี 200 รอบหรือน้อยกว่า สามารถทำได้ด้วยการค้นหาความลึกก่อน
edggy

การใช้เกมที่สั้นกว่านั้นใช้ได้ถ้าคุณสามารถพิสูจน์ได้ว่าทุกตำแหน่งสามารถเข้าถึงได้ใน 200 รอบหรือน้อยกว่า (ตอนนี้ดูเหมือนว่าจะเดาได้) คุณจะต้องพิจารณาตำแหน่งหมากรุกที่มีการเคลื่อนไหวทางกฎหมายมากกว่า 100 รายการเว้นแต่คุณจะพิสูจน์ได้ว่าสิ่งเหล่านั้นไม่เกิดขึ้นภายในการก่อสร้างของคุณ การหารผลลัพธ์ของคุณด้วยจำนวนการเคลื่อนไหวในเกมยังไม่ได้รับอนุญาตตามกฎของการท้าทายนี้
Anders Kaseorg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.