Como posso converter movimentos de peças possíveis em um movimento real em um bitboard?

Jan 09 2021

Se eu tiver um bitboard (por exemplo, para quadrados de cavaleiros, ele pode se mover) como este:

00000000
00000000
00000000
00000000
00000000
01000000
00100000
N0000000

Como posso "convertê-lo" em um movimento ou "aplicar" esse movimento?

Respostas

2 AryanParekh Jan 09 2021 at 19:28

Na verdade, existem duas perguntas em sua postagem

  • Como converter ataques em bitboards em uma lista de movimentos?

  • Como representar esses movimentos?


  • Como representar esses movimentos?

Esta questão foi discutida aqui e aqui completamente. Mas para fornecer algum contexto aos leitores deste post, uma maneira muito simples de fazer isso pode ser usar uma classe / estrutura para representar um movimento

  • De (onde estava a peça móvel)
  • Para (onde a peça em movimento estará)
  • Sinalizador de movimento especial (se o movimento foi um movimento especial, ou seja, enpassant, casting, promoção)
  • Peça promovida (se o movimento foi um movimento de promoção, para qual peça foi promovido)

Você também pode ter atributos extras, como peça capturada, tipo de castelo, etc. Mas essa informação também pode ser deduzida usando os quadrados Frome To.

Portanto, considerando o acima, podemos representar o movimento da seguinte forma

struct Move {
    char from; 
    char to;   
    char spMoveFlag;
    char promotedPiece;
};

No entanto, muitos mecanismos de xadrez, incluindo o meu, usam outro método que pode compactar o movimento em apenas 16pedaços. Leia mais sobre isso aqui .

Depois de saber o que é um movimento, podemos responder à próxima pergunta


  • Como converter ataques em bitboards em uma lista de movimentos?

Vamos considerar que temos um cavalo na casa d4 . Também temos uma função que retorna os ataques de um cavaleiro dado o quadrado.

. . . . . . . . 
. . . . . . . . 
. . 1 . 1 . . . 
. 1 . . . 1 . . 
. . . n . . . .   =  knightattacks(SQ_D4)
. 1 . . . 1 . . 
. . 1 . 1 . . . 
. . . . . . . . 

Então, vamos armazenar isso dentro de uma variável knightAttacks

uint64_t knightAttacks = getKnightAttacksBB(SQ_D4);

Se você observar com atenção, já temos 1 dos 4 atributos de que precisamos para representar o lance, que é o Fromquadrado - D4. Agora, tudo o que precisamos fazer é de alguma forma obter o Toquadrado para completar isso, já que um cavalo não pode realizar nenhum tipo de movimento especial.

Um método muito comum é estalar o bit menos significativo até que você knightAttacksfique sem nada, ou seja 0.

0000011100001000 
            ^
            Least significant bit (lsb)

Você pode seguir o link que forneci para saber como você pode fazer isso, ou há uma chance de que seu compilador já pode fornecer isso a você.

Você simplesmente precisa criar uma função que limpe o lsb de um bitboard e retorne seu índice. Vamos chamá-lo poplsb().

Ao todo, seu código pode ter a seguinte aparência

int from = SQ_D4;
uint16_t knightAttacks = getknightAttacks(from);

while (knightAttacks)  {
     int to = poplsb(knightAttacks);
     MyMoveList.Add( NewMove(from, to, 0, 0) ); // The last two 0's denote that there is no special move
}

Isso funciona porque cada vez que você estala o lsb, um bit é limpo até que o número seja == 0. É quando o loop para e você tem uma lista de movimentos perfeitamente boa. A mesma ideia se aplica a qualquer tipo de movimento que você criou usando Bitboards.