aboutsummaryrefslogtreecommitdiff
path: root/src/bitboard.c
blob: 96f220d862667b3dbd7f092664a5a93855ea72f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <stdio.h>
#include "bitboard.h"

/* Print bitboard on screen in the same way squares appear in memory
 * (i.e the board is actually flipped along X) */
void printBitboard(Bitboard bb) {
  for (U64 index = 0; index < 64; index++) {
    printf("%c", (bb >> index) & 1 ? '1' : '.');
    if ((index + 1) % 8 == 0) printf("\n");
  }
  printf("\n\n");
}

/* Return bitboard cardinality, aka number of elements in the set */
inline int popCount(Bitboard bb){
  if (bb == 0) return 0;
  return popCount(bb >> 1) + (bb & 1);
}

/* Return Bitboard with only Least Single Bit */
inline Bitboard ls1b(Bitboard bb) {
  return bb & -bb;
}

/* Log base 2 (aka Trailing Zero Count)
 * Only works for SINGLE Bitboards
 * Useful for calculating bit-index of LS1B */
inline int bitscan(Bitboard bb) {
  return popCount(ls1b(bb) - 1);
}

/* Bitscan forward with LS1B reset */
inline int bitscanAndReset(Bitboard* bb) {
  int idx = bitscan(*bb);
  *bb &= *bb - 1;
  return idx;
}


/* These 4 blindly copied from chessprogramming.org TODO: rewrite */
U64 rankMask(enumSquare sq) {
  return  C64(0xff) << (sq & 56);
}

U64 fileMask(enumSquare sq) {
  return C64(0x0101010101010101) << (sq & 7);
}

U64 diagonalMask(enumSquare sq) {
   const U64 maindia = C64(0x8040201008040201);
   int diag =8*(sq & 7) - (sq & 56);
   int nort = -diag & ( diag >> 31);
   int sout =  diag & (-diag >> 31);
   return (maindia >> sout) << nort;
}

U64 antiDiagMask(enumSquare sq) {
   const U64 maindia = C64(0x0102040810204080);
   int diag =56- 8*(sq&7) - (sq&56);
   int nort = -diag & ( diag >> 31);
   int sout =  diag & (-diag >> 31);
   return (maindia >> sout) << nort;
}