~macaptain/lkdo-chess

ref: 4a145c47f8fbfa347527f38f5105792fa96cc9e7 lkdo-chess/src/attack.zig -rw-r--r-- 2.7 KiB
4a145c47Michael Captain Add king attacks with tests 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
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)];
}