tensor_predictors/dataAnalysis/chess/Rchess/src/fen2int.cpp

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;
}