enum Tracing { NO_TRACE, TRACE };
- enum Term { // The first 8 entries are reserved for PieceType
- MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, INITIATIVE, VARIANT, TOTAL, TERM_NB
+ enum Term { // The first PIECE_TYPE_NB entries are reserved for PieceType
+ MATERIAL = PIECE_TYPE_NB, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, INITIATIVE, VARIANT, TOTAL, TERM_NB
};
Score scores[TERM_NB][COLOR_NB];
Bitboard emptySquares;
- Bitboard TRank8BB = rank_bb(Us == WHITE ? pos.promotion_rank() : ~pos.promotion_rank());
+ Bitboard TRank8BB = rank_bb(Us == WHITE ? pos.promotion_rank() : Rank(pos.max_rank() - pos.promotion_rank()));
Bitboard TRank7BB = shift<Down>(TRank8BB);
Bitboard pawnsOn7 = pos.pieces(Us, PAWN) & TRank7BB;
Bitboard pawnsNotOn7 = pos.pieces(Us, PAWN) & ~TRank7BB;
unsigned char col, row, token;
size_t idx;
- Square sq = SQ_A8;
std::istringstream ss(fenStr);
std::memset(this, 0, sizeof(Position));
ss >> std::noskipws;
+ Square sq = SQ_A8 + (RANK_8 - max_rank()) * SOUTH;
+
// 1. Piece placement
while ((ss >> token) && !isspace(token))
{
sq += (token - '0') * EAST; // Advance the given number of files
else if (token == '/')
- sq += 2 * SOUTH;
+ sq += 2 * SOUTH + (FILE_H - max_file()) * EAST;
else if ((idx = piece_to_char().find(token)) != string::npos)
{
int emptyCnt;
std::ostringstream ss;
- for (Rank r = RANK_8; r >= RANK_1; --r)
+ for (Rank r = max_rank(); r >= RANK_1; --r)
{
- for (File f = FILE_A; f <= FILE_H; ++f)
+ for (File f = FILE_A; f <= max_file(); ++f)
{
- for (emptyCnt = 0; f <= FILE_H && empty(make_square(f, r)); ++f)
+ for (emptyCnt = 0; f <= max_file() && empty(make_square(f, r)); ++f)
++emptyCnt;
if (emptyCnt)
ss << emptyCnt;
- if (f <= FILE_H)
+ if (f <= max_file())
{
ss << piece_to_char()[piece_on(make_square(f, r))];
assert(color_of(moved_piece(m)) == us);
assert(piece_on(square<KING>(us)) == make_piece(us, KING));
+ // illegal moves to squares outside of board
+ if (rank_of(to) > max_rank() || file_of(to) > max_file())
+ return false;
+
// illegal checks
if (!checking_permitted() && gives_check(m))
return false;
{
// We have already handled promotion moves, so destination
// cannot be on the 8th/1st rank.
- if (rank_of(to) == relative_rank(us, promotion_rank()))
+ if (rank_of(to) == relative_rank(us, promotion_rank(), max_rank()))
return false;
if ( !(attacks_from<PAWN>(us, from) & pieces(~us) & to) // Not a capture
{
Piece promotion = make_piece(us, promotion_type(m));
- assert(relative_rank(us, to) == promotion_rank());
+ assert(relative_rank(us, to, max_rank()) == promotion_rank());
assert(type_of(promotion) >= KNIGHT && type_of(promotion) < KING);
remove_piece(pc, to);
if (type_of(m) == PROMOTION)
{
- assert(relative_rank(us, to) == promotion_rank());
+ assert(relative_rank(us, to, max_rank()) == promotion_rank());
assert(type_of(pc) == promotion_type(m));
assert(type_of(pc) >= KNIGHT && type_of(pc) < KING);
// Variant rule properties
const Variant* variant() const;
+ Rank max_rank() const;
+ File max_file() const;
const std::string piece_to_char() const;
Rank promotion_rank() const;
std::vector<PieceType> promotion_piece_types() const;
return var;
}
+inline Rank Position::max_rank() const {
+ assert(var != nullptr);
+ return var->maxRank;
+}
+
+inline File Position::max_file() const {
+ assert(var != nullptr);
+ return var->maxFile;
+}
+
inline const std::string Position::piece_to_char() const {
assert(var != nullptr);
return var->pieceToChar;
return Square(s ^ (c * 56));
}
-constexpr Rank relative_rank(Color c, Rank r) {
- return Rank(r ^ (c * 7));
+constexpr Rank relative_rank(Color c, Rank r, Rank maxRank = RANK_8) {
+ return Rank(r ^ (c * maxRank));
}
-constexpr Rank relative_rank(Color c, Square s) {
- return relative_rank(c, rank_of(s));
+constexpr Rank relative_rank(Color c, Square s, Rank maxRank = RANK_8) {
+ return relative_rank(c, rank_of(s), maxRank);
}
inline bool opposite_colors(Square s1, Square s2) {
// TODO: piece promotions, illegal pawn drops
return v;
} ();
+ const Variant* losalamos = [&]{
+ Variant* v = new Variant();
+ v->maxRank = RANK_6;
+ v->maxFile = FILE_F;
+ v->set_piece(BISHOP, ' ');
+ v->startFen = "rnqknr/pppppp/6/6/PPPPPP/RNQKNR w - - 0 1";
+ v->promotionRank = RANK_6;
+ v->promotionPieceTypes = {QUEEN, ROOK, KNIGHT};
+ v->doubleStep = false;
+ v->castling = false;
+ return v;
+ } ();
insert(std::pair<std::string, const Variant*>(std::string("chess"), chess));
insert(std::pair<std::string, const Variant*>(std::string("makruk"), makruk));
insert(std::pair<std::string, const Variant*>(std::string("asean"), asean));
insert(std::pair<std::string, const Variant*>(std::string("crazyhouse"), crazyhouse));
insert(std::pair<std::string, const Variant*>(std::string("loop"), loop));
insert(std::pair<std::string, const Variant*>(std::string("euroshogi"), euroshogi));
+ insert(std::pair<std::string, const Variant*>(std::string("losalamos"), losalamos));
}
void VariantMap::clear_all() {
/// Variant struct stores information needed to determine the rules of a variant.
struct Variant {
+ Rank maxRank = RANK_8;
+ File maxFile = FILE_H;
std::string pieceToChar = " PNBRQ" + std::string(KING - QUEEN - 1, ' ') + "K" + std::string(PIECE_TYPE_NB - KING - 1, ' ')
+ " pnbrq" + std::string(KING - QUEEN - 1, ' ') + "k" + std::string(PIECE_TYPE_NB - KING - 1, ' ');
std::string startFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";