가장 작은 체스 판 압축


38

체스 판을 인코딩 및 디코딩 할 수있는 알고리즘 또는 프로그램을 작성하십시오. 목표는 해당 턴에 플레이어의 모든 이동 가능성을 결정하기 위해 사용될 수있는 체스 보드의 가장 작은 표현을 만드는 것입니다.

인코딩은 다음을 표시 할 수 있어야합니다.

  • 누구의 차례입니까?
  • 플레이어가 양쪽에서 성을 쌓을 수 있는지 여부.
  • 플레이어가 참가자를 수행 할 수 있는지 여부와 가능하다면 어떤 폰을 할 수 있습니까?
  • 모든 조각의 위치.

거세에 관한 중요 사항 : 흰색이 왕을 한 바퀴 움직 인 후 다음 차례로 되 돌리면 그 이후 어느 쪽도 성을 지을 수 없다는 것이 분명해야합니다. 그들이 왼쪽 또는 오른쪽 루크를 움직 인 경우에도 마찬가지입니다. 보드가 2 턴 전에와 같은 상태로 보이지만 게임 상태가 변경되었습니다. 자세한 정보는 여기 : http://en.wikipedia.org/wiki/Chess#Castling

동반자에 대한 중요 사항 : 이것은 또한 회전에 민감합니다. 자세한 내용은 규칙을 읽으십시오. http://en.wikipedia.org/wiki/Chess#En_passant

필요에 따라 입력 및 출력을 결정하십시오. 누구든지 가장 많이 압축 할 수있는 주요 소품!

점수는 최악의 시나리오 (최대 비트 크기)로 결정됩니다. 그 숫자를 계산 한 방법과 설명한 내용을 보여주십시오. 최악의 경우를 위해 쏴라!


"비트 단위"는 무슨 뜻입니까?
피터 테일러

가장 작은 코드입니까 아니면 가장 압축 된 것입니까? 가장 압축 된 것이 더 흥미 롭습니다.
Justin

명확하지 않아서 죄송합니다. 비트 단위로 표시하기 시작하면 압축 할 수 있다는 점에서 비트 단위이므로 약간의 비트 단위 작업이 필요합니다. 내 부분이 잘못 사용되었습니다. 가장 압축되지 않은 코드입니다.
Seltzer

1
@GeekWithALife 예, 동시에 18 명의 여왕이 보드에있을 수 있습니다. 이 링크를 따라 재생 버튼을 클릭하여 예를 들어보십시오.
squeamish 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

킹 +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 사용

164603 독특한 조각 주파수 가 있기 때문에 .

Log2( 164603) = 17.3286110452
             ~ 18 bits

0
 0000 0000 0000 0000 00  Freq ID

(+000) (+00) 캐슬 링

최대 : = 204 비트


개정 3

최소 : 82 최대 : 199 평균 : 160

마지막으로 최대 비트 크기를 찾기 위해 분석을 수행했습니다. 고유 한주파수 에 대해 최적의 허프만 인코딩 .

               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 

폰의 수가 1보다 크면 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 사이에서 가장 자주 나타납니다. 다음은 폰, 루크, 기사, 주교 그리고 가장 빈번한 것은 여왕과 왕입니다.

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 개를 확인하십시오. 따라서 최대 값은 213 비트 입니다.


가능한 개선

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 비트가 필요하지 않습니다. 마지막 턴에서 최대 1 개의 폰이 이동 했으므로 4 비트로 충분합니다 (예 : 1111"불가능한"또는 이진 숫자로 열의 경우).
피터 테일러

폰이 나무에서 더 나은 위치를 얻는 이유는 무엇입니까? 일반적인 경우 가장 일반적이지만 R / B / N은 10 번 나타날 수 있습니다.
ugoren

@PeterTaylor, 실제로 3 비트로 충분합니다. 검은 색 5 순위 폰이있는 열만 계산하면 (흰색 이동 가정) 8은 유효하지 않습니다.
ugoren

1
최악의 경우는 실제로 불가능합니다. 캡처가 없으면 승격이 불가능합니다 (2 개의 프로모션 당 하나 이상의 캡처가 필요함).
우고 렌

2
64 개의 위치 (흰색 또는 검은 색 왕의 경우)를 인코딩하려면 6 비트 (2 ** 6 = 64)가 필요합니다.
lambruscoAcido

17

192 비트 (최악의 경우)

다음은 임의의 폰 프로모션에 대처할 수 있고 64 + 4 × 32 = 192 비트 이상을 요구하지 않는 매우 간단한 저장 체계입니다.

  • 첫 번째 64 비트가 저장 bitboard 말한다 여기서 조각이 (되지 않지만 어떤 그들이 참조). 즉, 빈 사각형이 0으로, 점유 된 사각형이 1로 표시되도록 체스 판의 각 사각형에 대해 1 비트를 저장합니다 (정사각형 a1, b1, c1 등에서 정사각형 h8까지).

  • 다음으로 비트 보드에 점유 된 것으로 표시된 각 사각형에 대해 해당 사각형에 조각을 인코딩하는 4 비트 니블을 저장합니다. 4 비트 중 첫 번째 비트는 조각의 색상 (0 = 흰색, 1 = 검은 색)을 인코딩하고 나머지 3 비트는 조각의 유형을 인코딩합니다.

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

    동반자 및 캐스팅 규칙에 필요한 추가 정보를 인코딩하기 위해 행에 따라 폰 또는 루크를 나타내는 하나의 추가 피스 유형이 도입되었습니다.

    7 (1 열과 8 열) = 이동 한 적이없고 왕도 이동하지 않았으며
    7 번 (4 열과 5 열) 을 거둘 수있는 루크 = 2 칸 직전의 폰 따라서, 포착 될 수 EN 김에

함께 모아서:

     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

또는 16 진수로 :

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

2
"두 사각형 만 진행 한 풋"과 "이동 한 적이없는 루크"는 같은 행을 공유 할 수 있습니다. 여분의 자유 상태 (free state)는 "색상의 왕"을 인코딩하는데 사용될 수있다. 그런 식으로 매달려있는 비트를 제거 할 수 있어야합니다.
FireFly

비트 보드에 63 비트 만 저장하고 인코딩 된 남자 수에서 마지막 비트를 유추하여 비트를 절약 할 수도 있습니다. (비트 시퀀스 길이의 외부 인코딩이 필요하기 때문에 이것이 부정 행위인지 여부는 분명하지 않습니다). 그리고 남성의 상태 6과 7을 버리는 경우 최대 6 ^ 32까지 인코딩해야하며, 82.7 비트가 필요합니다. 83으로 반올림하면 상태 6과 7을 사용하여 13 비트가 절약되며 동일한 정보를 8 비트만으로 인코딩 할 수 있습니다.
피터 테일러

감사합니다, @FireFly! 귀하의 제안을 이행했습니다. (피터 테일러의 제안은 물론 훨씬 더 효율적이지만, 현재 체계의 간단한 이진 인코딩과 같은 종류 때문에 지금까지는 사용하지 않았습니다. 항상 별도의 항목으로 제출할 수 있습니다 ...)
Ilmari Karonen

좋아-이것은 약간 복잡합니다. 하지만 내 말 들어 턴 인디케이터에서 1 비트 히트를 취하면, pawn1이라고 부르는 조각으로 킹을 턴 으로 바꿀 수 있습니다. 폰을 폰 0으로 변경하십시오. 이제 (종속 취약하지 않은) 폰이있을 때마다 다음 조각에 대한 정보를 얻습니다 (pawn0의 경우 0 또는 pawn1의 경우 1). 폰이 16 개 있기 때문에, 턴 인디케이터에 대해 16 비트가 1 줄어 듭니다. 동반자에게 취약한 폰이있을 때마다 그 뒤에 1 비트를 추가해야합니다. 그러나 동시에 즉시 발생해야하므로 최소 게인은 14 비트입니다.
user5957401

