From: ianfab Date: Sat, 7 Jul 2018 14:19:28 +0000 (+0200) Subject: Use a general mobility bonus formula for fairy pieces X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=1a604427b3dc38728b14cf44cb3c7e3eea57fda5;p=fairystockfish.git Use a general mobility bonus formula for fairy pieces No functional change for standard chess. --- diff --git a/src/evaluate.cpp b/src/evaluate.cpp index da23236..5abb88a 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -159,7 +159,7 @@ namespace { constexpr int PassedDanger[RANK_NB] = { 0, 0, 0, 3, 6, 12, 21 }; // KingProtector[PieceType-2] contains a penalty according to distance from king - constexpr Score KingProtector[] = { S(3, 5), S(4, 3), S(3, 0), S(1, -1) }; + constexpr Score KingProtector[PIECE_TYPE_NB - 2] = { S(3, 5), S(4, 3), S(3, 0), S(1, -1) }; // Assorted bonuses and penalties constexpr Score BishopPawns = S( 3, 5); @@ -196,7 +196,7 @@ namespace { private: template void initialize(); - template Score pieces(); + template Score pieces(PieceType Pt); template Score king() const; template Score threats() const; template Score passed() const; @@ -291,14 +291,14 @@ namespace { // Evaluation::pieces() scores pieces of a given color and type - template template - Score Evaluation::pieces() { + template template + Score Evaluation::pieces(PieceType Pt) { constexpr Color Them = (Us == WHITE ? BLACK : WHITE); constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH); constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB : Rank5BB | Rank4BB | Rank3BB); - const Square* pl = pos.squares(Us); + const Square* pl = pos.squares(Us, Pt); Bitboard b, bb; Square s; @@ -330,7 +330,10 @@ namespace { int mob = popcount(b & mobilityArea[Us]); - mobility[Us] += MobilityBonus[Pt - 2][mob]; + if (Pt <= QUEEN) + mobility[Us] += MobilityBonus[Pt - 2][mob]; + else + mobility[Us] += make_score(300, 300) * (mob - 2) / (10 + mob); // Penalty if the piece is far from the king score -= KingProtector[Pt - 2] * distance(s, pos.square(Us)); @@ -909,10 +912,9 @@ namespace { initialize(); // Pieces should be evaluated first (populate attack tables) - score += pieces() - pieces() - + pieces() - pieces() - + pieces() - pieces() - + pieces() - pieces(); + for (PieceType pt : pos.piece_types()) + if (pt != PAWN && pt != KING) + score += pieces(pt) - pieces(pt); score += mobility[WHITE] - mobility[BLACK]; diff --git a/src/position.h b/src/position.h index 5738427..1079764 100644 --- a/src/position.h +++ b/src/position.h @@ -89,9 +89,10 @@ public: const Variant* variant() const; Rank max_rank() const; File max_file() const; + const std::set& piece_types() const; const std::string piece_to_char() const; Rank promotion_rank() const; - const std::vector& promotion_piece_types() const; + const std::set >& promotion_piece_types() const; bool double_step_enabled() const; bool castling_enabled() const; bool checking_permitted() const; @@ -252,6 +253,11 @@ inline File Position::max_file() const { return var->maxFile; } +inline const std::set& Position::piece_types() const { + assert(var != nullptr); + return var->pieceTypes; +} + inline const std::string Position::piece_to_char() const { assert(var != nullptr); return var->pieceToChar; @@ -262,7 +268,7 @@ inline Rank Position::promotion_rank() const { return var->promotionRank; } -inline const std::vector& Position::promotion_piece_types() const { +inline const std::set >& Position::promotion_piece_types() const { assert(var != nullptr); return var->promotionPieceTypes; } diff --git a/src/variant.cpp b/src/variant.cpp index 1b1c86f..df0820e 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -27,19 +27,17 @@ using std::string; VariantMap variants; // Global object void VariantMap::init() { + // Define variant rules const Variant* chess = [&]{ Variant* v = new Variant(); return v; } (); const Variant* makruk = [&]{ Variant* v = new Variant(); - v->reset_pieces(); - v->set_piece(PAWN, 'p'); - v->set_piece(KNIGHT, 'n'); - v->set_piece(KHON, 's'); - v->set_piece(ROOK, 'r'); - v->set_piece(MET, 'm'); - v->set_piece(KING, 'k'); + v->remove_piece(BISHOP); + v->remove_piece(QUEEN); + v->add_piece(KHON, 's'); + v->add_piece(MET, 'm'); v->startFen = "rnsmksnr/8/pppppppp/8/8/PPPPPPPP/8/RNSKMSNR w - - 0 1"; v->promotionRank = RANK_6; v->promotionPieceTypes = {MET}; @@ -49,13 +47,10 @@ void VariantMap::init() { } (); const Variant* asean = [&]{ Variant* v = new Variant(); - v->reset_pieces(); - v->set_piece(PAWN, 'p'); - v->set_piece(KNIGHT, 'n'); - v->set_piece(KHON, 'b'); - v->set_piece(ROOK, 'r'); - v->set_piece(MET, 'q'); - v->set_piece(KING, 'k'); + v->remove_piece(BISHOP); + v->remove_piece(QUEEN); + v->add_piece(KHON, 'b'); + v->add_piece(MET, 'q'); v->startFen = "rnbqkbnr/8/pppppppp/8/8/PPPPPPPP/8/RNBQKBNR w - - 0 1"; v->promotionPieceTypes = {ROOK, KNIGHT, KHON, MET}; v->doubleStep = false; @@ -64,13 +59,10 @@ void VariantMap::init() { } (); const Variant* aiwok = [&]{ Variant* v = new Variant(); - v->reset_pieces(); - v->set_piece(PAWN, 'p'); - v->set_piece(KNIGHT, 'n'); - v->set_piece(KHON, 's'); - v->set_piece(ROOK, 'r'); - v->set_piece(AIWOK, 'a'); - v->set_piece(KING, 'k'); + v->remove_piece(BISHOP); + v->remove_piece(QUEEN); + v->add_piece(KHON, 's'); + v->add_piece(AIWOK, 'a'); v->startFen = "rnsaksnr/8/pppppppp/8/8/PPPPPPPP/8/RNSKASNR w - - 0 1"; v->promotionRank = RANK_6; v->promotionPieceTypes = {AIWOK}; @@ -80,13 +72,10 @@ void VariantMap::init() { } (); const Variant* shatranj = [&]{ Variant* v = new Variant(); - v->reset_pieces(); - v->set_piece(PAWN, 'p'); - v->set_piece(KNIGHT, 'n'); - v->set_piece(ALFIL, 'b'); - v->set_piece(ROOK, 'r'); - v->set_piece(FERS, 'q'); - v->set_piece(KING, 'k'); + v->remove_piece(BISHOP); + v->remove_piece(QUEEN); + v->add_piece(ALFIL, 'b'); + v->add_piece(FERS, 'q'); v->startFen = "rnbkqbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBKQBNR w - - 0 1"; v->promotionPieceTypes = {FERS}; v->doubleStep = false; @@ -98,18 +87,18 @@ void VariantMap::init() { } (); const Variant* amazon = [&]{ Variant* v = new Variant(); - v->set_piece(QUEEN, ' '); - v->set_piece(AMAZON, 'a'); + v->remove_piece(QUEEN); + v->add_piece(AMAZON, 'a'); v->startFen = "rnbakbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBAKBNR w KQkq - 0 1"; v->promotionPieceTypes = {AMAZON, ROOK, BISHOP, KNIGHT}; return v; } (); const Variant* hoppelpoppel = [&]{ Variant* v = new Variant(); - v->set_piece(KNIGHT, ' '); - v->set_piece(BISHOP, ' '); - v->set_piece(KNIBIS, 'n'); - v->set_piece(BISKNI, 'b'); + v->remove_piece(KNIGHT); + v->remove_piece(BISHOP); + v->add_piece(KNIBIS, 'n'); + v->add_piece(BISKNI, 'b'); v->promotionPieceTypes = {QUEEN, ROOK, BISKNI, KNIBIS}; return v; } (); @@ -167,12 +156,12 @@ void VariantMap::init() { const Variant* euroshogi = [&]{ Variant* v = new Variant(); v->reset_pieces(); - v->set_piece(SHOGI_PAWN, 'p'); - v->set_piece(EUROSHOGI_KNIGHT, 'n'); - v->set_piece(GOLD, 'g'); - v->set_piece(BISHOP, 'b'); - v->set_piece(ROOK, 'r'); - v->set_piece(KING, 'k'); + v->add_piece(SHOGI_PAWN, 'p'); + v->add_piece(EUROSHOGI_KNIGHT, 'n'); + v->add_piece(GOLD, 'g'); + v->add_piece(BISHOP, 'b'); + v->add_piece(ROOK, 'r'); + v->add_piece(KING, 'k'); v->startFen = "1nbgkgn1/1r4b1/pppppppp/8/8/PPPPPPPP/1B4R1/1NGKGBN1[-] w 0 1"; v->pieceDrops = true; v->promotionRank = RANK_6; @@ -187,12 +176,12 @@ void VariantMap::init() { v->maxRank = RANK_5; v->maxFile = FILE_E; v->reset_pieces(); - v->set_piece(SHOGI_PAWN, 'p'); - v->set_piece(SILVER, 's'); - v->set_piece(GOLD, 'g'); - v->set_piece(BISHOP, 'b'); - v->set_piece(ROOK, 'r'); - v->set_piece(KING, 'k'); + v->add_piece(SHOGI_PAWN, 'p'); + v->add_piece(SILVER, 's'); + v->add_piece(GOLD, 'g'); + v->add_piece(BISHOP, 'b'); + v->add_piece(ROOK, 'r'); + v->add_piece(KING, 'k'); v->startFen = "rbsgk/4p/5/P4/KGSBR[-] w 0 1"; v->pieceDrops = true; v->promotionRank = RANK_5; @@ -206,7 +195,7 @@ void VariantMap::init() { Variant* v = new Variant(); v->maxRank = RANK_6; v->maxFile = FILE_F; - v->set_piece(BISHOP, ' '); + v->remove_piece(BISHOP); v->startFen = "rnqknr/pppppp/6/6/PPPPPP/RNQKNR w - - 0 1"; v->promotionRank = RANK_6; v->promotionPieceTypes = {QUEEN, ROOK, KNIGHT}; @@ -214,28 +203,41 @@ void VariantMap::init() { 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)); - insert(std::pair(std::string("ai-wok"), aiwok)); - insert(std::pair(std::string("shatranj"), shatranj)); - insert(std::pair(std::string("amazon"), amazon)); - insert(std::pair(std::string("hoppelpoppel"), hoppelpoppel)); - insert(std::pair(std::string("kingofthehill"), kingofthehill)); - insert(std::pair(std::string("racingkings"), racingkings)); - insert(std::pair(std::string("losers"), losers)); - insert(std::pair(std::string("3check"), threecheck)); - insert(std::pair(std::string("5check"), fivecheck)); - 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("minishogi"), minishogi)); - insert(std::pair(std::string("losalamos"), losalamos)); + + // Add to UCI_Variant option + add("chess", chess); + add("standard", chess); + add("makruk", makruk); + add("asean", asean); + add("ai-wok", aiwok); + add("shatranj", shatranj); + add("amazon", amazon); + add("hoppelpoppel", hoppelpoppel); + add("kingofthehill", kingofthehill); + add("racingkings", racingkings); + add("losers", losers); + add("3check", threecheck); + add("5check", fivecheck); + add("crazyhouse", crazyhouse); + add("loop", loop); + add("euroshogi", euroshogi); + add("minishogi", minishogi); + add("losalamos", losalamos); +} + +void VariantMap::add(std::string s, const Variant* v) { + insert(std::pair(s, v)); } void VariantMap::clear_all() { + std::set deleted_vars; for (auto const& element : *this) { - delete element.second; + // Delete duplicated variants (synonyms) only once + if (deleted_vars.find(element.second) == deleted_vars.end()) + { + delete element.second; + deleted_vars.insert(element.second); + } } clear(); } diff --git a/src/variant.h b/src/variant.h index 9b313a2..82f695d 100644 --- a/src/variant.h +++ b/src/variant.h @@ -21,6 +21,7 @@ #ifndef VARIANT_H_INCLUDED #define VARIANT_H_INCLUDED +#include #include #include #include @@ -34,11 +35,12 @@ struct Variant { Rank maxRank = RANK_8; File maxFile = FILE_H; + std::set pieceTypes = { PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING }; 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"; Rank promotionRank = RANK_8; - std::vector promotionPieceTypes = {QUEEN, ROOK, BISHOP, KNIGHT}; + std::set > promotionPieceTypes = { QUEEN, ROOK, BISHOP, KNIGHT }; bool doubleStep = true; bool castling = true; bool checking = true; @@ -55,18 +57,27 @@ struct Variant { bool flagMove = false; CheckCount maxCheckCount = CheckCount(0); - void set_piece(PieceType pt, char c) { + void add_piece(PieceType pt, char c) { pieceToChar[make_piece(WHITE, pt)] = toupper(c); pieceToChar[make_piece(BLACK, pt)] = tolower(c); + pieceTypes.insert(pt); + } + + void remove_piece(PieceType pt) { + pieceToChar[make_piece(WHITE, pt)] = ' '; + pieceToChar[make_piece(BLACK, pt)] = ' '; + pieceTypes.erase(pt); } void reset_pieces() { pieceToChar = std::string(PIECE_NB, ' '); + pieceTypes.clear(); } }; struct VariantMap : public std::map { void init(); + void add(std::string s, const Variant* v); void clear_all(); std::vector get_keys(); };