From 822f855faf07c77900a468b69bbf68387f028832 Mon Sep 17 00:00:00 2001 From: ianfab Date: Sun, 1 Jul 2018 16:01:24 +0200 Subject: [PATCH] Add support for smaller board sizes, implement los alamos chess However, the evaluation does not reflect the dependence of symmetry on number of ranks and files yet. --- src/evaluate.cpp | 4 ++-- src/movegen.cpp | 2 +- src/position.cpp | 23 ++++++++++++++--------- src/position.h | 12 ++++++++++++ src/types.h | 8 ++++---- src/variant.cpp | 13 +++++++++++++ src/variant.h | 2 ++ 7 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index aaf3f89..e3a3088 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -34,8 +34,8 @@ namespace Trace { 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]; diff --git a/src/movegen.cpp b/src/movegen.cpp index 88f350d..3010f18 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -108,7 +108,7 @@ namespace { 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(TRank8BB); Bitboard pawnsOn7 = pos.pieces(Us, PAWN) & TRank7BB; Bitboard pawnsNotOn7 = pos.pieces(Us, PAWN) & ~TRank7BB; diff --git a/src/position.cpp b/src/position.cpp index 1a0d010..f39afa0 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -248,7 +248,6 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, unsigned char col, row, token; size_t idx; - Square sq = SQ_A8; std::istringstream ss(fenStr); std::memset(this, 0, sizeof(Position)); @@ -259,6 +258,8 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, ss >> std::noskipws; + Square sq = SQ_A8 + (RANK_8 - max_rank()) * SOUTH; + // 1. Piece placement while ((ss >> token) && !isspace(token)) { @@ -266,7 +267,7 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, 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) { @@ -510,17 +511,17 @@ const string Position::fen() const { 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))]; @@ -633,6 +634,10 @@ bool Position::legal(Move m) const { assert(color_of(moved_piece(m)) == us); assert(piece_on(square(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; @@ -723,7 +728,7 @@ bool Position::pseudo_legal(const Move m) const { { // 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(us, from) & pieces(~us) & to) // Not a capture @@ -976,7 +981,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { { 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); @@ -1053,7 +1058,7 @@ void Position::undo_move(Move m) { 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); diff --git a/src/position.h b/src/position.h index 7e73ace..9ecc7e8 100644 --- a/src/position.h +++ b/src/position.h @@ -87,6 +87,8 @@ public: // 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 promotion_piece_types() const; @@ -240,6 +242,16 @@ inline const Variant* Position::variant() 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; diff --git a/src/types.h b/src/types.h index 9165fb0..df9f41c 100644 --- a/src/types.h +++ b/src/types.h @@ -441,12 +441,12 @@ constexpr Square relative_square(Color c, Square s) { 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) { diff --git a/src/variant.cpp b/src/variant.cpp index dc6209a..9f30262 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -181,6 +181,18 @@ void VariantMap::init() { // 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("chess"), chess)); insert(std::pair(std::string("makruk"), makruk)); insert(std::pair(std::string("asean"), asean)); @@ -196,6 +208,7 @@ void VariantMap::init() { insert(std::pair(std::string("crazyhouse"), crazyhouse)); insert(std::pair(std::string("loop"), loop)); insert(std::pair(std::string("euroshogi"), euroshogi)); + insert(std::pair(std::string("losalamos"), losalamos)); } void VariantMap::clear_all() { diff --git a/src/variant.h b/src/variant.h index f628f73..9b313a2 100644 --- a/src/variant.h +++ b/src/variant.h @@ -32,6 +32,8 @@ /// 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"; -- 1.7.0.4