감독과 비슷한 일을 할 수도 있습니다. 감독이 '특별한 구역'에 있지 않다고 가정하자 (모서리의 10 개 지점과 측면 중앙 줄)는 특별하다고 표시되어있다. 당신은 그 위치를 알고 있기 때문에-당신은 그 감독을 알고 있습니다. 이제 주교가 두 명 있고 다음 작품에 각각 0 또는 1을 줄 수 있습니다. 이것은 또 다른 4 비트를 제공하지만 최악의 경우 특수 구역의 주교가 있으며 이득은 없습니다.
user5957401

14

160 비트 최악의 경우

이전 답변을 22 바이트 게시 한 후 21 바이트로 줄일 수 있는지 궁금해지기 시작했습니다. 그러나 피터 테일러의 놀라운 166 바이트를 보았을 때 나는 "행복하다, 5 개의 32 비트 단어가 가능해 보인다"고 생각했다.

그래서 꽤 많은 생각을 한 후에, 나는 이것을 생각해 냈습니다. 159.91936391 바이트 (꽤 딱 맞습니다!)이 압축 수준은 상당히 복잡한 프로그램이 필요하지만 합리적인 시간에 실행하는 방법에 대해 생각했습니다.

이것은 긴 글이 될 것이므로, 제게 견디십시오. 오늘 내가 할 수있는 것을 게시하고 곧 몇 비트의 코드를 추가 할 것입니다.

이를 수행하는 방법은 다음과 같습니다.

En 잘못된 위치 (0 비트)로 인코딩 된 패시브 및 캐스팅

En Passant

다른 답변에서 언급했듯이, 침입자에게 취약한 폰이 서있을 수있는 최대 5 개의 사각형이 있습니다. 이들은 플레이어의 폰 옆에있는 사각형입니다.

이것을 인코딩하기 위해 enpassant에 취약한 폰은 첫 번째 또는 마지막 행의 사각형 중 하나에있는 것과 교환됩니다. 이것은 남자 또는 빈 사각형 일 수 있습니다. 폰이이 행에있을 수 없기 때문에 이것은 잘못된 위치를 생성합니다. 디코더는 폰을 정확한 위치로 돌려 놓고, 동반자 정보를 추출해야합니다.

이것이 캐슬 링 인코딩을 방해하지 않기 위해서는 게임 시작시 왕들이 서있는 사각형이 방해받지 않아야하며, 엔코 던트 인코딩 절차가 왕들을 나란히 배치하지 않아야합니다. 이는 불법적 인 왕의 입장입니다. 이 포인트 중 두 번째 포인트를 만족시키기 위해, 인코더는 엔트 폰트 폰을 어느 정사각형으로 교환 할 것인지에 대한 두 가지 선택이 있습니다. 최대 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. 따라서 가능한 모든 캐스트 가능성을 인코딩하기에 충분한 불법 위치가 있습니다.

적어도 하나의 왕이성에 들어갈 수 있다면, 인코더는 캐슬 링 데이터와 성에서 허용되지 않는 왕들의 위치 데이터를 테이블에서 찾거나 (또는, 여기에 지정하지 않은 알고리즘을 사용하여) 불법을 생성합니다 두 왕의 위치. 그런 다음이 광장에서 일어난 일과 왕을 교환 할 것입니다.

이것은 엔 패넌트 이후에 인코딩되고 디코딩되기 전에 중요하다. 그렇지 않으면 잠재적 인 간섭이있다.

비교

그래서 지금까지 나는 비트를 사용하지 않았습니다! Peter의 대답을 살펴보면 여전히 인코딩해야 할 내용이 다음과 같습니다.

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 인의 최악의 경우이다 (Peter의 답변 참조). 아래에 **로 표시된 두 가지 점에서 (최소한 29 인의 경우) 약간의 개선을 보여줍니다.

어느 사각형이 점유되어 있습니까? 누구의 차례입니까?

사용되는 사각형을 인코딩하는 쉬운 방법은 64 비트 그리드를 사용하는 것입니다. 이것은 또한 얼마나 많은 사각형이 점유되어 있는지 알려줍니다. 그러나 32 평방 이상을 차지할 수 없기 때문에 다소 낭비입니다. 내 솔루션은 1을 사용하여 점령 된 사각형을 흰색으로 돌리면 인코딩하고 0을 사용하여 점령 된 사각형을 검은 색으로 돌리면 인코딩합니다. 이제 모든 조합이 사용되며 폐기물이 없습니다.

따라서 우리는 턴을 저장하기 위해 약간의 비용을 절약합니다 .32 1 미만, 흰색 턴, 32 1 이상, 블랙 턴입니다. 유일한 모호한 경우는 모든 남자가 보드에 있고 32 1과 32 0이있을 때입니다. 따라서이 경우에만 추가 비트가 필요합니다. 캡처가 발생할 때까지 프로모션이 불가능하므로이 추가 비트는 최악의 경우에 영향을 미치지 않습니다 (3 명의 남자가 캡처되고 29 명이 남아 있음).

사각형을 차지하는 남자의 색

우리는 위에서 몇 명의 남자가 있는지 알고 있습니다. 다음 파스칼 삼각형 추출은 다양한 분포의 흑백에 대해 얼마나 많은 가능성이 있는지 알려줍니다. 예를 들어, 3 명의 남성의 경우 가능성은 다음과 같습니다. 3 명의 흑인 (1 순열) 2 명의 흑인, 1 명의 백인 (3 개의 순열), 1 명의 흑인, 2 명의 백인 (3 개의 순열), 3 명의 백인 (1 개의 순열). 3 = 8. 일반적으로 남성 수가 적을 경우 2 n 가능성이 있습니다. 그러나 모든 흑인과 백인의 가능성은 모두 불법입니다 (적어도 각면의 왕이 보드에 있어야 함). 실제 순열의 수는 2 n -2 (파스칼 삼각형의 1은 무시)입니다.

총 16 명 이상의 남성의 경우, 보드에 각 색상의 남성이 16 명을 초과 할 수 없다는 추가적인 제약이 있습니다. 따라서 모든 32 명의 남자가 보드에있을 때 각각 16 명이 있어야하며 총 수는 601080390으로 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

이 파스칼 삼각형 추출의 "행"을 합산하면 가능성의 수를 알 수 있습니다 (편리한 표현을 위해 삼각형을 시계 반대 방향으로 45도 회전 시켰기 때문에 표의 NE-SW 대각선을 의미합니다. 필요한 비트 수) 따라서 남자의 회전, 점령 된 사각형 및 색을 인코딩하는 것은 다음과 같습니다.

최대 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

두 가지 색상의 경우 어떤 남자와 어떤 순서로?

이전 답변에 따르면, 각 폰이 같은 열에서 반대 색상의 폰으로 차단되기 때문에 캡처가 발생할 때까지 폰을 승격시킬 수 없습니다. Peter의 대답은 모든 캡처가 한 쪽을 캡처하고 한 쪽을 캡처 할 수 있다고 상한으로 간주했습니다. 그러나 이것을 여러 경우로 나눌 수 있습니다.

  1. 검은 전당포는 흰색 전당포를 캡처합니다. 이제 캡처 전당포는 이제 다른 기둥에 있으므로 자유롭게 홍보 할 수 있습니다. 같은 칼럼에있는 그의 동료도 승진 할 수 있습니다. 흰 전당포의 원래 기둥에있는 검은 전당포도 홍보 할 수 있습니다. 이것은 3 개의 프로모션을 허용하는 유일한 경우입니다.

  2. 검은 전당포는 인접한 기둥에서 흰색 전당포를 지나서 흰색 전당포 (폰 이외)를 뒤에서 캡처합니다. 이를 통해 캡처 전당포와 원래 기둥에 있던 흰색 전당포를 홍보 할 수 있습니다. 각 측면마다 하나의 프로모션.

  3. 흰색 전당포는 폰으로 캡처됩니다 (전당포 이외). 일반적으로 Black에 대해 한 번만 승격 할 수 있습니다. 유일한 예외는 폰이 같은 컬럼으로 이동하는 여러 캡처로 인해 이미 막힌 폰 생성을 해제하는 경우입니다.

