#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