59 lines
1.2 KiB
C++
59 lines
1.2 KiB
C++
#ifndef __THREAT_H_INC
|
|
#define __THREAT_H_INC
|
|
|
|
namespace Threat {
|
|
byte can_capture(byte square) {
|
|
// TODO make this more efficient
|
|
byte t = 0;
|
|
Movegen gen = Movegen();
|
|
Move m;
|
|
while((m = gen.next_move()).sq_to != 255) {
|
|
if(m.sq_to == square) {
|
|
t++;
|
|
}
|
|
}
|
|
return t;
|
|
}
|
|
|
|
byte threats(byte square) {
|
|
byte t = 0;
|
|
Board::swap_side();
|
|
t = can_capture(square);
|
|
Board::swap_side();
|
|
return t;
|
|
}
|
|
|
|
bool is_check() {
|
|
byte king_ptr = Board::field[PTR_W_KING | Board::black_moving()];
|
|
return (threats(king_ptr)) > 0;
|
|
}
|
|
|
|
bool illegal() {
|
|
// if the enemy king can be captured, move they did is illegal.
|
|
byte king_ptr = Board::field[PTR_W_KING | !Board::black_moving()];
|
|
return (can_capture(king_ptr)) > 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool make_safe(Move m) {
|
|
byte sq_diff = m.sq_to - m.sq_from;
|
|
if(m.sq_from == Board::field[PTR_W_KING | Board::black_moving()] &&
|
|
abs(sq_diff) == 2
|
|
) {
|
|
// we are castling, so check if we are threatened in the square the king moves through
|
|
byte sq = m.sq_from + (sq_diff/2);
|
|
if(Threat::is_check() || Threat::threats(sq) > 0) {
|
|
return false; // castle blocked; return failure
|
|
}
|
|
}
|
|
Board::make(m);
|
|
if(Threat::illegal()) {
|
|
Board::unmake();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#endif |