따라서 기본 사례로서 각 캡처는 양쪽에 대해 각각 하나의 프로모션을 허용한다고 생각할 수 있습니다. 캡처 된 사람이 폰인 경우, 캡처 측에 대한 추가 프로모션이있을 수 있습니다.

Peter와 비슷한 프로그램을 작성했습니다. 다소 거칠지 만 중요한 추가 사항이 있습니다. 플레이어가 일반 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 명의 남성이 있고 White에 15 명의 남성이있는 경우 Black에 대한 2 개의 프로모션과 White에 대한 1 개의 프로모션에 대한 상한 추정치를 고려할 수 있습니다.

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에서 많은 테이블을 수행 했으며이 작업을 게시하는 것이 큰 일이므로 나중에 수정해야했습니다. 내가 말했듯이, 나는이 게시물을 아직 끝내지 않았지만, 시간이있을 때 순열 계산 프로그램과 인코딩 / 디코딩에 대한 코드 조각을 추가 할 것입니다. 추신. 나는 많은 사람들이 이것을 읽고 있는지 전혀 몰랐습니다 :-)
Level River St

결국 당신은 독자들에게 약간의 cinfusion을 일으킬 수있는 비트 대신에 tak of bytes를 관리했습니다
masterX244

13

177 비트 최악의 경우

이 알고리즘은 거의 단순하지 않지만, 단지 2 개의 왕이 남았을 때 177 비트 최악의 경우 (실제로 184b = 23B), 13b (16b = 2B) 최상의 시나리오를 제공합니다.

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 비트)를 다항식 계수 기반의 인코딩으로 대체하여이를 더욱 효율적으로 만들 수 있습니다. sum_{i=0}^{15} sum_{j=0}^{15} 62! / (i! j! (62-i-j)!) < 2^87.45.
피터 테일러

내가 바꿀 유일한 것은 인 커런트 영역을 위해 좀 더 단순화 된 버전을 만드는 것입니다. 예를 들어,베이스 5에서 30 개를 인코딩하고 최대 5 개의 잘못된 위치가있는 경우 5 ^ 31 <2 ^ 72를 가질 수 있습니다. 당신이 그들을 enpassant (13)와 non-enpassant (59)로 나누었을 때와 동일하지만 추가적인 복잡함이 없습니다.
Alin Stoian

그렇게하면 실제로 1 여분의 비트가 사용됩니다. 그 이유는 (가장 최악의 경우) 5 가지의 가능성있는 가능성이있을 수 있지만, 여전히 6 번째 상태 인 "없음"이라는 가능성을 선언해야합니다. 이 경우에 1 개의 여분의 비트는 가능하지 않은 것을 선언하거나하지 않을 것입니다. (그리고이 방법을 사용하면 30 개의 조각을 포함하는 블록을 건너 뛰고 더 세밀하게 접근 할 수 있습니다. +1 비트 사용으로 이어집니다). 다음 5 번째 줄은 5 명의 잠재적 인 참가자 (화이트 턴)를 가능하게합니다. BWBBWBBW
FIQ

네 말이 맞아.
Alin Stoian

7

166 비트

  • 1 비트 : 누구의 차례입니까?
  • 2비트 : 어떤 캐슬 링 옵션이 열려 있습니까? (질문을 자세히 읽으면 NB는 자신의 차례가 된 플레이어의 캐슬 링 옵션 만 기록하면됩니다).
  • lg 6 ~= 2.585비트 : 어떤 enpassant 옵션이 열려 있습니까? (다른 답변보기)
  • 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 명의 남성의 경우 한 명의 왕, 한 명의 여왕, 두 명의 루크, Pawn) 그리고 각 분포의 모든 가능한 순열을 고려할 수 있습니다.

그러나 상호 의존성을 고려하면 훨씬 더 잘할 수 있습니다. 나는 이것을 매우 기본적인 수준으로만하고 있습니다 : 가능한 프로모션은 몇 개입니까? 폰은 "통과"되고 세 가지 방식으로 만 승격 될 수 있습니다 : 포획하여 다른 열로 이동합니다. 또는 그 반대의 폰 캡처와 다른 열로 이동합니다. 또는 상대방의 폰이 캡처됩니다. 따라서 흰색을 캡처하면 흰색과 검은 색에 각각 두 개의 패스가 생성됩니다.

프로모션에서 상한의 일부 테이블을 만들 수 있습니다.

(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 개의 프로모션이 있다고 가정 할 수 있으며 최악의 경우 (14 명은 14 명이고 다른 하나는 15 명인 경우)는 68.613 비트보다 여전히 더 우수하다고 가정 할 수 있습니다.

이것은 많은 불법적 인 입장을 허용하기 때문에 완벽한 표현이 되기에는 아직 먼 길입니다.

순열 테이블을 계산하는 코드 :

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 명의 선수 모두를 특별 케이싱하여 이전 점수를 회복 할 수 있었지만 지금은 그렇게하지 않을 것입니다.
피터 테일러

흥미로운 데이터! 3 명이 체포 된 이론상 최악의 사례
Level River St

@ steveverrill, 내가 정말로하고 싶은 것은 폰 위치와 프로모션 수를 하나의 "블록"으로 인코딩 한 다음 조각 위치와 값을 인코딩하는 것입니다. 그러나 프로모션을 고려하지 않고 최소 2 ^ 38 개의 전당포 위치가 있으며,이를 효과적으로 열거하면 지금까지 벗어날 수 없었습니다.
피터 테일러

@petertaylor 보드에 폰이 16 개 밖에없고 48 칸으로 제한되어 있다면 48! / 32! / 8! / 8! = 29019905518636890의 가능성이 있습니다. 2 ^ 54보다 약간 더! 이 중 일부는 불법이므로 보드의 한면에 한 가지 색상의 폰을 모두 가질 수는 없습니다.
레벨 리버 세인트

5

178 비트 (핀치에 174!) 최악의 경우

안녕하세요, 저는 대학 시절부터하지 않은 코딩으로 돌아가고 있습니다. 나는이 사이트를보고 이것이 흥미로워 보인다고 생각했다. 나는 약간의 이론적 인 점검을했으며 완벽한 알고리즘을 위해 적어도 146 비트가 필요할 것으로 보입니다.

어쨌든, 이것이 데이터를 구성하는 방법입니다. 기본 개념은 178 비트로 제공되지만 약간의 포커로 인해 174 (21 3/4 바이트)로 떨어질 수 있습니다. 175는 프로그래밍하기가 조금 더 쉽고 사람이 읽을 수 있으며 22 바이트 이내입니다.

A) 두 왕의 위치 : 흰색과 검은 색 12 비트 각각 6 비트

B) 남은 62 개의 사각형 중 어느 것이 사용됩니까? 62 비트 의 매트릭스

C) 누구의 차례입니까? 1 비트

총합 : 75 비트

D) En Passant. 백인이 움직일 경우, 최대 5 명의 검은 폰이 En Passant를 잡을 수있는 것처럼 보일 수 있습니다. 검은 색 폰은 5 행 (아래에서 0으로 시작)에 있어야하고 그 옆에 흰색 폰이 있어야합니다. 가능한 최대 캡처 수의 상황은 다음과 같습니다.

BWBBWBBW

5 행에 6 개의 검은 색 폰이 있다면, 흰색은 2 개의 사각형 만 서 있고 4 개의 검은 색 폰만 위협 할 수 있으므로, 동시에 En passant의 위협을 받고있는 5 개 이상의 검은 색 폰을 가질 수는 없습니다. 우리는 필요 그래서 5에 숫자 1을 (이 경우 흰색) 폰을 적대적인을 가지고 행 5 일 (최대 5) 졸의 어떤 다음은이 개 마지막 차례에 사각형 (고급 하였다 나타내는 또는 제로 경우에는 전당포 없다 이 상황에서 마지막 차례에 이런 식으로 움직였습니다.)

