Skip to content

Commit

Permalink
Improve castling detection
Browse files Browse the repository at this point in the history
  • Loading branch information
gkalab committed Dec 8, 2023
1 parent 241d58e commit 1fa630f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 14 deletions.
49 changes: 37 additions & 12 deletions main/adapter/lib/Sentio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,27 +118,50 @@ bool eboard::Sentio::takeBackMove(std::vector<uint8_t> const& occupiedSquares) {
void eboard::Sentio::checkValidMove(std::vector<uint8_t> const& expectedSquares,
std::vector<uint8_t> const& occupiedSquares) {
std::vector<uint8_t> missing;
std::set_difference(expectedSquares.begin(), expectedSquares.end(), occupiedSquares.begin(), occupiedSquares.end(),
std::inserter(missing, missing.begin()));
std::vector<uint8_t> extra;
std::set_difference(occupiedSquares.begin(), occupiedSquares.end(), expectedSquares.begin(), expectedSquares.end(),
std::inserter(extra, extra.begin()));
if (!nonCaptureMove(missing, extra)) {
setDifference(expectedSquares, occupiedSquares, missing, extra);
if (!nonCaptureMove(occupiedSquares, missing, extra)) {
if (!captureMove(missing, extra)) {
incompleteMove(missing, extra);
}
}
}

void eboard::Sentio::setDifference(const std::vector<uint8_t>& expectedSquares,
const std::vector<uint8_t>& occupiedSquares, std::vector<uint8_t>& missing,
std::vector<uint8_t>& extra) {
std::set_difference(expectedSquares.begin(), expectedSquares.end(), occupiedSquares.begin(), occupiedSquares.end(),
std::inserter(missing, missing.begin()));
std::set_difference(occupiedSquares.begin(), occupiedSquares.end(), expectedSquares.begin(), expectedSquares.end(),
std::inserter(extra, extra.begin()));
}

static uint8_t toBoardArraySquare(uint8_t sq) {
uint8_t file = sq & 7;
uint8_t rank = sq / 8;
return (7 - rank) * 8 + file;
}

bool eboard::Sentio::nonCaptureMove(std::vector<uint8_t> const& missing, std::vector<uint8_t> const& extra) {
bool eboard::Sentio::nonCaptureMove(std::vector<uint8_t> const& occupiedSquares, std::vector<uint8_t> const& missing,
std::vector<uint8_t> const& extra) {
if (capturePiece == nullptr && missing.size() == 1 && extra.size() == 1) {
if (!makeMove(missing[0], extra[0])) {
if (makeMove(missing[0], extra[0])) {
std::vector<uint8_t> expectedSquares = board.getOccupiedSquares();
if (expectedSquares == occupiedSquares) {
callCallback(toBoardArray(board));
} else {
// castles - need rooks to move as well
std::vector<uint8_t> miss;
std::vector<uint8_t> ex;
setDifference(expectedSquares, occupiedSquares, miss, ex);
if (miss.size() == 1 && ex.size() == 1) {
std::array<StoneId, 64> boardArray = toBoardArray(board);
boardArray[toBoardArraySquare(ex[0])] = PIECE_TO_STONE_ID.at(board.getPiece(miss[0]));
boardArray[toBoardArraySquare(miss[0])] = 0;
callCallback(boardArray);
}
}
} else {
std::array<StoneId, 64> boardArray = toBoardArray(board);
boardArray[toBoardArraySquare(extra[0])] = board.getPiece(missing[0]);
boardArray[toBoardArraySquare(missing[0])] = 0;
Expand Down Expand Up @@ -182,12 +205,16 @@ bool eboard::Sentio::captureMove(std::vector<uint8_t> const& missing, std::vecto
uint8_t fromSquare = capturePiece->getFromSquare();
uint8_t toSquare = capturePiece->getToSquare();
capturePiece.reset();
return makeMove(fromSquare, toSquare);
bool result = makeMove(fromSquare, toSquare);
callCallback(toBoardArray(board));
return result;
} else if (capturePiece != nullptr && isPossibleEpCapture(missing, extra)) {
uint8_t fromSquare = capturePiece->getFromSquare();
uint8_t toSquare = extra[0];
capturePiece.reset();
return makeMove(fromSquare, toSquare);
bool result = makeMove(fromSquare, toSquare);
callCallback(toBoardArray(board));
return result;
}
return false;
}
Expand All @@ -197,9 +224,7 @@ bool eboard::Sentio::makeMove(uint8_t fromSquare, uint8_t toSquare) {
int i = 1;
for (uint32_t move : moves) {
if (fromSquare == get_move_source_64(move) && toSquare == get_move_target_64(move)) {
board.make_move(move);
callCallback(toBoardArray(board));
return true;
return board.make_move(move);
}
i++;
}
Expand Down
7 changes: 5 additions & 2 deletions main/adapter/lib/Sentio.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ class Sentio {
static std::vector<uint8_t> toSquares(const std::array<bool, 64>& occupied);
void callCallback(std::array<StoneId, 64> const& boardArray);
static std::array<StoneId, 64> toBoardArray(chess::Chess0x88& chessBoard);
bool takeBackMove(std::vector<uint8_t> const &occupiedSquares);
bool takeBackMove(std::vector<uint8_t> const& occupiedSquares);
void checkValidMove(std::vector<uint8_t> const& expectedSquares, std::vector<uint8_t> const& occupiedSquares);
bool nonCaptureMove(std::vector<uint8_t> const& missing, std::vector<uint8_t> const& extra);
static void setDifference(const std::vector<uint8_t>& expectedSquares, const std::vector<uint8_t>& occupiedSquares,
std::vector<uint8_t>& missing, std::vector<uint8_t>& extra) ;
bool nonCaptureMove(std::vector<uint8_t> const& occupied, std::vector<uint8_t> const& missing,
std::vector<uint8_t> const& extra);
bool captureMove(std::vector<uint8_t> const& missing, std::vector<uint8_t> const& extra);
void incompleteMove(std::vector<uint8_t> const& missing, std::vector<uint8_t> const& extra);
bool makeMove(uint8_t fromSquare, uint8_t toSquare);
Expand Down
11 changes: 11 additions & 0 deletions main/adapter/test/SentioTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ TEST_F(SentioTest, captureMove) {
thenLastReceivedBoardShouldBe("rnbqkbnr/ppp1pppp/8/3P4/8/8/PPPP1PPP/RNBQKBNR");
}

TEST_F(SentioTest, castlesMove) {
givenAnInstance("r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 4 4");
givenOccupiedIsCalledWith("r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ3R"); // Ke1 up
givenOccupiedIsCalledWith("r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ2KR"); // Kg1 down
thenLastReceivedBoardShouldBe("r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ2KR");
givenOccupiedIsCalledWith("r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ2K1"); // Rh1 up
thenLastReceivedBoardShouldBe("r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ2K1");
givenOccupiedIsCalledWith("r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1"); // Rf1 down
thenLastReceivedBoardShouldBe("r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1");
}

TEST_F(SentioTest, gameSequenceThreeCaptureMovesApart) {
givenAnInstance();
// game sequence: 1. e4 c5 2. Nf3 d6 3. Bb5+ Bd7 4. Bxd7+ Qxd7 5. h4 Qc6 6. h5 Qxe4+
Expand Down

0 comments on commit 1fa630f

Please sign in to comment.