Implement eg threat detection
This commit is contained in:
parent
5507db23dd
commit
49aa6ec54b
21
Board.h
21
Board.h
|
|
@ -51,7 +51,9 @@ namespace Board {
|
||||||
*zob = 0xDEADBEEF;
|
*zob = 0xDEADBEEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void swap_side() {
|
||||||
|
field[PTR_SIDE_AND_CASTLERIGHT] ^= 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
struct Unmove {
|
struct Unmove {
|
||||||
byte sq_from; // 0b(1kingside_castle?)(3rank)(1queenside_castle?)(3file)
|
byte sq_from; // 0b(1kingside_castle?)(3rank)(1queenside_castle?)(3file)
|
||||||
|
|
@ -151,7 +153,10 @@ namespace Board {
|
||||||
|
|
||||||
// TODO test the castling code more extensively
|
// TODO test the castling code more extensively
|
||||||
// Handle castling
|
// Handle castling
|
||||||
if(piece_type == W_KING && sq_diff_abs == 2) {
|
if(piece_type == W_KING) {
|
||||||
|
// Update the king position
|
||||||
|
field[PTR_W_KING | Board::black_moving()] = m.sq_to;
|
||||||
|
if(sq_diff_abs == 2) {
|
||||||
// We are castling! After all, a king cannot move
|
// We are castling! After all, a king cannot move
|
||||||
// more than one position except when castling.
|
// more than one position except when castling.
|
||||||
// Since we don't care about legality; just do it
|
// Since we don't care about legality; just do it
|
||||||
|
|
@ -163,6 +168,7 @@ namespace Board {
|
||||||
field[castle_target] = field[castle_source];
|
field[castle_target] = field[castle_source];
|
||||||
field[castle_source] = P_EMPTY;
|
field[castle_source] = P_EMPTY;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle castling rights
|
// Handle castling rights
|
||||||
// First store the current rights in the unmove
|
// First store the current rights in the unmove
|
||||||
|
|
@ -267,11 +273,15 @@ namespace Board {
|
||||||
field[PTR_SIDE_AND_CASTLERIGHT] |= 0b01 << castleright_offset;
|
field[PTR_SIDE_AND_CASTLERIGHT] |= 0b01 << castleright_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
field[PTR_SIDE_AND_CASTLERIGHT] ^= 0x01;
|
||||||
|
|
||||||
int sq_diff = (int)sq_to - (int)sq_from;
|
int sq_diff = (int)sq_to - (int)sq_from;
|
||||||
int sq_diff_abs = abs(sq_diff);
|
int sq_diff_abs = abs(sq_diff);
|
||||||
if((field[sq_from] & 0x7) == W_KING && sq_diff_abs == 2) {
|
if((field[sq_from] & 0x7) == W_KING) {
|
||||||
|
field[PTR_W_KING | Board::black_moving()] = sq_from;
|
||||||
|
if(sq_diff_abs == 2) {
|
||||||
// we castled
|
// we castled
|
||||||
byte castle_source = 0x70*!black_moving();
|
byte castle_source = 0x70*black_moving();
|
||||||
if(sq_diff == 2) {
|
if(sq_diff == 2) {
|
||||||
castle_source += 0x7;
|
castle_source += 0x7;
|
||||||
}
|
}
|
||||||
|
|
@ -281,13 +291,14 @@ namespace Board {
|
||||||
// and clear where it was put
|
// and clear where it was put
|
||||||
field[castle_target] = P_EMPTY;
|
field[castle_target] = P_EMPTY;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
field[sq_to] = u.captured & 0b1111;
|
field[sq_to] = u.captured & 0b1111;
|
||||||
|
|
||||||
field[PTR_SIDE_AND_CASTLERIGHT] ^= 0x01;
|
|
||||||
field[PTR_ENPASSANT] = u.captured >> 4;
|
field[PTR_ENPASSANT] = u.captured >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
3
Config.h
3
Config.h
|
|
@ -9,3 +9,6 @@
|
||||||
#define _ACF_DEBUG_PRINT
|
#define _ACF_DEBUG_PRINT
|
||||||
|
|
||||||
#define _ACF_ACTIVITY_BLINK
|
#define _ACF_ACTIVITY_BLINK
|
||||||
|
|
||||||
|
//#define _ACF_BENCH_BIG
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define __MOVEGEN_H_INC
|
#define __MOVEGEN_H_INC
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
#include "Board.h"
|
||||||
|
|
||||||
const static byte SLIDE_OFFSETS[] = {255, 1, 240, 16, 15, 17, 241, 239};
|
const static byte SLIDE_OFFSETS[] = {255, 1, 240, 16, 15, 17, 241, 239};
|
||||||
const static byte KNIGHT_OFFSETS[] = {225, 31, 223, 33, 238, 18, 242, 14};
|
const static byte KNIGHT_OFFSETS[] = {225, 31, 223, 33, 238, 18, 242, 14};
|
||||||
|
|
|
||||||
49
Tasks.h
49
Tasks.h
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
#include "Movegen.h"
|
#include "Movegen.h"
|
||||||
|
#include "Threat.h"
|
||||||
|
|
||||||
unsigned long pseudo_perft(byte depth) {
|
unsigned long pseudo_perft(byte depth) {
|
||||||
// only checks pseudolegality
|
// only checks pseudolegality
|
||||||
|
|
@ -17,7 +18,37 @@ unsigned long pseudo_perft(byte depth) {
|
||||||
m = gen.next_move();
|
m = gen.next_move();
|
||||||
if(m.sq_to != 255) {
|
if(m.sq_to != 255) {
|
||||||
Board::make(m);
|
Board::make(m);
|
||||||
|
if(!Threat::illegal()) {
|
||||||
move_count += pseudo_perft(depth-1);
|
move_count += pseudo_perft(depth-1);
|
||||||
|
} else {
|
||||||
|
//Board::print();
|
||||||
|
}
|
||||||
|
Board::unmake();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return move_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long divide(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();
|
||||||
|
print_move(m);
|
||||||
|
Serial.print(F(" "));
|
||||||
|
if(m.sq_to != 255) {
|
||||||
|
Board::make(m);
|
||||||
|
int count = pseudo_perft(depth-1);
|
||||||
|
Serial.println(count);
|
||||||
|
move_count += count;
|
||||||
Board::unmake();
|
Board::unmake();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
|
@ -77,6 +108,15 @@ void debug_castle() {
|
||||||
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.println(Threat::is_check());
|
||||||
|
}
|
||||||
|
|
||||||
void debug_ep() {
|
void debug_ep() {
|
||||||
Board::print();
|
Board::print();
|
||||||
Board::make({0x14, 0x34, P_EMPTY});
|
Board::make({0x14, 0x34, P_EMPTY});
|
||||||
|
|
@ -104,7 +144,11 @@ void debug_ep() {
|
||||||
void bench() {
|
void bench() {
|
||||||
// TODO reduce code size of this (by moving repeated constants from here to PROGMEM and loops?)
|
// TODO reduce code size of this (by moving repeated constants from here to PROGMEM and loops?)
|
||||||
|
|
||||||
unsigned long startTime = micros();
|
unsigned long startTime;
|
||||||
|
unsigned long elapsed;
|
||||||
|
|
||||||
|
#ifdef _ACF_BENCH_BIG
|
||||||
|
startTime = micros();
|
||||||
|
|
||||||
Board::make({0x14, 0x34, P_EMPTY});
|
Board::make({0x14, 0x34, P_EMPTY});
|
||||||
Board::make({0x64, 0x54, P_EMPTY});
|
Board::make({0x64, 0x54, P_EMPTY});
|
||||||
|
|
@ -133,9 +177,10 @@ void bench() {
|
||||||
Board::unmake();
|
Board::unmake();
|
||||||
|
|
||||||
|
|
||||||
unsigned long elapsed = micros() - startTime;
|
elapsed = micros() - startTime;
|
||||||
Serial.print(elapsed);
|
Serial.print(elapsed);
|
||||||
Serial.println(F(" microseconds for make/unmake"));
|
Serial.println(F(" microseconds for make/unmake"));
|
||||||
|
#endif
|
||||||
|
|
||||||
for(int i = 1; i <= 4; i++) {
|
for(int i = 1; i <= 4; i++) {
|
||||||
startTime = millis();
|
startTime = millis();
|
||||||
|
|
|
||||||
15
Types.h
15
Types.h
|
|
@ -50,4 +50,19 @@ struct Move {
|
||||||
//Move move_from_str(char* s) {
|
//Move move_from_str(char* s) {
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
void print_sq(byte sq) {
|
||||||
|
Serial.print((char)((sq & 0x07) + 'a'));
|
||||||
|
Serial.print((char)(((sq & 0x70) >> 4) + '1'));
|
||||||
|
}
|
||||||
|
void print_move(Move m) {
|
||||||
|
if(m.sq_from == 0xFF) {
|
||||||
|
Serial.print(F("INVALID_MOVE"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
print_sq(m.sq_from);
|
||||||
|
print_sq(m.sq_to);
|
||||||
|
byte pc = m.pc_prom & 0x7;
|
||||||
|
if(pc != 0) Serial.print(piece_to_char(pc));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
2
Uci.h
2
Uci.h
|
|
@ -39,7 +39,7 @@ namespace Uci {
|
||||||
int depth = Serial.parseInt();
|
int depth = Serial.parseInt();
|
||||||
|
|
||||||
unsigned long startTime = millis();
|
unsigned long startTime = millis();
|
||||||
unsigned long result = pseudo_perft(depth);
|
unsigned long result = divide(depth);
|
||||||
unsigned long elapsed = millis() - startTime;
|
unsigned long elapsed = millis() - startTime;
|
||||||
|
|
||||||
Serial.print(F("perft("));
|
Serial.print(F("perft("));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue