- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmovepick.cpp
More file actions
Latest commit
139 lines (113 loc) · 4.06 KB
/
Copy pathmovepick.cpp
File metadata and controls
139 lines (113 loc) · 4.06 KB
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
#include"movepick.h"
#include"eval.h"
#include"search.h"
#include<algorithm>
usingnamespacechess;
using engine::eval::piece_value_mg;
namespaceengine::movepick {
static Bitboard att(PieceType pt, Square sq, Bitboard occ) {
switch (pt) {
caseBISHOP:
returnattacks::bishop(sq, occ);
caseROOK:
returnattacks::rook(sq, occ);
caseQUEEN:
returnattacks::queen(sq, occ);
default:
return0;
}
}
inline Square least_valuable_attacker(const Position &board, Bitboard attackers, Color side) {
Bitboard bb;
bb = attackers & board.pieces(PAWN, side);
if (bb)
returnSquare(pop_lsb(bb));
bb = attackers & board.pieces(KNIGHT, side);
if (bb)
returnSquare(pop_lsb(bb));
bb = attackers & board.pieces(BISHOP, side);
if (bb)
returnSquare(pop_lsb(bb));
bb = attackers & board.pieces(ROOK, side);
if (bb)
returnSquare(pop_lsb(bb));
bb = attackers & board.pieces(QUEEN, side);
if (bb)
returnSquare(pop_lsb(bb));
bb = attackers & board.pieces(KING, side);
if (bb)
returnSquare(pop_lsb(bb));
returnSQ_NONE;
}
Value see(Position &board, Move move) {
Square from = move.from();
Square to = move.to();
PieceType captured = move.type_of() == EN_PASSANT ? PAWN : board.at<PieceType>(to);
if (captured == NO_PIECE_TYPE)
return0;
Bitboard occ = board.occ();
occ ^= 1ULL << from;
if (move.type_of() == EN_PASSANT)
occ ^= 1ULL << Square(int(to) + (board.side_to_move() == WHITE ? -8 : 8));
Bitboard attackers = board.attackers(WHITE, to, occ) | board.attackers(BLACK, to, occ);
Value gain[32];
PieceType attacker = board.at<PieceType>(move.from());
gain[0] = piece_value_mg(captured);
Color stm = ~board.side_to_move();
int d = 0;
while (++d < 32) {
// Charge the piece that just captured.
gain[d] = piece_value_mg(attacker) - gain[d - 1];
if (gain[d] < 0)
break;
Bitboard stmAttackers = attackers & board.occ(stm);
if (!stmAttackers)
break;
Square sq = least_valuable_attacker(board, stmAttackers, stm);
attacker = board.at<PieceType>(sq);
occ ^= 1ULL << sq;
// Recompute x-rays after EVERY removal.
attackers = board.attackers(WHITE, to, occ) | board.attackers(BLACK, to, occ);
stm = ~stm;
}
while (--d)
gain[d - 1] = -std::max(-gain[d - 1], gain[d]);
return gain[0];
}
voidorderMoves(Position &board, Movelist &moves, Move ttMove, int ply, const engine::search::Session &session, Move prevMove) {
Value scores[300];
size_t n = moves.size();
for (size_t i = 0; i < n; ++i) {
Move move = moves[i];
if (move == ttMove)
scores[i] = 10000;
elseif (board.isCapture(move)) {
Value s = see(board, move);
Value capturedVal =
move.type_of() == EN_PASSANT ? piece_value_mg(PAWN) : piece_value_mg(board.at<PieceType>(move.to()));
Value attackerVal = piece_value_mg(board.at<PieceType>(move.from()));
scores[i] = (s >= -50 ? 9000 : 4000) + std::max(s, Value(-50)) + (capturedVal * 10 - attackerVal) / 100;
} elseif (move == session.killerMoves[ply][0])
scores[i] = 8500;
elseif (move == session.killerMoves[ply][1])
scores[i] = 8000;
elseif (prevMove.is_ok() && move == session.counterMoves[prevMove.from_to()])
scores[i] = 7500;
elseif (board.givesCheck(move) != CheckType::NO_CHECK)
scores[i] = 7000;
else
scores[i] = session.historyHeuristic[move.from()][move.to()];
}
size_t limit = std::min(n, size_t(12));
for (size_t i = 0; i + 1 < limit; ++i) {
size_t best = i;
for (size_t j = i + 1; j < n; ++j)
if (scores[j] > scores[best])
best = j;
if (best != i) {
std::swap(moves[i], moves[best]);
std::swap(scores[i], scores[best]);
}
}
}
} // namespace engine::movepick