Implement eg threat detection
This commit is contained in:
parent
5507db23dd
commit
49aa6ec54b
55
Board.h
55
Board.h
|
|
@ -51,7 +51,9 @@ namespace Board {
|
|||
*zob = 0xDEADBEEF;
|
||||
}
|
||||
|
||||
|
||||
void swap_side() {
|
||||
field[PTR_SIDE_AND_CASTLERIGHT] ^= 0x01;
|
||||
}
|
||||
|
||||
struct Unmove {
|
||||
byte sq_from; // 0b(1kingside_castle?)(3rank)(1queenside_castle?)(3file)
|
||||
|
|
@ -151,17 +153,21 @@ namespace Board {
|
|||
|
||||
// TODO test the castling code more extensively
|
||||
// Handle castling
|
||||
if(piece_type == W_KING && sq_diff_abs == 2) {
|
||||
// We are castling! After all, a king cannot move
|
||||
// more than one position except when castling.
|
||||
// Since we don't care about legality; just do it
|
||||
byte castle_source = (color ? 0x70 : 0x0);
|
||||
if(sq_diff == 2) {
|
||||
castle_source += 0x7;
|
||||
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
|
||||
// more than one position except when castling.
|
||||
// Since we don't care about legality; just do it
|
||||
byte castle_source = (color ? 0x70 : 0x0);
|
||||
if(sq_diff == 2) {
|
||||
castle_source += 0x7;
|
||||
}
|
||||
byte castle_target = m.sq_from + (sq_diff/2);
|
||||
field[castle_target] = field[castle_source];
|
||||
field[castle_source] = P_EMPTY;
|
||||
}
|
||||
byte castle_target = m.sq_from + (sq_diff/2);
|
||||
field[castle_target] = field[castle_source];
|
||||
field[castle_source] = P_EMPTY;
|
||||
}
|
||||
|
||||
// Handle castling rights
|
||||
|
|
@ -267,27 +273,32 @@ namespace Board {
|
|||
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_abs = abs(sq_diff);
|
||||
if((field[sq_from] & 0x7) == W_KING && sq_diff_abs == 2) {
|
||||
// we castled
|
||||
byte castle_source = 0x70*!black_moving();
|
||||
if(sq_diff == 2) {
|
||||
castle_source += 0x7;
|
||||
if((field[sq_from] & 0x7) == W_KING) {
|
||||
field[PTR_W_KING | Board::black_moving()] = sq_from;
|
||||
if(sq_diff_abs == 2) {
|
||||
// we castled
|
||||
byte castle_source = 0x70*black_moving();
|
||||
if(sq_diff == 2) {
|
||||
castle_source += 0x7;
|
||||
}
|
||||
byte castle_target = sq_from + (sq_diff/2);
|
||||
// move rook back to original position
|
||||
field[castle_source] = field[castle_target];
|
||||
// and clear where it was put
|
||||
field[castle_target] = P_EMPTY;
|
||||
}
|
||||
byte castle_target = sq_from + (sq_diff/2);
|
||||
// move rook back to original position
|
||||
field[castle_source] = field[castle_target];
|
||||
// and clear where it was put
|
||||
field[castle_target] = P_EMPTY;
|
||||
}
|
||||
|
||||
|
||||
field[sq_to] = u.captured & 0b1111;
|
||||
|
||||
field[PTR_SIDE_AND_CASTLERIGHT] ^= 0x01;
|
||||
field[PTR_ENPASSANT] = u.captured >> 4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
5
Config.h
5
Config.h
|
|
@ -8,4 +8,7 @@
|
|||
|
||||
#define _ACF_DEBUG_PRINT
|
||||
|
||||
#define _ACF_ACTIVITY_BLINK
|
||||
#define _ACF_ACTIVITY_BLINK
|
||||
|
||||
//#define _ACF_BENCH_BIG
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define __MOVEGEN_H_INC
|
||||
|
||||
#include "Types.h"
|
||||
#include "Board.h"
|
||||
|
||||
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};
|
||||
|
|
|
|||
53
Tasks.h
53
Tasks.h
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "Types.h"
|
||||
#include "Movegen.h"
|
||||
#include "Threat.h"
|
||||
|
||||
unsigned long pseudo_perft(byte depth) {
|
||||
// only checks pseudolegality
|
||||
|
|
@ -17,7 +18,37 @@ unsigned long pseudo_perft(byte depth) {
|
|||
m = gen.next_move();
|
||||
if(m.sq_to != 255) {
|
||||
Board::make(m);
|
||||
move_count += pseudo_perft(depth-1);
|
||||
if(!Threat::illegal()) {
|
||||
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();
|
||||
} else {
|
||||
break;
|
||||
|
|
@ -77,6 +108,15 @@ void debug_castle() {
|
|||
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() {
|
||||
Board::print();
|
||||
Board::make({0x14, 0x34, P_EMPTY});
|
||||
|
|
@ -104,7 +144,11 @@ void debug_ep() {
|
|||
void bench() {
|
||||
// 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({0x64, 0x54, P_EMPTY});
|
||||
|
|
@ -133,9 +177,10 @@ void bench() {
|
|||
Board::unmake();
|
||||
|
||||
|
||||
unsigned long elapsed = micros() - startTime;
|
||||
elapsed = micros() - startTime;
|
||||
Serial.print(elapsed);
|
||||
Serial.println(F(" microseconds for make/unmake"));
|
||||
#endif
|
||||
|
||||
for(int i = 1; i <= 4; i++) {
|
||||
startTime = millis();
|
||||
|
|
@ -167,4 +212,4 @@ void bench() {
|
|||
Serial.println(F(" microseconds for make/unmake(init_pos)"));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
15
Types.h
15
Types.h
|
|
@ -50,4 +50,19 @@ struct Move {
|
|||
//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
|
||||
|
|
|
|||
Loading…
Reference in New Issue