59 lines
2.4 KiB
C++
59 lines
2.4 KiB
C++
#include <vector>
|
|
#include <Rcpp.h>
|
|
|
|
#include "SchachHoernchen/types.h"
|
|
#include "SchachHoernchen/utils.h"
|
|
#include "SchachHoernchen/Board.h"
|
|
|
|
//' Convert a legal FEN string to a 3D binary (integer with 0-1 entries) array
|
|
// [[Rcpp::export(rng = false)]]
|
|
Rcpp::IntegerVector fen2int(const std::vector<Board>& boards) {
|
|
// Initialize empty chess board as a 3D binary tensor
|
|
Rcpp::IntegerVector bitboards(8 * 8 * 12 * (int)boards.size());
|
|
// Set dimension and dimension names (required this way since `Rcpp::Dimension`
|
|
// does _not_ support 4D arrays)
|
|
auto dims = Rcpp::IntegerVector({ 8, 8, 12, (int)boards.size() });
|
|
bitboards.attr("dim") = dims;
|
|
bitboards.attr("dimnames") = Rcpp::List::create(
|
|
Rcpp::Named("rank") = Rcpp::CharacterVector::create(
|
|
"8", "7", "6", "5", "4", "3", "2", "1"
|
|
),
|
|
Rcpp::Named("file") = Rcpp::CharacterVector::create(
|
|
"a", "b", "c", "d", "e", "f", "g", "h"
|
|
),
|
|
Rcpp::Named("piece") = Rcpp::CharacterVector::create(
|
|
"P", "N", "B", "R", "Q", "K", // White Pieces (Upper Case)
|
|
"p", "n", "b", "r", "q", "k" // Black Pieces (Lower Case)
|
|
),
|
|
R_NilValue
|
|
);
|
|
|
|
// Index to color/piece mapping (more robust)
|
|
enum piece colorLoopup[2] = { white, black };
|
|
enum piece pieceLookup[6] = { pawn, knight, bishop, rook, queen, king };
|
|
|
|
// Set for every piece the corresponding pit positions, note the
|
|
// "transposition" of the indexing from SchachHoernchen's binary indexing
|
|
// scheme to the 3D array indexing of ranks/files.
|
|
for (int i = 0; i < boards.size(); ++i) {
|
|
const Board& pos = boards[i];
|
|
for (int color = 0; color < 2; ++color) {
|
|
for (int piece = 0; piece < 6; ++piece) {
|
|
int slice = 6 * color + piece;
|
|
u64 bb = pos.bb(colorLoopup[color]) & pos.bb(pieceLookup[piece]);
|
|
for (; bb; bb &= bb - 1) {
|
|
// Get BitBoard index
|
|
int index = bitScanLS(bb);
|
|
// Transpose to align with printing as a Chess Board
|
|
index = ((index & 7) << 3) | ((index & 56) >> 3);
|
|
// Flip black to move positions to whites point of view
|
|
index ^= pos.isWhiteTurn() ? 0 : 7;
|
|
bitboards[768 * i + 64 * slice + index] = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return bitboards;
|
|
}
|