#ifndef __TASKS_H_INC #define __TASKS_H_INC #include "Types.h" #include "Movegen.h" #include "Threat.h" unsigned long pseudo_perft(byte depth) { // only checks pseudolegality // but, it should work overall if(depth == 0) return 1; if(depth == 3) blink(); unsigned long move_count = 0; Movegen gen; Move m; while (true) { m = gen.next_move(); if(m.sq_to != 255) { Board::make(m); if(!Threat::illegal()) { move_count += pseudo_perft(depth-1); } else { //Board::print(); } Board::unmake(); } else { break; } } return move_count; } unsigned long perft(byte depth) { 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) { 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(make_safe(m)) { unsigned long count = perft(depth-1); Serial.println(count); move_count += count; Board::unmake(); } } return move_count; } void perft_test() { for(byte i = 0; i < 5; i++) { Serial.print(F("Perft ")); Serial.print(i); Serial.print(F(": ")); Serial.println(pseudo_perft(i)); } } void debug_movegen() { Board::make({0x14, 0x34, P_EMPTY}); Movegen gen = Movegen(); Move m; do { DEBUG("start movegen"); m = gen.next_move(); Serial.print(F("FROM ")); Serial.print(m.sq_from, HEX); Serial.print(F(" TO ")); Serial.print(m.sq_to, HEX); Serial.print(F(" PROMOTE ")); Serial.println(m.pc_prom); if(m.sq_from != 255) { DEBUG("make"); Board::make(m); Board::print(); DEBUG("unmake"); Board::unmake(); DEBUG("unmake done"); } } while (m.sq_from != 255); } void debug_castle() { Board::print(); Board::make({0x06, 0x25, P_EMPTY}); Board::print(); Board::make({0x76, 0x55, P_EMPTY}); Board::print(); Board::make({0x16, 0x26, P_EMPTY}); Board::print(); Board::make({0x63, 0x43, P_EMPTY}); Board::print(); Board::make({0x05, 0x16, P_EMPTY}); Board::print(); Board::make({0x62, 0x42, P_EMPTY}); Board::print(); Board::make({0x04, 0x06, P_EMPTY}); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); } void debug_check() { Board::make({0x14, 0x34, P_EMPTY}); Board::make({0x63, 0x43, P_EMPTY}); Board::make({0x05, 0x41, P_EMPTY}); Board::print(); 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() { Board::print(); Board::make({0x14, 0x34, P_EMPTY}); Board::print(); Board::make({0x64, 0x54, P_EMPTY}); Board::print(); Board::make({0x34, 0x44, P_EMPTY}); Board::print(); Board::make({0x63, 0x43, P_EMPTY}); Board::print(); Board::make({0x44, 0x53, P_EMPTY}); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); Board::unmake(); Board::print(); } void bench() { // TODO reduce code size of this (by moving repeated constants from here to PROGMEM and loops?) unsigned long startTime; unsigned long elapsed; #ifdef _ACF_BENCH_BIG startTime = micros(); Board::make({0x14, 0x34, P_EMPTY}); Board::make({0x64, 0x54, P_EMPTY}); Board::make({0x34, 0x44, P_EMPTY}); Board::make({0x63, 0x43, P_EMPTY}); Board::make({0x44, 0x53, P_EMPTY}); Board::unmake(); Board::unmake(); Board::unmake(); Board::unmake(); Board::unmake(); Board::make({0x06, 0x25, P_EMPTY}); Board::make({0x76, 0x55, P_EMPTY}); Board::make({0x16, 0x26, P_EMPTY}); Board::make({0x63, 0x43, P_EMPTY}); Board::make({0x05, 0x16, P_EMPTY}); Board::make({0x62, 0x42, P_EMPTY}); Board::make({0x04, 0x06, P_EMPTY}); Board::unmake(); Board::unmake(); Board::unmake(); Board::unmake(); Board::unmake(); Board::unmake(); Board::unmake(); elapsed = micros() - startTime; Serial.print(elapsed); Serial.println(F(" microseconds for make/unmake")); #endif for(int i = 1; i <= 4; i++) { startTime = millis(); pseudo_perft(i); elapsed = millis() - startTime; Serial.print(elapsed); Serial.print(F(" milliseconds for pseudo_perft(")); Serial.print(i); Serial.println(')'); } Movegen gen; Move move[20]; startTime = micros(); for(int i = 0; i < 20; i++) { move[i] = gen.next_move(); } elapsed = micros() - startTime; Serial.print(elapsed); Serial.println(F(" microseconds for movegen(init_pos)")); startTime = micros(); for(int i = 0; i < 20; i++) { Board::make(move[i]); Board::unmake(); } elapsed = micros() - startTime; Serial.print(elapsed); Serial.println(F(" microseconds for make/unmake(init_pos)")); } #endif