1from array import array
2
3
4# setBit returns a bitboard with the ith bit set
5def setBit(bitboard, i):
6    return bitboard | bitPosArray[i]
7
8
9bitPosArray = [2**(63 - i) for i in range(64)]
10
11
12# clearBit returns the bitboard with the ith bit unset
13def clearBit(bitboard, i):
14    return bitboard & notBitPosArray[i]
15
16
17notBitPosArray = [~2**(63 - i) for i in range(64)]
18
19
20# firstBit returns the bit closest to 0 (A4) that is set in the board
21def firstBit(bitboard):
22    """ Returns the index of the first non-zero bit from left """
23    if (bitboard >> 48):
24        return lzArray[bitboard >> 48]
25    if (bitboard >> 32):
26        return lzArray[bitboard >> 32] + 16
27    if (bitboard >> 16):
28        return lzArray[bitboard >> 16] + 32
29    return lzArray[bitboard] + 48
30
31
32# The bitCount array returns the leading non-zero bit in the 16 bit
33# input argument.
34
35lzArray = array('B', [0] * 65536)
36
37s = n = 1
38for i in range(16):
39    for j in range(s, s + n):
40        lzArray[j] = 16 - 1 - i
41    s += n
42    n += n
43
44
45# lastBit returns the bit closest to 63 (H8) that is set in the board
46def lastBit(bitboard):
47    return lsb[bitboard & -bitboard]
48
49
50lsb = {}
51for i in range(64):
52    lsb[2**i] = 63 - i
53
54
55# iterBits yields, or returns a list of, the positions of all set bits in a
56# bitboard. There is no guarantee of the order.
57def iterBits(bitboard):
58    while bitboard:
59        bit = bitboard & -bitboard
60        yield lsb[bit]
61        bitboard -= bit
62
63
64# toString returns a representation of the bitboard for debugging
65def toString(bitboard):
66    s = []
67    last = -1
68
69    while bitboard:
70        cord = firstBit(bitboard)
71        bitboard = clearBit(bitboard, cord)
72        for c in range(cord - last - 1):
73            s.append(" -")
74        s.append(" #")
75        last = cord
76    while len(s) < 64:
77        s.append(" -")
78
79    s2 = ""
80    for i in range(64, 0, -8):
81        a = s[i - 8:i]
82        s2 += "".join(a) + "\n"
83    return s2
84