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.
23 #define CreateMove(from, to, type, piece) (SET_FROM(from) | SET_TO(to) | SET_TYPE(type) | SET_PROMOTE(piece))
25 const int sign_8
[2] = {-8, 8};
26 const int sign_16
[2] = {-16, 16};
27 const int ks
[2] = {WHITE_CASTLE_KINGSIDE
, BLACK_CASTLE_KINGSIDE
};
28 const int qs
[2] = {WHITE_CASTLE_QUEENSIDE
, BLACK_CASTLE_QUEENSIDE
};
30 /* forward declarations of functions */
31 static int cap(int move
, int side
, int *see
);
32 static int gen_non_quiescent_moves(struct moves_t
*moves
);
35 static void gen_pawn_push_one(int side
, struct moves_t
*moves
);
36 static void gen_pawn_push_two(int side
, struct moves_t
*moves
);
38 /* piece moves including captures */
39 static void gen_knight(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
);
40 static void gen_bishop(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
);
41 static void gen_rook(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
);
42 static void gen_queen(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
);
43 static void gen_king(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
);
46 static void gen_castle(int side
, struct moves_t
*moves
);
49 static void gen_pawn_promote_minor(int side
, struct moves_t
*moves
);
50 static void gen_pawn_promote_queen(int side
, struct moves_t
*moves
);
52 /* pawn promotes and captures */
53 static void gen_pawn_cap_promote(int side
, struct moves_t
*moves
);
55 /* score for move ordering */
57 cap(int move
, int side
, int *see
)
63 return (*see
) + 10000000;
66 /* return only legal moves */
68 gen_legal_moves(struct moves_t
*moves
)
71 struct moves_t tmp_moves
;
74 gen_moves(&tmp_moves
);
76 for (i
= 0; i
< tmp_moves
.count
; i
++) {
77 if (make_move(tmp_moves
.move
[i
], TRUE
)) {
78 moves
->move
[moves
->count
] = tmp_moves
.move
[i
];
79 moves
->score
[moves
->count
] = tmp_moves
.score
[i
];
80 moves
->see
[moves
->count
] = tmp_moves
.see
[i
];
87 /* generate all pseudo legal moves */
89 gen_moves(struct moves_t
*moves
)
91 gen_quiescent_moves(moves
, side_boards
[1 ^ brd
.wtm
]);
92 gen_non_quiescent_moves(moves
);
97 /* generate captures and queen promotions */
99 gen_quiescent_moves(struct moves_t
*moves
, uint64_t target
)
103 gen_pawn_cap_promote(brd
.wtm
, moves
);
104 gen_knight(brd
.wtm
, TRUE
, target
, moves
);
105 gen_bishop(brd
.wtm
, TRUE
, target
, moves
);
106 gen_rook(brd
.wtm
, TRUE
, target
, moves
);
107 gen_queen(brd
.wtm
, TRUE
, target
, moves
);
108 gen_king(brd
.wtm
, TRUE
, target
, moves
);
109 gen_pawn_promote_queen(brd
.wtm
, moves
);
114 /* generate non-captures and non-queen promotions */
116 gen_non_quiescent_moves(struct moves_t
*moves
)
118 uint64_t target
= ~complete
;
120 gen_pawn_push_one(brd
.wtm
, moves
);
121 gen_pawn_push_two(brd
.wtm
, moves
);
122 gen_knight(brd
.wtm
, FALSE
, target
, moves
);
123 gen_bishop(brd
.wtm
, FALSE
, target
, moves
);
124 gen_rook(brd
.wtm
, FALSE
, target
, moves
);
125 gen_queen(brd
.wtm
, FALSE
, target
, moves
);
126 gen_pawn_promote_minor(brd
.wtm
, moves
);
127 gen_king(brd
.wtm
, FALSE
, target
, moves
);
128 gen_castle(brd
.wtm
, moves
);
134 gen_pawn_push_one(int side
, struct moves_t
*moves
)
139 /* remove pawns that can be promoted (there is another routine
141 move_mask
= side
? ((PAWNS(BLACK
) >> 8) & ~complete
& ~_RANK1
) : \
142 ((PAWNS(WHITE
) << 8) & ~complete
& ~_RANK8
);
145 to
= bit_scan_clear(&move_mask
);
146 moves
->move
[moves
->count
] = CreateMove(to
+ sign_8
[side
], to
, \
148 moves
->score
[moves
->count
] = history
[side
][PAWN
][(to
+ sign_8
[side
]) | \
155 gen_pawn_push_two(int side
, struct moves_t
*moves
)
160 /* mask pawns standing on their initial positions */
161 move_mask
= side
? (((PAWNS(BLACK
) & _RANK7
) >> 16) & \
162 (~complete
& (~complete
>> 8))) : (((PAWNS(WHITE
) & _RANK2
) << 16) & \
163 (~complete
& (~complete
<< 8)));
166 to
= bit_scan_clear(&move_mask
);
167 moves
->move
[moves
->count
] = CreateMove(to
+ sign_16
[side
], to
, \
169 moves
->score
[moves
->count
] = history
[side
][PAWN
][(to
+ sign_16
[side
]) | \
176 gen_knight(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
)
182 pieces
= KNIGHTS(side
);
185 from
= bit_scan_clear(&pieces
);
186 move_mask
= piece_moves
[KNIGHT
][from
] & mask
;
189 to
= bit_scan_clear(&move_mask
);
190 moves
->move
[moves
->count
] = CreateMove(from
, to
, \
191 capture
? TYPE_CAPTURE
: 0, 0);
192 moves
->score
[moves
->count
] = capture
? \
193 cap(moves
->move
[moves
->count
], side
, \
194 &moves
->see
[moves
->count
]) : history
[side
][KNIGHT
][from
| \
202 gen_bishop(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
)
208 pieces
= BISHOPS(side
);
211 from
= bit_scan_clear(&pieces
);
212 move_mask
= BISHOP_ATTACKS(from
, complete
) & mask
;
215 to
= bit_scan_clear(&move_mask
);
216 moves
->move
[moves
->count
] = CreateMove(from
, to
, \
217 capture
? TYPE_CAPTURE
: 0, 0);
218 moves
->score
[moves
->count
] = capture
? \
219 cap(moves
->move
[moves
->count
], side
, \
220 &moves
->see
[moves
->count
]) : history
[side
][BISHOP
][from
| \
228 gen_rook(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
)
234 pieces
= ROOKS(side
);
237 from
= bit_scan_clear(&pieces
);
238 move_mask
= ROOK_ATTACKS(from
, complete
) & mask
;
241 to
= bit_scan_clear(&move_mask
);
242 moves
->move
[moves
->count
] = CreateMove(from
, to
, \
243 capture
? TYPE_CAPTURE
: 0, 0);
244 moves
->score
[moves
->count
] = capture
? \
245 cap(moves
->move
[moves
->count
], side
, \
246 &moves
->see
[moves
->count
]) : history
[side
][ROOK
][from
| \
254 gen_queen(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
)
260 pieces
= QUEENS(side
);
263 from
= bit_scan_clear(&pieces
);
264 move_mask
= QUEEN_ATTACKS(from
, complete
) & mask
;
267 to
= bit_scan_clear(&move_mask
);
268 moves
->move
[moves
->count
] = CreateMove(from
, to
, \
269 capture
? TYPE_CAPTURE
: 0, 0);
270 moves
->score
[moves
->count
] = capture
? \
271 cap(moves
->move
[moves
->count
], side
, \
272 &moves
->see
[moves
->count
]) : history
[side
][QUEEN
][from
| \
280 gen_king(int side
, int capture
, uint64_t mask
, struct moves_t
*moves
)
285 from
= brd
.kings
[side
];
286 move_mask
= piece_moves
[KING
][from
] & mask
;
289 to
= bit_scan_clear(&move_mask
);
290 moves
->move
[moves
->count
] = CreateMove(from
, to
, \
291 capture
? TYPE_CAPTURE
: 0, 0);
292 moves
->score
[moves
->count
] = capture
? \
293 cap(moves
->move
[moves
->count
], side
, \
294 &moves
->see
[moves
->count
]) : history
[side
][KING
][from
| \
301 gen_castle(int side
, struct moves_t
*moves
)
303 if (!brd
.castle_mask
)
306 if ((brd
.castle_mask
& ks
[side
]) && !square64
[F1
+ side
* (F8
- F1
)] && \
307 !square64
[G1
+ side
* (G8
- G1
)]) {
308 moves
->move
[moves
->count
] = CreateMove(E1
+ side
* (E8
- E1
), \
309 G1
+ side
* (G8
- G1
), TYPE_CASTLE
, 0);
310 moves
->score
[moves
->count
] = history
[side
][KING
][(E1
+ side
* (E8
- E1
))\
311 | ((G1
+ side
* (G8
- G1
)) << 6)];
314 if ((brd
.castle_mask
& qs
[side
]) && !square64
[B1
+ side
* (B8
- B1
)] && \
315 !square64
[C1
+ side
* (C8
- C1
)] && !square64
[D1
+ side
* (D8
- D1
)]) {
316 moves
->move
[moves
->count
] = CreateMove(E1
+ side
* (E8
- E1
), \
317 C1
+ side
* (C8
- C1
), TYPE_CASTLE
, 0);
318 moves
->score
[moves
->count
] = history
[side
][KING
][(E1
+ side
* (E8
- E1
))\
319 | ((C1
+ side
* (C8
- C1
)) << 6)];
325 gen_pawn_promote_minor(int side
, struct moves_t
*moves
)
330 mask
= side
== WHITE
? (PAWNS(WHITE
) << 8) & ~complete
& _RANK8
: \
331 (PAWNS(BLACK
) >> 8) & ~complete
& _RANK1
;
333 to
= bit_scan_clear(&mask
);
335 for (piece
= KNIGHT
; piece
< QUEEN
; piece
++) {
336 moves
->move
[moves
->count
] = CreateMove(to
+ sign_8
[side
], to
, \
337 TYPE_PROMOTE
, piece
);
338 moves
->score
[moves
->count
] = cap(moves
->move
[moves
->count
], side
, &moves
->see
[moves
->count
]);
339 if (moves
->score
[moves
->count
] < 0)
340 moves
->score
[moves
->count
] = -piece_value
[PAWN
];
347 gen_pawn_promote_queen(int side
, struct moves_t
*moves
)
352 mask
= side
== WHITE
? (PAWNS(WHITE
) << 8) & ~complete
& _RANK8
:\
353 (PAWNS(BLACK
) >> 8) & ~complete
& _RANK1
;
355 to
= bit_scan_clear(&mask
);
357 moves
->move
[moves
->count
] = CreateMove(to
+ sign_8
[side
], to
, \
358 TYPE_PROMOTE
, QUEEN
);
359 moves
->score
[moves
->count
] = cap(moves
->move
[moves
->count
], side
, &moves
->see
[moves
->count
]);
360 if (moves
->score
[moves
->count
] < 0)
361 /* small bonus for queen promotions */
362 moves
->score
[moves
->count
] = -piece_value
[PAWN
] + 1;
368 gen_pawn_cap_promote(int side
, struct moves_t
*moves
)
376 enemies
= side_boards
[1 ^ side
] | (brd
.ep
== -1? 0 : BIT(brd
.ep
));
379 for (k
= 0, l
= 0; k
<= 2; k
+= 2, l
+= 7) {
380 mask
= ((PAWNS(WHITE
) & ~file_bit
[l
]) << (7 + k
)) & enemies
;
382 to
= bit_scan_clear(&mask
);
385 for (piece
= KNIGHT
; piece
< KING
; piece
++) {
386 moves
->move
[moves
->count
] = CreateMove(to
- 7 - k
, \
387 to
, TYPE_PROMOTE
| TYPE_CAPTURE
, piece
);
388 moves
->score
[moves
->count
] = cap(moves
->move
[moves
->count
], side
, \
389 &moves
->see
[moves
->count
]);
393 moves
->move
[moves
->count
] = CreateMove(to
- 7 - k
, to
, \
394 (to
!= brd
.ep
? TYPE_CAPTURE
: TYPE_ENPASSANT
), 0);
395 moves
->score
[moves
->count
] = \
396 cap(moves
->move
[moves
->count
], \
397 side
, &moves
->see
[moves
->count
]);
403 for (k
= 0, l
= 7; k
<= 2; k
+= 2, l
-= 7) {
404 mask
= ((PAWNS(BLACK
) & ~file_bit
[l
]) >> (7 + k
)) & enemies
;
406 to
= bit_scan_clear(&mask
);
409 for (piece
= KNIGHT
; piece
< KING
; piece
++) {
410 moves
->move
[moves
->count
] = CreateMove(to
+ 7 + k
, \
411 to
, TYPE_PROMOTE
| TYPE_CAPTURE
, piece
);
412 moves
->score
[moves
->count
] = cap(moves
->move
[moves
->count
], side
, \
413 &moves
->see
[moves
->count
]);
417 moves
->move
[moves
->count
] = CreateMove(to
+ 7 + k
, to
, \
418 (to
!= brd
.ep
? TYPE_CAPTURE
: TYPE_ENPASSANT
), 0);
419 moves
->score
[moves
->count
] = \
420 cap(moves
->move
[moves
->count
], \
421 side
, &moves
->see
[moves
->count
]);