Fix move generation I think
This commit is contained in:
parent
65015c9a6c
commit
25156e7ac7
|
|
@ -9,6 +9,58 @@
|
|||
#include "Movegen.h"
|
||||
#include "Types.h"
|
||||
|
||||
unsigned int pseudo_perft(byte depth) {
|
||||
// only checks pseudolegality
|
||||
// but, it should work overall
|
||||
if(depth == 0) return 1;
|
||||
Serial.print(F("Start a PERFT "));
|
||||
Serial.print(depth);
|
||||
Serial.println('-');
|
||||
print();
|
||||
unsigned int move_count = 0;
|
||||
Movegen gen;
|
||||
Move m;
|
||||
do {
|
||||
m = gen.next_move();
|
||||
//make(m);
|
||||
move_count += pseudo_perft(depth-1);
|
||||
//unmake();
|
||||
} while (m.sq_from != 255);
|
||||
return move_count - 1;
|
||||
}
|
||||
|
||||
void perft_test() {
|
||||
for(byte i = 0; i < 2; i++) {
|
||||
Serial.print(F("Perft "));
|
||||
Serial.print(i);
|
||||
Serial.print(F(": "));
|
||||
Serial.println(pseudo_perft(i));
|
||||
}
|
||||
}
|
||||
|
||||
void debug_movegen() {
|
||||
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");
|
||||
make(m);
|
||||
print();
|
||||
DEBUG("unmake");
|
||||
unmake();
|
||||
DEBUG("unmake done");
|
||||
}
|
||||
} while (m.sq_from != 255);
|
||||
}
|
||||
|
||||
void debug_castle() {
|
||||
print();
|
||||
make({0x06, 0x25, P_EMPTY}); print();
|
||||
|
|
|
|||
5
Board.h
5
Board.h
|
|
@ -34,7 +34,7 @@
|
|||
#define PTR_UNMOVE_LAST 0x7F
|
||||
|
||||
byte field[128];
|
||||
byte PTR_UNMOVE = PTR_UNMOVE_START;
|
||||
byte PTR_UNMOVE;
|
||||
|
||||
const byte field_default_value[] PROGMEM = BOARD_DEFAULT_VALUE;
|
||||
|
||||
|
|
@ -42,6 +42,7 @@ void board_init() {
|
|||
for(int i = 0; i < 128; i++) {
|
||||
field[i] = pgm_read_byte_near(field_default_value + i);
|
||||
}
|
||||
PTR_UNMOVE = PTR_UNMOVE_START;
|
||||
field[PTR_SIDE_AND_CASTLERIGHT] = 0b11110; // all castle rights allowed, white to move
|
||||
field[PTR_W_KING] = 0x04; // e1
|
||||
field[PTR_B_KING] = 0x74; // e8
|
||||
|
|
@ -267,7 +268,7 @@ void unmake() {
|
|||
field[PTR_SIDE_AND_CASTLERIGHT] |= 0b01 << castleright_offset;
|
||||
}
|
||||
|
||||
int sq_diff = (int)sq_to - (int)u.sq_from;
|
||||
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
|
||||
|
|
|
|||
2
Config.h
2
Config.h
|
|
@ -5,3 +5,5 @@
|
|||
// PANIC_BLINK makes the Arduino blink an error code when it panics.
|
||||
// Costs a lot of flash though (around 700 bytes)
|
||||
//#define _ACF_PANIC_BLINK
|
||||
|
||||
#define _ACF_DEBUG_PRINT
|
||||
|
|
|
|||
59
Movegen.h
59
Movegen.h
|
|
@ -25,7 +25,7 @@ class Movegen {
|
|||
};
|
||||
|
||||
Move Movegen::next_move() {
|
||||
while(square <= 0x7F) {
|
||||
while(square <= 0x77) {
|
||||
if(square & 0x88) square += 8;
|
||||
|
||||
byte piece_type = field[square] & 0x7;
|
||||
|
|
@ -37,14 +37,11 @@ Move Movegen::next_move() {
|
|||
// there is an own piece to investigate
|
||||
Move m;
|
||||
if(piece_type == W_PAWN) {
|
||||
Serial.println("GENERATE PAWN");
|
||||
m = generate_pawn();
|
||||
} else if(piece_type & 0b0100) {
|
||||
Serial.println("GENERATE SLIDING");
|
||||
// bishop, rook and queen are 01xx.
|
||||
m = generate_sliding(piece_type);
|
||||
} else {
|
||||
Serial.println("GENERATE NONSLIDING");
|
||||
m = generate_non_sliding(piece_type);
|
||||
}
|
||||
if(m.sq_to != 255) {
|
||||
|
|
@ -125,6 +122,8 @@ Move Movegen::generate_non_sliding(byte piece_type) {
|
|||
}
|
||||
|
||||
Move Movegen::generate_pawn() {
|
||||
// TODO: implement capture promotion
|
||||
|
||||
byte color = black_moving();
|
||||
byte offset;
|
||||
byte target;
|
||||
|
|
@ -166,19 +165,21 @@ Move Movegen::generate_pawn() {
|
|||
offset = color ? -0x11 : 0xF;
|
||||
target_square = square + offset;
|
||||
target = field[target_square];
|
||||
if(target && (target & 0x8) != (field[square] & 0x8)) {
|
||||
// normal capture allowded
|
||||
return Move{square, target_square, P_EMPTY};
|
||||
} else if(field[PTR_ENPASSANT]) {
|
||||
// note that EP being legal only happens
|
||||
// when the target field is empty. so this saves some effort.
|
||||
byte ep_col = field[PTR_ENPASSANT] & 0x7;
|
||||
if(
|
||||
ep_col == (target_square & 0x7) &&
|
||||
(square & 0x70) == (color ? 0x30 : 0x40)
|
||||
) {
|
||||
// EP-capture possible
|
||||
if(!(target_square & 0x88)) {
|
||||
if(target && (target & 0x8) != (field[square] & 0x8)) {
|
||||
// normal capture allowded
|
||||
return Move{square, target_square, P_EMPTY};
|
||||
} else if(field[PTR_ENPASSANT]) {
|
||||
// note that EP being legal only happens
|
||||
// when the target field is empty. so this saves some effort.
|
||||
byte ep_col = field[PTR_ENPASSANT] & 0x7;
|
||||
if(
|
||||
ep_col == (target_square & 0x7) &&
|
||||
(square & 0x70) == (color ? 0x30 : 0x40)
|
||||
) {
|
||||
// EP-capture possible
|
||||
return Move{square, target_square, P_EMPTY};
|
||||
}
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
|
|
@ -188,19 +189,21 @@ Move Movegen::generate_pawn() {
|
|||
offset = color ? -0xF : 0x11;
|
||||
target_square = square + offset;
|
||||
target = field[target_square];
|
||||
if(target && (target & 0x8) != (field[square] & 0x8)) {
|
||||
// normal capture allowded
|
||||
return Move{square, target_square, P_EMPTY};
|
||||
} else if(field[PTR_ENPASSANT]) {
|
||||
// note that EP being legal only happens
|
||||
// when the target field is empty. so this saves some effort.
|
||||
byte ep_col = field[PTR_ENPASSANT] & 0x7;
|
||||
if(
|
||||
ep_col == (target_square & 0x7) &&
|
||||
(square & 0x70) == (color ? 0x30 : 0x40)
|
||||
) {
|
||||
// EP-capture possible
|
||||
if(!(target_square & 0x88)) {
|
||||
if(target && (target & 0x8) != (field[square] & 0x8)) {
|
||||
// normal capture allowded
|
||||
return Move{square, target_square, P_EMPTY};
|
||||
} else if(field[PTR_ENPASSANT]) {
|
||||
// note that EP being legal only happens
|
||||
// when the target field is empty. so this saves some effort.
|
||||
byte ep_col = field[PTR_ENPASSANT] & 0x7;
|
||||
if(
|
||||
ep_col == (target_square & 0x7) &&
|
||||
(square & 0x70) == (color ? 0x30 : 0x40)
|
||||
) {
|
||||
// EP-capture possible
|
||||
return Move{square, target_square, P_EMPTY};
|
||||
}
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
|
|
|
|||
Loading…
Reference in New Issue