summaryrefslogtreecommitdiff
path: root/src/engine/moves/knight.c
blob: e7615f097a65046ae2b994e81d79fc832e5d361b (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
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
#include "moves.h"

bitboard_t knight_moves[64] = {
  132096ULL,
  329728ULL,
  659712ULL,
  659712ULL << 1,
  659712ULL << 2,
  659712ULL << 3,
  10489856ULL,
  4202496ULL,

  33816580ULL,
  84410376ULL,
  168886289ULL,
  168886289ULL << 1,
  168886289ULL << 2,
  168886289ULL << 3,
  2685403152ULL,
  1075839008ULL,

  8657044482ULL,
  21609056261ULL,
  43234889994ULL,
  43234889994ULL << 1,
  43234889994ULL << 2,
  43234889994ULL << 3,
  687463207072ULL,
  275414786112ULL,

  8657044482ULL << 8,
  21609056261ULL << 8,
  43234889994ULL << 8,
  43234889994ULL << (8 + 1),
  43234889994ULL << (8 + 2),
  43234889994ULL << (8 + 3),
  687463207072ULL << 8,
  275414786112ULL << 8,
  
  8657044482ULL << 16,
  21609056261ULL << 16,
  43234889994ULL << 16,
  43234889994ULL << (16 + 1),
  43234889994ULL << (16 + 2),
  43234889994ULL << (16 + 3),
  687463207072ULL << 16,
  275414786112ULL << 16,

  8657044482ULL << 24,
  21609056261ULL << 24,
  43234889994ULL << 24,
  43234889994ULL << (24 + 1),
  43234889994ULL << (24 + 2),
  43234889994ULL << (24 + 3),
  687463207072ULL << 24,
  275414786112ULL << 24,

  288234782788157440ULL,
  576469569871282176ULL,
  1224997833292120064ULL,
  1224997833292120064ULL << 1,
  1224997833292120064ULL << 2,
  1224997833292120064ULL << 3,
  1152939783987658752ULL,
  2305878468463689728ULL,

  1128098930098176ULL,
  2257297371824128ULL,
  4796069720358912ULL,
  4796069720358912ULL >> 1,
  4796069720358912ULL >> 2,
  4796069720358912ULL >> 3,
  4679521487814656ULL,
  9077567998918656ULL,
};

void get_knight_moves(moves_t* moves, position_t position) {
  assert_valid_position(position);

  bitboard_t friendly_knights;
  bitboard_t friendly_pieces;
  bitboard_t enemy_pieces;
  if (position.turn == WHITE_TURN) {
    friendly_pieces = whites(position);
    enemy_pieces = blacks(position);
    friendly_knights = position.bitboards[WHITE_KNIGHT];
  } else {
    friendly_pieces = blacks(position);
    enemy_pieces = whites(position);
    friendly_knights = position.bitboards[BLACK_KNIGHT];
  }

  while (friendly_knights) {
    int from = __builtin_ctzll(friendly_knights);
    friendly_knights &= friendly_knights - 1;
    bitboard_t ATTACK_MASK = knight_moves[from];
    ATTACK_MASK &= ~friendly_pieces;
    while (ATTACK_MASK) {
      int to = __builtin_ctzll(ATTACK_MASK);
      ATTACK_MASK &= ATTACK_MASK - 1;
      int capture = 0;
      add_move(
        moves,
        from,
        to,
        .flags = ((enemy_pieces >> to) & 1) ? MOVE_CAPTURE : 0,
      );
    }
  }
}