diff --git a/ArduChess.ino b/ArduChess.ino index 5c7723e..749d8cc 100644 --- a/ArduChess.ino +++ b/ArduChess.ino @@ -10,30 +10,43 @@ void setup() { // put your setup code here, to run once: Serial.begin(9600); - char value; - while(Serial.available() == 0) { - delay(100); - } - value = Serial.read(); + //char value; + //while(Serial.available() == 0) { + // delay(100); + //} + //value = Serial.read(); + + //b.field[0x31] = char_to_piece(value); + + //Serial.println(F("hello")); + //delay(1000); + //Serial.println(b.get_zobrist()); + //Serial.println(sizeof(b)); + + //Move m = {0x14, 0x34, P_EMPTY}; + //Serial.println(F("Initial board")); + //b.print(); + //b.make(m); + //Serial.println(F("Board after e2e4")); + //b.print(); + //b.unmake(); + //Serial.println(F("Board after unmake")); + //b.print(); + //delay(1000); + Serial.println(F("hello")); + + b = Board(); + 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.print(); + b.make({0x44, 0x53, P_EMPTY}); + b.print(); + - b.field[0x32] = char_to_piece(value); } void loop() { // put your main code here, to run repeatedly: - Serial.println(F("hello")); - delay(1000); - Serial.println(b.get_zobrist()); - Serial.println(sizeof(b)); - - Move m = {0x14, 0x34, P_EMPTY}; - Serial.println(F("Initial board")); - b.print(); - b.make(m); - Serial.println(F("Board after e2e4")); - b.print(); - b.unmake(); - Serial.println(F("Board after unmake")); - b.print(); - delay(1000); } diff --git a/Board.h b/Board.h index 7435f20..05edf33 100644 --- a/Board.h +++ b/Board.h @@ -6,10 +6,11 @@ #include "Move.h" struct Unmove { - byte sq_from; - byte sq_to; - byte captured; + byte sq_from; // 0b(1unused)(3rank)(1unused)(3file) + byte sq_to; // 0b(1promoted?)(3rank)(1unused)(3file) + byte captured; // 0b(4unused)(1color)(3piecetype) byte enpassant; + byte revmov; }; class Board { @@ -30,6 +31,10 @@ class Board { 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, @@ -86,25 +91,68 @@ void Board::print() { } void Board::make(Move m) { + // fill unmove struct with basic data Unmove u; u.captured = field[m.sq_to]; u.sq_from = m.sq_from; u.sq_to = m.sq_to; - byte new_val = m.pc_prom & 0b1111; - if(new_val != P_EMPTY) { - u.sq_to |= 0x80; - } else { - new_val = field[m.sq_from]; - } - field[m.sq_to] = field[m.sq_from]; - field[m.sq_from] = P_EMPTY; - // TODO handle castling // TODO handle castling rights // TODO handle revmov clock - // TODO handle enpassant + // TODO zobrist + // TODO: test enpassant code + + // handle enpassant capture + if(field[PTR_ENPASSANT] && (field[m.sq_from] & 0b111) == W_PAWN) { + // en-passant capture is allowed. + // we are also doing a pawn move + // do further checks to see if we should remove the EP-pawn. + if( + (m.sq_to & 0x7) == (field[PTR_ENPASSANT] & 0x7) && + (m.sq_to & 0x70) == (0x50 - 0x30*black_moving()) + ) { + // we are also going to the correct square to do EP. + // therefore, delete the EP-vurnerable pawn + byte ep_field = m.sq_to - 16 + 32*black_moving(); + field[ep_field] = P_EMPTY; + } + } + + // Store the current enpassant situation + u.enpassant = field[PTR_ENPASSANT]; + + // handle enpassant setup (double pawn move) + // Calculate the move 'amount' + int sq_diff = (int)m.sq_from - (int)m.sq_to; + if( + (field[m.sq_from] & 0b111) == W_PAWN && + (sq_diff == 32 || sq_diff == -32) + ) { + // we are doing a pawn double-move. + // therefore, it allows enpassant in the next move. + field[PTR_ENPASSANT] = 0b1000 | (m.sq_from & 0x7); + } else { + // no enpassant in the next turn. + field[PTR_ENPASSANT] = 0; + } + + // are we promoting? + byte new_val = m.pc_prom & 0b1111; + if(new_val != P_EMPTY) { + // promoting; indicate this in the sq_to byte in unmove. + u.sq_to |= 0x80; + } else { + // not promoting; so keep the same piece type + new_val = field[m.sq_from]; + } + // copy (and possibly promote) our piece. + field[m.sq_to] = new_val; + // then delete the original copy. + field[m.sq_from] = P_EMPTY; + + // Switch sides field[PTR_SIDE_AND_CASTLERIGHT] ^= 0x01; store_unmove(u); diff --git a/Move.h b/Move.h index 7cb65ff..3ce5083 100644 --- a/Move.h +++ b/Move.h @@ -4,9 +4,9 @@ #include "Types.h" struct Move { - byte sq_from; - byte sq_to; - Piece pc_prom; + byte sq_from; // 0x88 + byte sq_to; // 0x88 + Piece pc_prom; // 0b(4unused)(1color)(3type) }; //Move move_from_str(char* s) {