E) 점령 된 사각형을 30 개까지 (왕을 포함하지 않음)에 무엇이 포함되어 있습니까?

각각 10 진수로 표시되는 10 가지 가능성이 있습니다.

최하위 비트는 색상을 나타냅니다.

따라서 짝수는 흰색이고 홀수는 검은 색입니다.

화이트 / 블랙

폰 0/1 (또는 캐슬이 허용되는 루크 *)

기사 2/3

비숍 4/5

루크 6/7

퀸 8/9

*성에 허용되는 (그리고 첫 번째 또는 마지막 행에서 이동 한 적이없는) 루크는 6 또는 7 대신 0 또는 1로 표시됩니다. 또는 마지막 행.

이것은 최대 30 자리의 십진수를 제공하는데, 우리는 6을 곱한 다음 En passant에 대한 코드를 추가 할 수 있습니다. 결과 숫자는 103 비트에 맞으며, 위에서 언급 한 75에 추가하면 103 + 75 = 178 비트가 됩니다. 실제로 6 대신 10을 곱하면 사용되는 비트 수에 차이가 없으며 디코딩이 더 쉽습니다.

이것은 22 바이트보다 2 비트 더 큽니다. 그러나 아래 설명과 같이 174 비트로 푸시 다운 할 수 있습니다.

조각이 포착되지 않으면 폰을 승격시키는 것이 불가능합니다 .

증거는 다음과 같습니다. 흰색이 게임의 시작부터 열 (예 : 열)에 자신의 폰을 홍보한다고 가정한다고 상상해보십시오. 이 폰의 반대편에 검은 폰이 있습니다. 따라서이 폰을 승격 시키려면 다음 중 하나가 발생해야합니다.

1) 검은 전당포가 캡처됩니다.

2) 검은 전당포가 다른 조각을 포착하여 이동합니다.

3) 흰색 전당포는 D 열과 같은 인접한 열의 전당포를 캡처합니다.

4) 화이트 폰은 인접한 컬럼에서 블랙 폰을 통과하거나 통과시킵니다. 그런 다음 동일한 컬럼에서 조각을 캡처하여 화이트 폰이 컬럼을 변경합니다.

사례 4가 가장 흥미 롭습니다. 이제 E 열에서 시작된 흰색 전당포가 승진의 명확한 길을 가지지 않았기 때문입니다. 열 E에 남아있는 열의 검은 색 폰도 승격 할 수 있습니다. 따라서 한 번의 캡처로 각 색상의 폰 하나를 승격시킬 수 있습니다.

어쨌든, 한 조각이 캡처 될 때까지 폰이 승격 될 수 없다는 사실은 30 번째 조각을 저장할 필요가 없음을 의미합니다. 게임을 시작할 때 조각 코드의 전체 세트가 항상 같은 양 = 80이기 때문에 제거 (또는 빼기)로 해결할 수 있습니다. 사소한 점은 루크가있는 사각형을 보장해야한다는 것입니다 게임의 시작 부분에서는 첫 번째 스캔 중 하나입니다 (마지막으로 진행 한 경우 루크가 캐슬인지 여부를 알 수 없기 때문에). 이것은 행 0과 행 7에서 행 1을 스캔하여 쉽게 수행 할 수 있습니다. r = 8 ~ 1 스캔 행 [r mod 8].

따라서 (B)의 비트 행렬은 몇 개의 조각이 있는지 알려줍니다 (킹 제외). 30이 가득 찬 경우 인코딩 할 때 마지막 조각을 무시하면 디코더가 원래 상태로 작동합니다. 이제 최대 29 자리의 10 진수를 얻습니다.이 숫자에는 6을 곱한 후 En Passant 코드에 추가됩니다. 결과 숫자는 99 비트로 짜서 총 99 + 75 = 174 비트를 제공합니다.

예를 들어 실제 위치는 다음과 같습니다. 화이트는 방금 첫 번째 움직임 (고급 전당포)을 만들었고 블랙 턴입니다.

rnbqkbnr
pppppppp


    P

PPPP PPP
RNBQKBNR

A) 왕의 위치 (8 진수로 된 흰색 / 검정, 12 비트 ) : 03 73 = 000011 111011

B) 어떤 사각형이 사용됩니까? 왕을 건너 뛰고 행 0 (하단 행)으로 시작한 다음 위에서 아래로 다른 모든 행으로 시작하십시오.

1111 111

1111 111
11111111
00000000
00000000
00001000
00000000
11110111 

C) 블랙 턴 : 턴 비트 = 1

D) En Passant. 검은 폰 옆에 흰색 폰이 없기 때문에 (이 폰이 마지막 이동을 진행 했음에도 불구하고) 행할 수있는 폰이 없으므로 D = 0입니다. 옆에 적대적인 폰이있는 폰만 고려하는 대신 양쪽에 친근한 조각이없는 모든 폰을 고려하면이 상황에서 폰이 하나 있기 때문에 D는 1이됩니다. 폰은 마지막 차례에 실제로 움직였습니다.

E) 다시, 맨 아래 줄부터, 맨 아래에서 다른 맨 아래 줄까지 왕을 건너 뛰고 4 개의 성곽이없는 루크는 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)

디코딩 할 때는 오른쪽에서 왼쪽으로, 인코딩 할 때는 왼쪽에서 오른쪽 (역순)으로 스캔하는 것이 가장 좋습니다. 최대 일관성을 유지하면서 적은 부분이있을 때 우리는 적은 수있을 것이라는 점을이 수단 (즉, 우리는 빈 공간 / 제로 드문 드문 점령 보드의 압축을 사용하려면, 후행하지 선도 할 싶어.) 우리는 두 왕이있을 때 보드에는 위에서 언급 한 75 비트와 함께 가장 좋은 경우 78 비트의 데이터를 저장하는 3 비트가 있습니다. 각 추가 피스는 3.5 비트보다 약간 아래에옵니다 (100 개 128이므로 2 개는 7 비트로 저장할 수 있음).

99 비트 정수가 64 비트 정수 변수에 맞지 않기에는 실제 문제가 있습니다. 이는 많은 프로그래밍 언어가이를 지원하지 않음을 의미합니다 (29-30 자리의 문자열 표현을 변환 할 수는 없습니다) 정수로 수.) 22 바이트의 인코딩 쉬운 방법으로서, 우리는 각각 50 비트마다 (총 100 비트에 맞는 두 개의 15 자리 숫자로 30 자리 숫자 (29 개 코드 + EN 김에 코드) 끊을 수 위에서 언급 한 75를 더하면 175 비트가 최악입니다.)

위에서 언급 한 것처럼 최대 압축의 경우, 소수점 이하 29 자리와 En Passant 코드 (6 개의 가능한 값)는 99 비트 (약 174 비트)에 맞지만이 크기의 정수에 대한 언어의 지원은 없습니다. 프로그램하기가 복잡합니다. 29 색 비트를 분리하고 색상 (70 비트, 64 비트 변수에 거의 맞는)과 별도로 피스 타입 코드 (5 가지 가능성) 및 Enpassant 코드 (6 가지 가능성)로 작업하는 것이 더 쉬울 수 있습니다.


마지막 남자와 좋은 트릭.
피터 테일러

5

여기에 완전한 해결책, 실제 최악의 경우 181 비트가 있습니다.

여기서 초점은 쉽게 이해할 수있는 간단한 프로그램입니다.

