diff --git a/ArduChess.ino b/ArduChess.ino index b8ed633..10c2545 100644 --- a/ArduChess.ino +++ b/ArduChess.ino @@ -9,22 +9,21 @@ #include "Movegen.h" #include "Types.h" -Board b = Board(); - void bench() { - b = Board(); + board_init(); + int startTime = micros(); - b.make({0x14, 0x34, P_EMPTY}); - b.make({0x64, 0x54, P_EMPTY}); - b.make({0x34, 0x44, P_EMPTY}); - b.make({0x63, 0x43, P_EMPTY}); - b.make({0x44, 0x53, P_EMPTY}); - b.unmake(); - b.unmake(); - b.unmake(); - b.unmake(); - b.unmake(); + make({0x14, 0x34, P_EMPTY}); + make({0x64, 0x54, P_EMPTY}); + make({0x34, 0x44, P_EMPTY}); + make({0x63, 0x43, P_EMPTY}); + make({0x44, 0x53, P_EMPTY}); + unmake(); + unmake(); + unmake(); + unmake(); + unmake(); int elapsed = micros() - startTime; Serial.print(elapsed); @@ -34,34 +33,35 @@ void bench() { void setup() { // put your setup code here, to run once: + board_init(); Serial.begin(115200); bench(); Serial.println(F("hello")); - b = Board(); + board_init(); int startTime = micros(); - b.print(); - b.make({0x14, 0x34, P_EMPTY}); - b.print(); - b.make({0x64, 0x54, P_EMPTY}); - b.print(); - b.make({0x34, 0x44, P_EMPTY}); - b.print(); - b.make({0x63, 0x43, P_EMPTY}); - b.print(); - b.make({0x44, 0x53, P_EMPTY}); - b.print(); - b.unmake(); - b.print(); - b.unmake(); - b.print(); - b.unmake(); - b.print(); - b.unmake(); - b.print(); - b.unmake(); - b.print(); + print(); + make({0x14, 0x34, P_EMPTY}); + print(); + make({0x64, 0x54, P_EMPTY}); + print(); + make({0x34, 0x44, P_EMPTY}); + print(); + make({0x63, 0x43, P_EMPTY}); + print(); + make({0x44, 0x53, P_EMPTY}); + print(); + unmake(); + print(); + unmake(); + print(); + unmake(); + print(); + unmake(); + print(); + unmake(); + print(); int elapsed = micros() - startTime; Serial.print(elapsed); diff --git a/Board.h b/Board.h index d8e03da..dcc7e6c 100644 --- a/Board.h +++ b/Board.h @@ -5,6 +5,45 @@ #include "Panic.h" #include "Move.h" +#define BOARD_DEFAULT_VALUE { \ + W_ROOK, W_KNGT, W_BSHP, W_QUEN, W_KING, W_BSHP, W_KNGT, W_ROOK, 0, 0, 0, 0, 0, 0, 0, 0, \ + W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, 0, 0, 0, 0, 0, 0, 0, 0, \ + B_ROOK, B_KNGT, B_BSHP, B_QUEN, B_KING, B_BSHP, B_KNGT, B_ROOK, 0, 0, 0, 0, 0, 0, 0, 0, \ +}; + + +byte field[128]; +const byte field_default_value[] PROGMEM = BOARD_DEFAULT_VALUE; + +void board_init() { + for(int i = 0; i < 128; i++) { + field[i] = pgm_read_byte_near(field_default_value + i); + } +} + +// 0x88-fill definitions +static const byte PTR_SIDE_AND_CASTLERIGHT = 0x08; //byte (1=side, 2,4=white castle, 8,16=black) +// CAN FILL 0x09 +static const byte PTR_W_KING = 0x0A; // byte (points to index or maybe 64-arr index) +// const byte PTR_B_KING = 0x0B; (PTR_W_KING | COLOR or PTR_W_KING + COLOR) +static const byte PTR_ZOBRIST = 0x0C; // 4 bytes +// 0x0D +// 0x0E +// 0x0F + +static const byte PTR_ENPASSANT = 0x18; +static const byte PTR_REVMOV = 0x19; +// free space + +static const byte PTR_UNMOVE_START = 0x28; +static const byte PTR_UNMOVE_LAST = 0x7F; +byte PTR_UNMOVE = PTR_UNMOVE_START; + struct Unmove { byte sq_from; // 0b(1unused)(3rank)(1unused)(3file) byte sq_to; // 0b(1promoted?)(3rank)(1unused)(3file) @@ -12,74 +51,59 @@ struct Unmove { byte revmov; // 8bit integer }; -class Board { - public: - Board(); - - void make(Move m); - void unmake(); - - void print(); - - bool black_moving() { - return field[PTR_SIDE_AND_CASTLERIGHT] & 0x1; - } - - unsigned long get_zobrist() { - long* addr = (long*) &field[PTR_ZOBRIST]; - return *addr; - } - - void reset_unmake_stack() { - PTR_UNMOVE = PTR_UNMOVE_START; - } - - byte field[128] = { - W_ROOK, W_KNGT, W_BSHP, W_QUEN, W_KING, W_BSHP, W_KNGT, W_ROOK, 0, 0, 0, 0, 0, 0, 0, 0, - W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, W_PAWN, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, B_PAWN, 0, 0, 0, 0, 0, 0, 0, 0, - B_ROOK, B_KNGT, B_BSHP, B_QUEN, B_KING, B_BSHP, B_KNGT, B_ROOK, 0, 0, 0, 0, 0, 0, 0, 0, - }; - private: - // Private function defs - void next_unmove(); - void prev_unmove(); - - void store_unmove(Unmove u); - Unmove read_unmove(); - - // 0x88-fill definitions - static const byte PTR_SIDE_AND_CASTLERIGHT = 0x08; //byte (1=side, 2,4=white castle, 8,16=black) - // CAN FILL 0x09 - static const byte PTR_W_KING = 0x0A; // byte (points to index or maybe 64-arr index) - // const byte PTR_B_KING = 0x0B; (PTR_W_KING | COLOR or PTR_W_KING + COLOR) - static const byte PTR_ZOBRIST = 0x0C; // 4 bytes - // 0x0D - // 0x0E - // 0x0F - - static const byte PTR_ENPASSANT = 0x18; - static const byte PTR_REVMOV = 0x19; - // free space - - static const byte PTR_UNMOVE_START = 0x28; - static const byte PTR_UNMOVE_LAST = 0x7F; - byte PTR_UNMOVE = PTR_UNMOVE_START; - - - -}; - -Board::Board() { - // Then, other data we need to store is assigned 0-fields. - field[PTR_ZOBRIST+1] = 1; +bool black_moving() { + return field[PTR_SIDE_AND_CASTLERIGHT] & 0x1; } -void Board::print() { +unsigned long get_zobrist() { + long* addr = (long*) &field[PTR_ZOBRIST]; + return *addr; +} + +void reset_unmake_stack() { + PTR_UNMOVE = PTR_UNMOVE_START; +} + +void next_unmove() { + PTR_UNMOVE++; + if(PTR_UNMOVE > PTR_UNMOVE_LAST) { + panic(F("Unmove stack overflow")); + } + if(!(PTR_UNMOVE & 0x8)) { + PTR_UNMOVE += 0x8; + } +} +void prev_unmove() { + PTR_UNMOVE--; + if(PTR_UNMOVE < PTR_UNMOVE_START) { + panic(F("Unmaking from empty stack")); + } + if(!(PTR_UNMOVE & 0x8)) { + PTR_UNMOVE -= 0x8; + } +} +void store_unmove(Unmove u) { + byte *ub = (byte*) &u; + for(byte i = 0; i < sizeof(u); i++) { + field[PTR_UNMOVE] = ub[i]; + next_unmove(); + } +} +Unmove read_unmove() { + Unmove u; + byte* ptr = (byte*) &u; + for(int i = sizeof(u) - 1; i >= 0; i--) { + prev_unmove(); + ptr[i] = field[PTR_UNMOVE]; + #ifdef _ACF_CLEAR_UNMOVE + field[PTR_UNMOVE] = 0; + #endif + } + return u; +} + + +void print() { Serial.println(F("BOARD:")); for(char i = 7; i >= 0; i--) { for(byte j = 0; j < 16; j++) { @@ -92,7 +116,7 @@ void Board::print() { } } -void Board::make(Move m) { +void make(Move m) { // TODO handle revmov clock // TODO zobrist? @@ -198,7 +222,7 @@ void Board::make(Move m) { store_unmove(u); } -void Board::unmake() { +void unmake() { Unmove u = read_unmove(); field[PTR_REVMOV] = u.revmov; @@ -227,42 +251,5 @@ void Board::unmake() { field[PTR_ENPASSANT] = u.captured >> 4; } -void Board::next_unmove() { - PTR_UNMOVE++; - if(PTR_UNMOVE > PTR_UNMOVE_LAST) { - panic(F("Unmove stack overflow")); - } - if(!(PTR_UNMOVE & 0x8)) { - PTR_UNMOVE += 0x8; - } -} -void Board::prev_unmove() { - PTR_UNMOVE--; - if(PTR_UNMOVE < PTR_UNMOVE_START) { - panic(F("Unmaking from empty stack")); - } - if(!(PTR_UNMOVE & 0x8)) { - PTR_UNMOVE -= 0x8; - } -} -void Board::store_unmove(Unmove u) { - byte *ub = (byte*) &u; - for(byte i = 0; i < sizeof(u); i++) { - field[PTR_UNMOVE] = ub[i]; - next_unmove(); - } -} -Unmove Board::read_unmove() { - Unmove u; - byte* ptr = (byte*) &u; - for(int i = sizeof(u) - 1; i >= 0; i--) { - prev_unmove(); - ptr[i] = field[PTR_UNMOVE]; - #ifdef _ACF_CLEAR_UNMOVE - field[PTR_UNMOVE] = 0; - #endif - } - return u; -} #endif