2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 const char *char_board
[64] = {
21 "a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1",
22 "a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2",
23 "a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3",
24 "a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4",
25 "a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5",
26 "a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6",
27 "a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7",
28 "a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8" };
30 const char char_pieces
[7] = {' ', 'P', 'N', 'B', 'R', 'Q', 'K'};
36 uint64_t isolated_mask
[8]; /* masks adjacent files */
37 uint64_t passer_mask
[2][64]; /* masks passed pawn way */
38 uint64_t pawn_moves
[2][64]; /* pawn capture moves */
39 uint64_t piece_moves
[7][64]; /* all piece moves */
40 uint64_t forward_ray
[2][64]; /* masks squares infront of a pawn */
41 uint64_t king_shield
[2][64]; /* example: for king on G1 - F2,g2,h2 */
43 int distance
[64][64]; /* distance from 2 squares */
45 /* bitboard mask for files */
46 const uint64_t file_bit
[8] = {
47 0x0101010101010101ULL
, 0x0202020202020202ULL
,
48 0x0404040404040404ULL
, 0x0808080808080808ULL
,
49 0x1010101010101010ULL
, 0x2020202020202020ULL
,
50 0x4040404040404040ULL
, 0x8080808080808080ULL
53 uint64_t complete
; /* complete bitboard for both sides */
54 int square64
[64]; /* regular board */
55 struct board_t brd
; /* board parameters */
56 struct game_history_t game_history
; /* takeback buffer */
58 uint64_t piece_boards
[2][7]; /* bitboard for each type of piece */
59 uint64_t side_boards
[2]; /* pieces for each side */
61 int castled
[2]; /* WHITE or BLACK castled */
63 int material_complete
[2]; /* sum of the material */
64 int material_pawns
[2]; /* ... for pawns */
65 int material_pieces
[2]; /* for pieces except pawns */
67 /* initial values according to Larry Kaufman */
68 int piece_value
[7] = { 0, 100, 325, 325, 500, 1000, 10000 };
70 int piece_count
[2][7]; /* count pieces of each type */
72 /* add piece to the board, update bitboard, zobrist and count */
74 add_piece(int square
, int piece
, int side
)
76 assert(square
>= 0 && square
<= 63);
77 assert(piece
>= PAWN
&& piece
<= KING
);
78 assert(side
== WHITE
|| side
== BLACK
);
79 assert(material_complete
[side
] == material_pieces
[side
] + \
80 material_pawns
[side
]);
82 square64
[square
] = piece
;
84 SET(piece_boards
[side
][piece
], square
); /* update bitboard */
85 SET(side_boards
[side
], square
); /* update bitboard */
86 SET(complete
, square
); /* update bitboard */
87 brd
.hash_key
^= hash_code
[side
][piece
][square
]; /* update zobrist key */
90 brd
.kings
[side
] = square
;
93 brd
.hash_pawn_key
^= hash_code
[side
][PAWN
][square
];
94 material_pawns
[side
] += piece_value
[PAWN
];
96 material_pieces
[side
] += piece_value
[piece
];
97 material_complete
[side
] += piece_value
[piece
];
99 piece_count
[side
][piece
]++;
103 board_is_legal(struct board_t
*b
)
111 for (i
= 0; i
< 64; i
++) {
113 /* if mailbox square isn't empty but bitboard's bit isn't set */
114 if (complete
& BIT(i
))
118 switch (square64
[i
]) {
120 if (((PAWNS(WHITE
) | PAWNS(BLACK
)) & BIT(i
)) == 0)
122 if (_FILE(square64
[i
]) == 0 || _FILE(square64
[i
]) == 7)
126 if (((KNIGHTS(WHITE
) | KNIGHTS(BLACK
)) & BIT(i
)) == 0)
130 if (((BISHOPS(WHITE
) | BISHOPS(BLACK
)) & BIT(i
)) == 0)
134 if (((ROOKS(WHITE
) | ROOKS(BLACK
)) & BIT(i
)) == 0)
138 if (((QUEENS(WHITE
) | QUEENS(BLACK
)) & BIT(i
)) == 0)
142 if (b
->kings
[WHITE
] == i
)
144 else if (b
->kings
[BLACK
] == i
)
153 /* bad king count or more than 32 pieces total */
154 if (wk
!= 1 || bk
!= 1 || n_pieces
> 32)
160 /* return board position in Forsyth-Edwards notation */
162 current_fen_position(char *buf
)
164 assert(board_is_legal(&brd
));
173 for (i
= 8; i
> 0; i
--) {
174 for (j
= 0; j
< 8; j
++) {
175 p
= square64
[(i
- 1) * 8 + j
];
180 /* square is not empty, but last square is. add empty
181 square count to result */
182 snprintf(tmp
, 2, "%d", empty
);
185 if (side_boards
[WHITE
] & BIT((i
- 1) * 8 + j
))
186 sprintf(tmp
, "%c", char_pieces
[p
]);
188 sprintf(tmp
, "%c", (char)(char_pieces
[p
] + 'a' - 'A'));
194 snprintf(tmp
, 2, "%d", empty
);
202 strcat(buf
, !brd
.wtm
? " w " : " b ");
204 if (!brd
.castle_mask
)
207 if (brd
.castle_mask
& WHITE_CASTLE_KINGSIDE
)
209 if (brd
.castle_mask
& WHITE_CASTLE_QUEENSIDE
)
211 if (brd
.castle_mask
& BLACK_CASTLE_KINGSIDE
)
213 if (brd
.castle_mask
& BLACK_CASTLE_QUEENSIDE
)
222 strcat(buf
, char_board
[brd
.ep
]);
227 /* remove piece from the board, update bitboard, zobrist and count */
229 remove_piece(int square
, int piece
, int side
)
231 assert(square
>= 0 && square
<= 63);
232 assert(piece
>= PAWN
&& piece
<= KING
);
233 assert(side
== WHITE
|| side
== BLACK
);
234 assert(material_complete
[side
] == material_pieces
[side
] + \
235 material_pawns
[side
]);
237 square64
[square
] = 0;
239 CLEAR(piece_boards
[side
][piece
], square
); /* update bitboard */
240 CLEAR(side_boards
[side
], square
); /* update bitboard */
241 CLEAR(complete
, square
); /* update bitboard */
242 brd
.hash_key
^= hash_code
[side
][piece
][square
]; /* update zobrist */
246 brd
.hash_pawn_key
^= hash_code
[side
][PAWN
][square
];
247 material_pawns
[side
] -= piece_value
[PAWN
];
249 material_pieces
[side
] -= piece_value
[piece
];
250 material_complete
[side
] -= piece_value
[piece
];
252 piece_count
[side
][piece
]--;
255 /* how many times this position was occured */
261 /* search for the same hash_key */
262 for (i
= 0, rep
= 0; i
< game_history
.count
- 1; i
++)
263 if (game_history
.board
[i
].hash_key
== brd
.hash_key
)
269 /* setup board using FEN notation */
271 setup_board(char *fen
)
280 if (sscanf(fen
, "%8[1-8pnbrqkPNBRQK]/%8[1-8pnbrqkPNBRQK]/" \
281 "%8[1-8pnbrqkPNBRQK]/%8[1-8pnbrqkPNBRQK]/%8[1-8pnbrqkPNBRQK]/" \
282 "%8[1-8pnbrqkPNBRQK]/%8[1-8pnbrqkPNBRQK]/%8[1-8pnbrqkPNBRQK] " \
283 "%1[bw] %[KQkq-] %[1-8a-h-]", ranks
[7], ranks
[6], ranks
[5], \
284 ranks
[4], ranks
[3], ranks
[2], ranks
[1], ranks
[0], side
, \
289 ZERO_MEM(game_history
);
290 ZERO_MEM(piece_boards
);
291 ZERO_MEM(side_boards
);
292 ZERO_MEM(material_pawns
);
293 ZERO_MEM(material_pieces
);
294 ZERO_MEM(material_complete
);
295 ZERO_MEM(piece_count
);
297 castled
[WHITE
] = castled
[BLACK
] = FALSE
;
299 for (i
= 0, j
= 0; i
< 8; i
++, j
= 0)
300 for (p
= 0; p
< strlen(ranks
[i
]); p
++) {
301 if (ranks
[i
][p
] < 'A') { /* empty squares */
302 for (m
= j
, k
= m
; k
< m
+ ranks
[i
][p
] - '0'; k
++, j
++)
303 square64
[i
* 8 + j
] = 0;
306 /* lowercase letter - BLACK, uppercase - WHITE */
307 color
= ranks
[i
][p
] > 'a'? BLACK
: WHITE
;
308 switch (ranks
[i
][p
] - ('a' - 'A') * color
) {
310 add_piece(i
* 8 + j
, BISHOP
, color
);
313 add_piece(i
* 8 + j
, KING
, color
);
316 add_piece(i
* 8 + j
, KNIGHT
, color
);
319 add_piece(i
* 8 + j
, PAWN
, color
);
322 add_piece(i
* 8 + j
, QUEEN
, color
);
325 add_piece(i
* 8 + j
, ROOK
, color
);
331 brd
.wtm
= (!strcmp(side
, "w")) ? WHITE
: BLACK
;
334 if (strncmp(ep
, "-", 1)) {
335 i
= (ep
[0] - 'a') + (ep
[1] - '1') * 8;
336 j
= i
+ (brd
.wtm
== WHITE
? 8 : -8);
337 /* polyglot compatibility hack */
338 if ((BIT(j
- 1) & PAWNS(brd
.wtm
)) || (BIT(j
+ 1) & PAWNS(brd
.wtm
)))
341 assert((brd
.ep
>= 16 && brd
.ep
<= 47) || brd
.ep
== -1);
345 if (strchr(castle
, 'K'))
346 brd
.castle_mask
|= WHITE_CASTLE_KINGSIDE
;
347 if (strchr(castle
, 'Q'))
348 brd
.castle_mask
|= WHITE_CASTLE_QUEENSIDE
;
349 if (strchr(castle
, 'k'))
350 brd
.castle_mask
|= BLACK_CASTLE_KINGSIDE
;
351 if (strchr(castle
, 'q'))
352 brd
.castle_mask
|= BLACK_CASTLE_QUEENSIDE
;
357 calc_zobrist(&brd
.hash_key
, &brd
.hash_pawn_key
);
359 assert(board_is_legal(&brd
));
360 set_engine_value(&e
.hopeless_moves
, 0);
365 /* update bitboards, normaly after making moves */
369 side_boards
[WHITE
] = PAWNS(WHITE
) | KNIGHTS(WHITE
) | BISHOPS(WHITE
) | \
370 ROOKS(WHITE
) | QUEENS(WHITE
) | KING(WHITE
);
371 side_boards
[BLACK
] = PAWNS(BLACK
) | KNIGHTS(BLACK
) | BISHOPS(BLACK
) | \
372 ROOKS(BLACK
) | QUEENS(BLACK
) | KING(BLACK
);
374 complete
= side_boards
[WHITE
] | side_boards
[BLACK
];
377 /* simple board representation for debugging */
383 for (rank
= 7; rank
>= 0; rank
--) {
384 for (file
= 0; file
< 8; file
++)
385 if (b
& (1ULL << (rank
* 8 + file
)))
394 /* simple bitboard representation for debugging */
399 char pieces
[] = {' ', 'P', 'N', 'B', 'R', 'Q', 'K'};
401 for (i
= 7; i
>= 0; i
--) {
402 printf("%d ", i
+ 1);
403 for (j
= 0; j
< 8; j
++) {
404 p
= square64
[i
* 8 + j
];
406 if (side_boards
[BLACK
] & BIT(i
* 8 + j
))
407 printf("%c ", (char)(pieces
[p
] + ('a' - 'A')));
409 printf("%c ", pieces
[p
]);
415 printf("\n a b c d e f g h\n");