diff --git a/ArduChess.ino b/ArduChess.ino index 335e21e..75ccde2 100644 --- a/ArduChess.ino +++ b/ArduChess.ino @@ -12,6 +12,7 @@ void setup() { Board::init(); Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); + //debug_check(); //perft_test(); //bench(); } diff --git a/Tasks.h b/Tasks.h index 7e1ac07..441bbd3 100644 --- a/Tasks.h +++ b/Tasks.h @@ -31,27 +31,39 @@ unsigned long pseudo_perft(byte depth) { return move_count; } -unsigned long divide(byte depth) { - // only checks pseudolegality - // but, it should work overall +unsigned long perft(byte depth) { if(depth == 0) return 1; - if(depth == 3) blink(); + if(depth == 2) blink(); unsigned long move_count = 0; Movegen gen; Move m; - while (true) { - m = gen.next_move(); + while((m = gen.next_move()).sq_to != 255) { + if(make_safe(m)) { + move_count += perft(depth-1); + Board::unmake(); + } + } + return move_count; +} + +unsigned long divide(byte depth) { + // only checks pseudolegality + // but, it should work overall + if(depth == 0) return 1; + if(depth == 2) blink(); + unsigned long move_count = 0; + Movegen gen; + Move m; + + while((m = gen.next_move()).sq_to != 255){ print_move(m); Serial.print(F(" ")); - if(m.sq_to != 255) { - Board::make(m); - int count = pseudo_perft(depth-1); + if(make_safe(m)) { + unsigned long count = perft(depth-1); Serial.println(count); move_count += count; Board::unmake(); - } else { - break; } } return move_count; @@ -114,7 +126,20 @@ void debug_check() { Board::make({0x05, 0x41, P_EMPTY}); Board::print(); - Serial.println(Threat::is_check()); + Serial.print(Threat::is_check()); + Serial.println(Threat::illegal()); + + divide(1); + + Board::make({0x60, 0x40, P_EMPTY}); + Board::print(); + Serial.print(Threat::is_check()); + Serial.println(Threat::illegal()); + + Board::unmake(); + Board::unmake(); + Board::unmake(); + Board::unmake(); } void debug_ep() { diff --git a/Threat.h b/Threat.h index f5c39fc..68939b7 100644 --- a/Threat.h +++ b/Threat.h @@ -5,7 +5,6 @@ namespace Threat { byte can_capture(byte square) { // TODO make this more efficient byte t = 0; - Board::swap_side(); Movegen gen = Movegen(); Move m; while((m = gen.next_move()).sq_to != 255) { @@ -13,7 +12,6 @@ namespace Threat { t++; } } - Board::swap_side(); return t; } @@ -39,4 +37,23 @@ namespace Threat { } +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 \ No newline at end of file diff --git a/Types.h b/Types.h index ee7acb6..d6a493d 100644 --- a/Types.h +++ b/Types.h @@ -61,7 +61,7 @@ void print_move(Move m) { } print_sq(m.sq_from); print_sq(m.sq_to); - byte pc = m.pc_prom & 0x7; + Piece pc = (Piece)(m.pc_prom & 0x7); if(pc != 0) Serial.print(piece_to_char(pc)); }