-
Notifications
You must be signed in to change notification settings - Fork 0
/
pieces.cpp
128 lines (114 loc) · 3.2 KB
/
pieces.cpp
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
#include "pieces.h"
map<char, int> PieceMap;
map<int, char> PieceIndexMap;
/// This function uses the existing knowledge of a pieces type, destination, and
/// maybe part of the source and tries to exactly reconstruct the source
/// considering it is a valid move.
/// If the source is incomplete, it presumes the column and/or line to be 64.
/// The equivalent of INDEX_TO_COORDS will return <72, 0> if we don't know
/// anything about the source.
/// When checking for failure please use index >= 64 !
bool Move::FindCoordinates(Board &board)
{
if (source < 64) return true; // we already know the source
ull occ = board.GetOccupancy();
int type = PieceMap[piece] + 7*player;
ull attack = 0;
if (piece == 'P') {
// move one square
if (!(flags & CAPTURE)) {
if (player) {
SET_BIT(attack, destination+8);
}
else {
SET_BIT(attack, destination-8);
}
// move two squares
if (player) {
if (!IS_SET_BIT(board.bb[6] | board.bb[13], destination+8))
if (31 < destination && destination < 40)
SET_BIT(attack, destination+16);
}
else {
if (!IS_SET_BIT(board.bb[6] | board.bb[13], destination-8))
if (23 < destination && destination < 32)
SET_BIT(attack, destination-16);
}
}
// capture
if (flags & CAPTURE || flags & ENPASS) {
if (player) {
if (destination+7 < 64) SET_BIT(attack, destination+7);
if (destination+9 < 64) SET_BIT(attack, destination+9);
}
else {
if (destination-7 >= 0) SET_BIT(attack, destination-7);
if (destination-9 >= 0) SET_BIT(attack, destination-9);
}
}
}
else if (piece == 'N') {
attack = Nmagic(destination);
}
else if (piece == 'B') {
attack = Bmagic(destination, occ);
}
else if (piece == 'R') {
attack = Rmagic(destination, occ);
}
else if (piece == 'Q') {
attack = Qmagic(destination, occ);
}
else if (piece == 'K') {
attack = Kmagic(destination);
}
attack &= board.bb[type];
// NOTICE: the conditions work, no need to recheck :)
if (source/8 < 64) {
// we know the line
attack &= lbb[(source-64)/8];
}
if (source/8 < 8 || (64 <= source/8 && source/8 < 72)) {
// we know the column
attack &= cbb[source%8];
}
int valid = 0;
ull osrc;
while (attack) {
source = LSBi(attack);
Board brd = board;
brd.MakeMove(*this);
if (!brd.VerifyChess(brd.bb[5 + 7*brd.player], !brd.player)) {
valid++;
osrc = source;
}
}
if (valid != 1)
return false;
else
source = osrc;
return true;
}
/// Function that initialises pieces information.
/// Initialisation of a piece's character representation hasing takes place here
void initPieces()
{
PieceMap['P'] = PAWN_W;
PieceMap['N'] = KNIGHT_W;
PieceMap['B'] = BISHOP_W;
PieceMap['R'] = ROOK_W;
PieceMap['Q'] = QUEEN_W;
PieceMap['K'] = KING_W;
PieceIndexMap[PAWN_W] = 'P';
PieceIndexMap[KNIGHT_W] = 'N';
PieceIndexMap[BISHOP_W] = 'B';
PieceIndexMap[ROOK_W] = 'R';
PieceIndexMap[QUEEN_W] = 'Q';
PieceIndexMap[KING_W] = 'K';
PieceIndexMap[PAWN_B] = 'p';
PieceIndexMap[KNIGHT_B] = 'n';
PieceIndexMap[BISHOP_B] = 'b';
PieceIndexMap[ROOK_B] = 'r';
PieceIndexMap[QUEEN_B] = 'q';
PieceIndexMap[KING_B] = 'k';
}