ArduChess/Tasks.h

241 lines
5.1 KiB
C

#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