~macaptain/lkdo-chess

ref: dd7525ce7009b586079db00596ea4c67dc8d45da lkdo-chess/src/attack.zig -rw-r--r-- 3.9 KiB
dd7525ceMichael Captain Add bishop relative occupancy mask 9 months ago
                                                                                
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
pub usingnamespace @import("board.zig");

const mask_not_a = 0xfefefefefefefefe;
const mask_not_ab = 0xfcfcfcfcfcfcfcfc;
const mask_not_h = 0x7f7f7f7f7f7f7f7f;
const mask_not_gh = 0x3f3f3f3f3f3f3f3f;

const pawn_attacks = initPawnAttacks();

fn initPawnAttacks() [2][64]u64 {
    comptime {
        var sq: u8 = 0;
        var attacks: [2][64]u64 = undefined;
        while (sq < 64) : (sq += 1) {
            attacks[0][sq] = maskPawnAttacks(Side.White, @intToEnum(Square, sq));
        }
        sq = 0;
        while (sq < 64) : (sq += 1) {
            attacks[1][sq] = maskPawnAttacks(Side.Black, @intToEnum(Square, sq));
        }
        return attacks;
    }
}

fn maskPawnAttacks(side: Side, pawn: Square) u64 {
    const bitboard = bitboardFromSquare(pawn);
    return switch (side) {
        Side.White => (bitboard >> 9 & mask_not_h) | (bitboard >> 7 & mask_not_a),
        Side.Black => (bitboard << 9 & mask_not_a) | (bitboard << 7 & mask_not_h),
    };
}

pub fn pawnAttacks(side: Side, pawn: Square) u64 {
    return pawn_attacks[@enumToInt(side)][@enumToInt(pawn)];
}

const knight_attacks = initKnightAttacks();

fn initKnightAttacks() [64]u64 {
    comptime {
        var sq: u8 = 0;
        var attacks: [64]u64 = undefined;
        while (sq < 64) : (sq += 1) {
            attacks[sq] = maskKnightAttacks(@intToEnum(Square, sq));
        }
        return attacks;
    }
}

fn maskKnightAttacks(knight: Square) u64 {
    const bitboard = bitboardFromSquare(knight);
    // attacks considered clockwise
    var attacks = bitboard >> 15 & mask_not_a;
    attacks |= bitboard >> 6 & mask_not_ab;
    attacks |= bitboard << 10 & mask_not_ab;
    attacks |= bitboard << 17 & mask_not_a;
    attacks |= bitboard << 15 & mask_not_h;
    attacks |= bitboard << 6 & mask_not_gh;
    attacks |= bitboard >> 10 & mask_not_gh;
    attacks |= bitboard >> 17 & mask_not_h;
    return attacks;
}

pub fn knightAttacks(knight: Square) u64 {
    return knight_attacks[@enumToInt(knight)];
}

const king_attacks = initKingAttacks();

fn initKingAttacks() [64]u64 {
    comptime {
        var sq: u8 = 0;
        var attacks: [64]u64 = undefined;
        while (sq < 64) : (sq += 1) {
            attacks[sq] = maskKingAttacks(@intToEnum(Square, sq));
        }
        return attacks;
    }
}

fn maskKingAttacks(king: Square) u64 {
    const bitboard = bitboardFromSquare(king);
    var attacks = bitboard >> 8;
    attacks |= bitboard >> 7 & mask_not_a;
    attacks |= bitboard << 1 & mask_not_a;
    attacks |= bitboard << 9 & mask_not_a;
    attacks |= bitboard << 8;
    attacks |= bitboard << 7 & mask_not_h;
    attacks |= bitboard >> 1 & mask_not_h;
    attacks |= bitboard >> 9 & mask_not_h;
    return attacks;
}

pub fn kingAttacks(king: Square) u64 {
    return king_attacks[@enumToInt(king)];
}

/// Given a square occupied by a bishop, return a bitboard of relevant
/// occupancy bits.  i.e. squares on which, if other pieces are placed, the
/// line of attack is blocked and the attack bitboard is altered.
pub fn maskBishopOccupancy(bishop: Square) u64 {
    const sq = @enumToInt(bishop);
    const rank = sq / 8;
    const file = sq % 8;
    var bitboard: u64 = 0;
    var r: u6 = rank + 1;
    var f: u6 = file + 1;
    while (r >= 1 and r <= 6 and f >= 1 and f <= 6) : ({
        r += 1;
        f += 1;
    }) {
        bitboard |= @as(u64, 1) << (8 * r + f);
    }
    r = rank - 1;
    f = file + 1;
    while (r >= 1 and r <= 6 and f >= 1 and f <= 6) : ({
        r -= 1;
        f += 1;
    }) {
        bitboard |= @as(u64, 1) << (8 * r + f);
    }
    r = rank + 1;
    f = file - 1;
    while (r >= 1 and r <= 6 and f >= 1 and f <= 6) : ({
        r += 1;
        f -= 1;
    }) {
        bitboard |= @as(u64, 1) << (8 * r + f);
    }
    r = rank - 1;
    f = file - 1;
    while (r >= 1 and r <= 6 and f >= 1 and f <= 6) : ({
        r -= 1;
        f -= 1;
    }) {
        bitboard |= @as(u64, 1) << (8 * r + f);
    }

    return bitboard;
}