입력은 FEN이며 여기는 시작 위치이며 6 개의 필드가 있습니다 (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

필드 1 : 킹 (12 비트)의 위치를 ​​인코딩합니다.

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

필드 2 : 조각 조각을 인코딩합니다 (조각 당 최대 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//

필드 3 : 활성 색상 (1 비트)

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

필드 4 : 주조 가용성 (4 비트)

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

필드 5 : enpassant (0 또는 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 비트

가장 나쁜 경우는 전임자를 위해 폰을 남겨 두지 않고 모든 조각을 홍보하는 것입니다.

SHOWN 코드 12 + 75 + 55 + 34 + 1 + 4 = 181 비트의 실제 실제 최악 사례

FIQ는 이 간단한 구성표의 두 가지 개선 사항을 보여 주지만 코딩하기가 더 어렵습니다.

  • 폰이 갈 수 없기 때문에 행 1과 8의 조각 인코딩에서 비트 2를 제거하십시오 (최대 16 비트 절약)
  • 폰을 사용하여 캐스트 가능한 루크를 인코딩하십시오 (4 비트 절약)

이 답변에 표시되지 않은 유일한 코드는 (간결하게) : 필드에서 입력 FEN을 끊는 것 ( split /\s/) 및 변수 할당입니다.


플레이어는 자신의 모든 폰을 홍보 할 수 있습니다 (적의 폰을 캡처 할 수 있음). Qn4QQ / Qb6 / Qq1k4 / Qr6 / Qb6 / Qr6 / Qn4NK / RNB2B1R b--0 84
Krzysztof Szewczyk

@KrzysztofSzewczyk, 그렇습니다. 위에 언급 된 것입니다 PPpp=>QQq_
William Entriken

4

총 데이터는 33 바이트가 필요합니다

(이 의견은 전당포 판촉에는 효과가 없다는 것을 알게 된 사람에게 감사합니다. 해결할 수있을 때 업데이트됩니다)

첫 번째 바이트에는 5 비트를 사용합니다.

  • 첫 번째 비트 : 플레이어 차례, 1 = 흰색
  • 두 번째 비트 : 블랙 킹 사이드 캐슬, 1 = 캔 캐슬
  • 세 번째 비트 : 검은 여왕 쪽 성, 1 = 성
  • 네 번째 비트 : 화이트 킹 사이드 캐슬, 1 = 캔 캐슬
  • 다섯 번째 비트 : 하얀 여왕 쪽 성, 1 = 성

다음 32 바이트는 각 체스 조각을 사전 정의 된 순서로 나타내는 데 사용됩니다.

  • 3 비트 : 행을 나타냅니다
  • 3 비트 : 열을 나타냅니다
  • 1 비트 : en-passant, 1 = can-passant를 나타냅니다.
  • 1 비트 : "통과 가능"비트가 1 인 경우 : 어느 쪽을 나타내며, 0 = 왼쪽
    은 캡처 여부를 나타냅니다. 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
폰이 여덟 번째 등급에 도달하고 기사, 주교, 루크 또는 여왕으로 승격 되면 사전 정의 된 주문은 많이 사용되지 않습니다 .
squeamish ossifrage

Snow의 @Doorknob ok 저는 알고리즘을 연구하고 있습니다. 밤에는 약간 늦었고 피곤합니다. 그래서 조금 느리게하고 있습니다
ace_HongKongIndependence

그렇다면 해결책이 없다면 왜 이것을 게시 했습니까?
Doorknob

3
사람들이 여전히이 답변이 허물이고 여기에 가치가 없다고 생각하면 계속 진행하여 투표하여 삭제하고 투표하면 내 계정을 삭제할 수도 있습니다. 난 그냥 내가 생각할 수있는 것을 공유하고 싶어, 왜 너희들은 그렇게 의미해야합니까?
ace_HongKongIndependence

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

그런 다음 밑수 11의 큰 64 자리 숫자에 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.

참가자를 0에서 8 사이의 숫자로 저장할 수 있습니다 (현재 플레이어가 참가자를 캡처 할 수있는 열은 무엇입니까?). 13^64 * 9239.99로 11 비트를 절약합니다. 킹 포지션을 별도로 인코딩하여 더 많은 비용을 절약하십시오.
우고 렌

내 게시물에 댓글을 작성한 Snow의 Doorknob에 따르면 이런 종류의 답변은 "답변이 아닙니다". 그냥 말하면 참고로 C 코드를 내 답변에 추가하기 전에 그의 의견이 게시되었습니다.
ace_HongKongIndependence

@ugoren : 나는 잊어 버렸습니다. 네 말이 맞아, 한 폰만 동시에 참여할 수 있다는 것을 잊었다.
Joe Z.

@ace : 귀하의 답변은 인코딩 및 디코딩 코드를 포함하지 않으므로 유효하지 않습니다. 폰 프로모션 사례를 설명하지 않기 때문에 유효하지 않습니다 (이 경우 사전 정의 된 순서의 순서는 아무 것도하지 않습니다). 문제의 핵심은 데이터 인코딩 체계를 요구하는 것입니다. 이 프로그램은 그와 인터페이스 할 무언가입니다.
Joe Z.

3

? 비트

(≥ 최악의 경우 217, 최상의 경우 17, 초기 보드의 경우 179)


인코딩 설명

여분의 메타 데이터는 자신의 차례 (1 비트)와 캐슬 링 (4 비트, 즉 왕의 옆에 하얀 성, 여왕의 옆에 그리고 검은 색의 유사)으로 구성됩니다.

보드 위치 자체를 위해 활성 조각 세트로 인코딩합니다. 글쎄, 실제로, 우리는 조금 설명 할 이유 때문에 특정 순서로 조각을 열거해야합니다. 각 조각에 대해 우리는 그 색 (1 비트), 그 종류 (6 가지 종류를 포함하는 3 비트, 그리고 "포수자가 가져갈 수있는 앞발"을위한 1 가지 종류)와 그 위치를 저장합니다.

흥미로운 부분은 다음과 같습니다. 조각의 위치를 ​​좌표로 저장하는 대신 조각을 왼쪽에서 오른쪽, 위에서 아래로 순서로 열거 할 때 마지막 조각과의 상대적 거리를 저장합니다 (예 : A8). , B8, ..., G1, H1). 또한 거리를 가변 길이 숫자로 저장 1하여이 조각이 이전 조각 바로 옆, 0xx1-3 조각 000xxx건너 뛰기, 4-10 조각 건너 뛰기, 000000xxxx11-25, 0000000000xxxxx26-56 그리고 마지막 000000000000000xxx으로 57-62.

I 만든 요지 이 부호화하여 부호화를 어떤 위치, 어떤 주석의 초기 위치에 대한 하나 주석.

최악의 비트 크기를 분석하는 방법을 모르지만 요점의 예제를 살펴보면 적어도 알고리즘이 다소 효율적이어야한다고 생각합니다.


디코더 구현

아래는이 인코딩을위한 빠르고 더티 디코더입니다 (위의 주석이 달린 예제에서와 같이 텍스트로 인코딩 된 이진 데이터를 입력하고 '0'또는 '1'이 아닌 것을 건너 뛰는 것). 유니 코드 체스 판을 표준 출력으로 제작합니다.

#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

하나는 217 개 비트를 요구하는 것 같다 @squeamishossifrage : gist.github.com/FireyFly/8639791 (시험의 경우 주셔서 감사합니다, 나는 난이도가 하나 그것을 시험해보고 싶었다!)
반딧불

이봐, 나쁘지 않아. 계속가요!
으스스한 ossifrage

2

최대 : 184 비트, 최소 : 75 비트

나는 @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

각 조각의 코드 앞에는 2 비트가 붙어서 어떤 팀에 소속되어 있는지 표시 할 수 있습니다 ( 10흰색, 11검정). 0빈 공간을 인코딩하는 데 사용할 수 있습니다. 이러한 아이디어를 통해 원하는 절차를 사용하여 전체 보드에 대해 사각형으로 인코딩을 만들 수 있습니다. 반복 순서를 가정하겠습니다 a1, b1, c1, ... f8, g8, h8. 즉, 위에 표시된대로 이러한 코드를 나열하면 해당 코드를 제외한 모든 정보가 인코딩됩니다. 매우 간단한 체스 엔진은 폰, 루크, 킹을위한 "클래스"를 사용하여 거세와 패배자가 합법적인지 판단 할 수 있습니다. 또한,이 체계는 폰 프로모션을 쉽게 처리합니다. 플레이어가 폰을 루크에게 승격시키는 경우, "이동 된"변형이 선택되는 한 킹 또는 퀸 사이드 코드를 사용할 수 있습니다.

내가 생각할 수없는 병리학 적 위치를 제외하고,이 인코딩의 최악의 시나리오는 모든 조각이 여전히 보드에 있고 이전 플레이어가 폰을 두 칸 앞으로 움직일 때입니다. 예를 들어 아래 보드는 다음을 인코딩합니다 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은 2 개의 공간 점프하는 폰을위한 것, 24는 나이트를위한 것, 24 도둑 28 명, 여왕 12 명, 왕 12 명.

조각이 이동하고 캡처되면 인코딩 크기가 줄어 듭니다. 가장 좋은 시나리오는 보드에 두 개의 왕만 표시됩니다. 플레이어를 나타내는 1 비트 + 빈 사각형을 나타내는 62 비트 + 왕을 나타내는 12 비트는 최소 길이가 75 비트입니다.

오늘 다시 또는 나중에 내림차순으로이 인코딩을 보여주는 일부 코드로이 응답을 다시 편집 해 보겠습니다. 지금은 다른 사람들이이 인코딩에 대해 어떻게 생각하는지 궁금합니다.


1
루크에 비트를 저장할 수 있습니다. 위치에 따라 여왕과 왕의 편을 결정할 수 있으며, 이동 루크가 어느 쪽에서 왔는지 알 필요가 없습니다. 그래서 당신은 루크에 대한 정보가 필요합니다.
찰스가

... 실제로 데이터를 조각 수준으로 저장하는 것이 더 쉽게 인코딩 / 디코딩 할 수 있지만 시작시 마커를 방금 저장 한 경우 전체적으로 최악의 경우 비트를 저장할 수 있습니다 (예 : 마커 11001수단 B'S MOVE W CAN KSC W CANT QSC B CANT KSC B CAN QSC). 이는 인코딩에서 측면 당 5 비트 대신 4 비트이거나 루크에서 측면 마커를 제거하면 측면 당 3 비트입니다. ( KSC= QSC킹 사이드 캐슬. = 퀸 사이드 캐슬)
찰스가 아닙니다.

또한 프로모션으로 인해 최대 9 명의 퀸즈 또는 10 명의 기사 (또는 다른 비 법적, 비 본적이 아닌 조각)를
가질 수 있습니다.

1

184 비트 = 23 바이트 최악의 경우이며 너무 복잡하지는 않습니다.

A. 점유 한 사각형 : 64 비트 = 8 바이트 B. <= 32 점유 된 사각형의 색상 : 32 비트 = 4 바이트 이제 비왕이 차지하는 <= 30 제곱 만 사용 : B. 기수로 인코딩 된 PNBRQ 사용 5 ^ 30 가능성에 대해 5; 킹 포지션, 무버-컬러, 화이트 & 블랙 캐슬 링 권한, 패배 제곱 광장 (8 가지 가능성 + 없음, 9 번째)의 경우 32 * 31 * 2 * 4 * 4 * 9; 이 숫자 5 ^ 30 * 32 * 31 * 2 * 4 * 4 * 9 = 266075134277343750000000000 = 2 ^ 87.782는 전체 인코딩에 대해 총 64 + 32 + 88 = 184 비트의 88 비트에 적합합니다.

예를 들어 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 비트로 표시됩니다. 첫 번째 비트 : 색상 ( 0=white, 1=black) 두 번째 -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을 제공합니다. 아무 것도없이 내 한계를 넘어선 다. 트릭이 시작되는 곳입니다.

알았어-위의 유형이 보입니까? 비숍 0과 비숍 1? 폰 0과 폰 1? 이러한 유형은이 조각 뒤에 삽입 할 비트를 알려주기 때문에 그렇게 지정되어 있습니다. 따라서 Bishop0은 그 이후에 0이 있음을 의미합니다. 즉, 다음 조각이 흰색입니다. Bishop1은 다음 조각이 검은 색이라고 말하고 pawn0과 pawn1은 동일하게 작동합니다. (이 작품이 마지막으로 열거 된 작품이라면 다음 차례에 대해 알려줍니다).

최악의 경우에는 보드에있는 모든 조각이 포함되므로 폰 16 개와 주교 4 개가 있으면 20 비트가 절약됩니다. 나는 173로 줄었다.

괜찮아. 최악의 경우에 16 비트 색상이 인코딩되면 색상 인코딩을 중지합니다. 앞으로 알고 있습니다. 내 최악의 경우에는 이제 흰색 조각이 포함되어 캡처없이 멀리 구석에 있습니다. 거기서, 나는 단지 한 비트 만 저장합니다. 172.

이제 조각 이름을 지정하는 순서를 변경하겠습니다. 우리는 외부에서 시작하는 열을 따라 이름을 붙일 것입니다. 시작 부분에 이름이 지정된 보드는 동일하게 유지되지만, 그 위에 조각을 놓으면 오른쪽 아래에서 흰색으로 시작하여 그 열 위로 올라갑니다. 그런 다음 오른쪽 하단의 검은 색으로 이동하여 해당 열로 올라갑니다. 나는 흰색의 오른쪽 아래 알 수없는 셀로 뛰어 들었습니다. 이것은 최악의 경우가 다시 시작임을 의미합니다. 내 이유는 내 패배 한 속임수, 내가 잃어버린 다음 두 비트 및 캐스트와 관련이 있습니다.

이제 폰을 길게 (길게 논의했듯이) 피스를 캡처해야합니다. 따라서 32 조각이 있다는 것을 알면 31 개만 표시하면됩니다. 마지막 조각은 고유하게 식별됩니다. 결과적으로, 이것은 2 비트 만 절약합니다. 마지막 조각은 폰 / 비숍 (일반적으로 다음 조각에 1을 저장하기 때문에 3 비트를 소비합니다) 일 수 있기 때문에 색상이 이미 결정되어 있기 때문에 2 비트 나는 170 비트로 떨어졌다.

폰이 승격되면 단순히 타입을 변경합니다. 보드에서 나오는 각 조각에 대해 (최소) 3 비트를 제거했으며 2 개의 폰 프로모션 비용이 2 비트이므로 프로모션에서 (느리게) 감소하고 있습니다.

Castling. 거세가 일어나기 위해 왕이나 그와 관련된 사기꾼은 이사하지 않았을 것입니다. 따라서, 루크가 둘 다를 찌를 수 있고 왕은 원래 장소에있을 것입니다. 따라서 거세 할 수있는 루크들은 그 색의 왕들과 같은 곳에 나열 될 것입니다. 이것은 불법이며 (보드에 같은 색의 두 왕 또는 세 왕) 각 색상에 대해 세 가지 가능한 설정에서만 발생할 수 있습니다 (왼쪽, 오른쪽, 두 루크가 모두 왕으로 표시됨). 디코딩은 가능합니다. 따라서 비트가 없으면 캐슬 링을 인코딩했습니다.

En Passant 여기서 우리는 또한 불법적 인 위치를 사용할 것입니다. 한 번에 하나의 폰만이 동반자의 위험에 처할 수 있습니다. 네 번째 줄에 있어야합니다. 취약한 폰은 홈 행으로 다시 튕겨져 있습니다. 그 폰은 자신의 첫 번째 행에 있습니다-불법적 인 위치, 상황은 디코더에게 명백 할 것입니다-위치를 반전시키고 폰을 전임자에게 취약한 것으로 표시합니다.

마지막 조각은 '고유하게 식별'되어야하므로 주문과 관련이 필요했습니다. 표준 순서대로, 우리는 뒷 모퉁이의 루크가성에 올 수 있는지 알 수 없습니다. 우리가 외부에서 일할 때, 우리는 그 루크가 자신의 구석이나 보드 중간에 취약한 전당포로 전환되어 있기 때문에 어디에서나 목록에 올랐다는 것을 보증합니다. 우리는 루크의 유형을 들었습니다. 폰이 취약하기 위해서는 폰이 내부에 폰이 있어야하기 때문에 그 이후에 조각이있을 것임을 알고 있습니다 (위의 지침에 따라 나중에 인코딩됩니다).

아, 최악의 경우 보드의 모든 조각이 포함되도록하기 위해, 32 조각보다 적 으면 64 비트 보드를 사용하여 흰색을 나타낼 때 조각을 나타내는 0을 사용하여 회전 및 점유 위치를 식별 할 수 있습니다. 검은 색 턴일 때 1을 돌립니다.

그래서 우리는 무료로 패배하고 거세했습니다. 우리는 마지막 조각을 무료로 집어 들었습니다. 표준 조각에 20 비트를 버렸습니다. 나는 최악의 경우 여기에 하얀 중간 전당포가 전진하고 검은 조각이 여왕과 여왕 사이에 있다고 생각합니다. 빠른 이중 확인 : 첫 번째 조각이 캡처됩니다-폰으로, 폰에서 보드에서 3 비트, 마지막 조각으로 보드에서 3 비트, 턴 마커에서 1 비트가 사라집니다. 보드에서 2 개의 폰을 2 비트로 다시 승격하십시오. 아 젠장, 나는 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 가지 기능을 빌드합니다. 조각과 보드 구조를 약간 분리하고 조각 유형과 '암시 적'조각을 알아내는 것. 다음 함수는 보드 구조를 약간의 괴짜 (초기 알고리즘과는 다른) 순서로 채 웁니다. 다음 함수는 채워진 보드를 가져 와서 잘못된 위치를 감지합니다. 그런 다음이를 수정하고, "x pawn-e"및 취약한 "x rook-c"에 취약한 폰의 이름을 수정하고 폰의 이름을 바꿉니다. 최종 기능은 해당 기능을 순서대로 실행하고 현재 보드 및 턴인 출력을 제공하는 래퍼입니다.

시작 위치의 인코딩도 포함했습니다. (호출해야하지만 c(startboard,newpieces)코드는 해당 위치에서 래퍼 함수를 ​​호출합니다.


이건 재미 있네. 작동하는 구현을 개념 증명으로보고 싶습니다.
Mego

구현은 일반적으로 개념 증명을 넘어서는 몇 단계이지만, 디코더를 추가했습니다. R에 있으므로 비트 대신 부울을 사용합니다 (죄송합니다-너무 많은 시간을 사용하고 싶지 않았습니다). 그러나 나는 그것이 개념의 증거라고 생각합니다.
user5957401

0

229/226 비트

이것은 성공적이지 않은 것으로 판명되었지만 다른 사람들이 같은 길을가는 것을 구할 수 있습니다.

간단한 버전 :

  • 1 누구의 차례인지
  • 4 4 개의 캐스터 링 가능성을위한 비트
  • 3동반 가능성에 대한 비트 . 이것은 내가 처음 이해했던 것보다 더 깊이가 있습니다. 참가자 는 캡처 된 폰과 같은 순위 (행)에서 이동하는 폰으로 수행해야합니다. 사례 분석은 우리가 마지막으로 이동 한 색상의 많은 폰이 정확히 두 개의 사각형을 고급 방법을 알고 나면, 최대 6가있을 것을 나타냅니다 ...하는 김에 (취약 더 폰이 없다는 경우를 포함 경우 엔 옆모습이 ). 더 나쁜 경우는 폰이 5 개입니다 (잠재적으로는 모두 취약합니다. 예 : PpPPpPPp5 개가 취약 P합니다). 6 심으로 최대 2 심 복을 위협 할 수있는 각각의 동일 순위에서 최대 2 적의 폰,가 ...하는 김에는 . 그러므로 우리는 필요합니다ceil(lg 6) = 3 여기에 비트 합니다.

그런 다음 보드. 보드에는 64 개의 사각형이 있으므로 사각형 인덱스를 6 비트로 인코딩 할 수 있습니다. 우리는 왕을 시작으로 계급별로 색깔을 번갈아 가며 나열합니다.

  • 6비트 : 하얀 왕의 위치. (보드에 보장됨).
  • 6비트 : 검은 왕의 위치. (보드에 있다고 보증했다. 최악의 경우 백인 왕이 모퉁이에있을 수있는 장소는 60 곳이다. 가장 좋은 경우, 흰색이 가장자리에 있지 않은 경우 55 곳이있다).
  • 6비트 : 하얀 여왕의 위치. 백색 여왕이 없으면 백색 왕의 위치를 ​​신호로 반복하십시오.
  • 각각의 추가 백색 여왕 1에 대해 위치에 대해 비트 다음에 6 비트가옵니다.
  • A는 0비트.
  • 검은 여왕을위한 Ditto.
  • 루크, 주교, 기사 및 폰에 대한 비슷한 프로세스이지만 이미 해당 색상의 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 4 개의 캐스터 링 가능성을위한 비트
  • lg 6동반 가능성에 대한 비트 .
  • 6 백인 왕을위한 비트
  • lg 60 검은 왕을위한 비트 (최악의 경우)
  • lg 63 하얀 왕비가없는 경우 하얀 왕의 위치를 ​​사용하여 흰 여왕의 비트 (수표를 보는 수준으로 복잡하게 만들고 싶지 않기 때문에)
  • 각 추가 화이트 퀸 들어, 1비트는이어서 lg 62, lg 61자신에 대한 위치 등의 비트.
  • A는 0비트.
  • lg 63 검은 여왕에 대한 비트 (또는 흰색 여왕이있는 경우 더 적음).
  • 기타

실제로 존재하는 n 번째 사람은 66-n가능한 값을 가지고 있습니다. 색상에 유형이없는 경우 66-#men so far비트를 기록하는 데 비트를 사용했습니다 (구분 기호에 1 비트 추가). 극단적 인 경우는 다음과 같습니다.

  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 비트 인 것 같습니다 .

폰 전체가 64 개가 아닌 48 개로 제한되어 있기 때문에 폰을 조각하기 전에 평균적으로 더 나은 결과를 얻을 수 있습니다. 그러나 최악의 경우 모든 남자가 보드에 있고 모든 폰이 승격되었다고 생각합니다. 이것은 남자를 계산할 수있는 것이 아니라 "폰 없음"플래그가 필요하기 때문에 2 비트 더 비싸게됩니다.


0

이것은 체스 서클의 토론 주제입니다.

다음은 164 비트 https://groups.google.com/forum/#!topic/rec.games.chess.computer/vmvI0ePH2kI 155의 간단한 증거입니다. . /chess/chess.html

지나치게 단순화 된 전략 :

  • 폰을 찾을 수있는 곳으로 폰을 제한하십시오.
  • 군대가 오리지널 작품과 전당포 프로모션을 고려하도록 제한
  • 프로모션이 불가능한 프로모션 및 상황에 대해 열심히 생각하십시오.

2
링크 전용 답변은 좋은 답변이 아닙니다. 답변에 대한 링크뿐만 아니라 게시물 내에 완전한 답변을 제공해야합니다. 귀하의 답변이 본인의 작품이 아닌 경우 게시물을 커뮤니티 위키로 만들어야합니다.
ace_HongKongIndependence

게시물은 원본입니다. 답변 할 세부 정보 추가
William Entriken

1
이것이 답변에 내용을 포함시키는 이유의 예입니다. 두 번째 링크가 죽었습니다. 이거예요? tromp.github.io/chess/chess.html
mbomb007

-2

최소 : 0 비트

최대 : 1734 243 비트 (4.335 4.401 비트 / 보드 상각)

예상 : 351 177 비트 (4.376 4.430 비트 / 보드 상각)

그러나 입력과 출력을 결정할 수 있기 때문에이 시점까지 게임 기록을 인코딩하기로 결정했습니다. 한 가지 장점은 자신의 차례에 대한 추가 정보가 동반자이며, 파생되고 인코딩 될 수없는 위치를 성명 할 수있는 능력이 있다는 것입니다.

시도 1 :

순진하게 나는 각 비트가 3 비트 인 12 비트, 4 개의 트리플렛 (시작 x, 시작 y, 끝 x, 끝 y) 형식으로 각 움직임을 인코딩 할 수 있다고 생각했습니다.

우리는 시작 위치를 가정하고 먼저 흰색으로 이동하면서 조각을 이동합니다. 보드는 (0, 0)이 흰색의 왼쪽 아래 모서리가되도록 배열됩니다.

예를 들어 게임 :

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

다음과 같이 인코딩됩니다 :

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

이것은 12m 비트 의 인코딩으로 이어지며, 여기서 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)을 원하기 때문에 20 개의 가능한 이동이 있기 때문에 이것을베이스 20에서 13으로 인코딩합니다.

이제 게임 번호 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)을 원하기 때문에 20 개의 가능한 이동이 있기 때문에 이것을베이스 20에서 11로 인코딩합니다.

이제 게임 번호 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)을 원하기 때문에 29 개의 가능한 이동이 있기 때문에 이것을베이스 29에서 13으로 인코딩합니다.

이제 게임 번호 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 은 가능한 이동 횟수이고 '//'는 정수 나누기 연산자이고 '%'는 계수 연산자입니다. g 0 = g 1 + m 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 및 _m_ 3 = 564 % 29 = 13. 마지막으로 g 5 = 19 // 29 = 0 및 m 4 = 19 % 29 = 19.

이런 식으로 게임을 인코딩하는 데 몇 비트가 사용됩니까?

간단히하기 위해, 매 턴마다 항상 20 개의 움직임이 있고 최악의 시나리오에서는 항상 가장 큰 것을 선택한다고 가정 해 봅시다. 우리가 얻을 수있는 숫자는 19 ⋅ 20 m입니다.

+ 19 ⋅ 20 m-1 + 19 ⋅ 20 m-2 + ⋯ + 19 ⋅ 20 + 19 = 20 m + 1 − 1 여기서 _m은 이동 횟수입니다. 인코딩하는데 20 m + 1 - 1 우리가 로그인 할 필요가 2 (20 m + 1 에 대해이다) 비트 (m + 1) * 로그인 2 (20)를 4.3219 = * (m + 1)

평균 m = 80 (플레이어 당 40 개 이동)이므로 인코딩하는 데 351 비트가 필요합니다. 많은 게임을 녹화하는 경우 각 숫자에 필요한 비트 수를 모르기 때문에 범용 인코딩이 필요합니다.

m = 400 (플레이어 당 200 이동) 인 최악의 경우 인코딩하는 데 1734 비트가 필요합니다.

인코딩하려는 위치는 규칙에 따라 가장 짧은 경로를 통해 제공되어야합니다. 예를 들어 여기서 이론화 된 게임 은 최종 위치를 인코딩하기 위해 m = 11741이 필요하지 않습니다 . 대신 너비 우선 검색을 실행하여 해당 위치에 대한 최단 경로를 찾아서 인코딩합니다. 모든 체스 위치를 열거하기 위해 얼마나 깊이 들어가야할지 모르겠지만 400이 과대 평가 된 것으로 생각됩니다.

빠른 계산 :

12 개의 고유 한 조각이 있거나 사각형을 비워 체스 판에 배치 할 수 있습니다 (13 64) . 잘못된 위치가 많이 포함되어 있기 때문에 이는 과대 평가 된 수치입니다. 우리가 m 게임을 할 때 우리는 약 20m 위치를 만들었습니다 . 그래서 우리는 20 m = 13 64 일 때를 찾고 있습니다. m = 64 * log 20 (13) = 54.797이되도록 양쪽을 기록 합니다. 이것은 우리가 55 번의 움직임으로 어떤 위치로든 이동할 수 있어야한다는 것을 보여줍니다.

지금은 할 최악의 경우를 계산한다는 m 55 없다 = m 내 결과를 = 400을 편집합니다. m = 55 인 위치를 인코딩하려면 243 비트가 필요합니다. 또한 평균 사례는 약 m = 40이며 인코딩하는 데 177 비트가 필요 하다고 말합니다 .

이전의 할부 상환 인수를 사용하면 1734 비트로 400 "체스 보드"를 인코딩하므로 최악의 경우 각 "체스 보드"가 4.335 비트를 차지합니다.

참고 g = 0가 유효한 게임 하나를 나타낸다는 수있는 최소 제곱 최저 사각형의 이동 부재.

추가 사항 :

게임에서 특정 위치를 참조하려면 색인을 인코딩해야 할 수도 있습니다. 이것은 수동으로 추가 될 수 있습니다. 예를 들어 인덱스를 게임에 연결하거나 매번 마지막으로 가능한 이동으로 추가 "종료"이동을 추가 할 수 있습니다. 이것은 이제 플레이어가 인정하는 것을 고려할 수 있으며, 2 명이 연속으로 추첨에 동의 한 것을 나타낼 수 있습니다. 위치에 따라 게임이 체크 메이트 나 교착 상태로 끝나지 않은 경우에만 필요합니다.이 경우에는 암시 적입니다. 이 경우 평균 필요한 비트 수는 356이며 최악의 경우 1762입니다.


1
귀하의“상각”주장은 효과가 없습니다. 목표는 사용자가 제공 한 보드를 인코딩하는 것입니다. 이 보드를 인코딩하는 비용을 도중에 생성 할 수있는 400 개의 보조 보드로 나누지 않아도됩니다. (이것은 사용자가 400 보드를 독립적으로 선택하고 체스 게임을 구성하기위한 요구 사항에 의해 제한되지 않은 경우에만 가능합니다.) 또한 체스 게임은 이론적으로 수천 가지 움직임을 취할 수 있으며 OP는 최악의 경우에 관심을 갖는 것에 대해 명확합니다.
Anders Kaseorg

@AndersKaseorg : 매우 그렇습니다. 그것은 실제로 목표에 달려 있습니다. 다른 모든 알고리즘으로 전체 게임을 저장하려는 경우 m * c 바이트가 필요합니다. 여기서 m은 이동 횟수이고 c는 출력 크기입니다. 160 비트 솔루션을 사용하여 전체 80 개 무브먼트 게임을 저장하려는 경우 12800 비트가 걸리지 만 내 게임은 351 만 걸립니다. 경쟁을 위해 나는 당신이 맞다는 것을 인정하지만, 그것이 좋은 재산이라고 생각했습니다 보드뿐만 아니라 전체 게임을 저장하는 것이 매우 일반적이기 때문에 지적했습니다.
edggy

목표는 분명하다. “목표는 그 턴에 플레이어의 모든 이동 가능성을 결정하기 위해 사용될 수있는 체스 보드의 가장 작은 표현을 만드는 것입니다. … 당신의 점수는 최악의 시나리오-비트 단위의 가능한 최대 크기로 결정됩니다.”
Anders Kaseorg

@AndersKaseorg : 모호하다고 주장한 적이 없습니다. 방금 다른 접근법을 사용하기로 결정했습니다. 주목해야 할 것은 내 알고리즘을 사용하여 가장 작은 보드를 찾으려면이 위치에 도달하기 위해 가장 작은 경로가 필요하다는 것입니다. 예를 들어, 같은 보드 위치에 도달하기 위해 링크 한 11741 턴 게임에서, 우리가 관심있는 모든 것이 보드라면 그 길을 따를 필요가 없습니다. 따라서 연결된 게임을 인코딩하기 위해 단지 200 턴 이하의 사각형에 2 개의 왕이있는 가장 짧은 게임을 발견했습니다. 이것은 깊이 우선 검색으로 수행 할 수 있습니다.
edggy

만약 당신이 실제로 모든 포지션이 200 턴 이하로 도달 할 수 있다는 것을 증명할 수 있다면, 더 짧은 동등한 게임을 사용하는 것이 좋습니다. 또한 건설 내에서 발생하지 않는다는 것을 입증 할 수없는 경우 100 개 이상의 법적 이동으로 체스 위치 를 고려해야합니다 . 이 도전의 규칙에 따라 결과를 게임의 이동 횟수로 나누는 것은 여전히 ​​허용되지 않습니다.
Anders Kaseorg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.