From: Fabian Fichter Date: Fri, 15 May 2020 15:27:42 +0000 (+0200) Subject: Separate bikjang and material counting X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=fab32da2e2443f4a11890a172c4d3b6ce82fba9e;p=fairystockfish.git Separate bikjang and material counting Closes #115. --- diff --git a/src/parser.cpp b/src/parser.cpp index 0bfd656..f814862 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -75,6 +75,13 @@ namespace { return value == "win" || value == "loss" || value == "draw" || value == "none"; } + template <> bool set(const std::string& value, MaterialCounting& target) { + target = value == "janggi" ? JANGGI_MATERIAL + : value == "unweighted" ? UNWEIGHTED_MATERIAL + : NO_MATERIAL_COUNTING; + return value == "janggi" || value == "unweighted" || value == "none"; + } + template <> bool set(const std::string& value, CountingRule& target) { target = value == "makruk" ? MAKRUK_COUNTING : value == "asean" ? ASEAN_COUNTING @@ -107,6 +114,7 @@ template void VariantParser::parse_attribute(const std::strin : std::is_same() ? "File" : std::is_same() ? "bool" : std::is_same() ? "Value" + : std::is_same() ? "MaterialCounting" : std::is_same() ? "CountingRule" : std::is_same() ? "Bitboard" : typeid(T).name(); @@ -267,7 +275,7 @@ Variant* VariantParser::parse(Variant* v) { parse_attribute("checkmateValue", v->checkmateValue); parse_attribute("shogiPawnDropMateIllegal", v->shogiPawnDropMateIllegal); parse_attribute("shatarMateRule", v->shatarMateRule); - parse_attribute("bikjangValue", v->bikjangValue); + parse_attribute("bikjangRule", v->bikjangRule); parse_attribute("bareKingValue", v->bareKingValue); parse_attribute("extinctionValue", v->extinctionValue); parse_attribute("bareKingMove", v->bareKingMove); @@ -292,6 +300,7 @@ Variant* VariantParser::parse(Variant* v) { parse_attribute("flagMove", v->flagMove); parse_attribute("checkCounting", v->checkCounting); parse_attribute("connectN", v->connectN); + parse_attribute("materialCounting", v->materialCounting); parse_attribute("countingRule", v->countingRule); // Report invalid options if (DoCheck) diff --git a/src/position.cpp b/src/position.cpp index c74f933..ac0d71e 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -499,7 +499,7 @@ void Position::set_check_info(StateInfo* si) const { si->checkSquares[pt] = ksq != SQ_NONE ? attacks_bb(~sideToMove, pt, ksq, pieces()) : Bitboard(0); si->checkSquares[KING] = 0; si->shak = si->checkersBB & (byTypeBB[KNIGHT] | byTypeBB[ROOK] | byTypeBB[BERS]); - si->bikjang = var->bikjangValue != VALUE_NONE && ksq != SQ_NONE ? bool(attacks_bb(sideToMove, ROOK, ksq, pieces()) & pieces(sideToMove, KING)) : false; + si->bikjang = var->bikjangRule && ksq != SQ_NONE ? bool(attacks_bb(sideToMove, ROOK, ksq, pieces()) & pieces(sideToMove, KING)) : false; } @@ -1961,21 +1961,12 @@ bool Position::is_immediate_game_end(Value& result, int ply) const { } } } - // Check for bikjang rule (Janggi) - if (var->bikjangValue != VALUE_NONE && st->pliesFromNull > 0 && ( (st->bikjang && st->previous->bikjang) - || (st->pass && st->previous->pass))) - { - // material counting - auto weigth_count = [this](PieceType pt, int v){ return v * (count(WHITE, pt) - count(BLACK, pt)); }; - int materialCount = weigth_count(ROOK, 13) - + weigth_count(JANGGI_CANNON, 7) - + weigth_count(HORSE, 5) - + weigth_count(JANGGI_ELEPHANT, 3) - + weigth_count(WAZIR, 3) - + weigth_count(SOLDIER, 2) - - 1; - bool stmUpMaterial = (sideToMove == WHITE) == (materialCount > 0); - result = convert_mate_value(stmUpMaterial ? var->bikjangValue : -var->bikjangValue, ply); + // Check for bikjang rule (Janggi) and double passing + if (st->pliesFromNull > 0 && ((st->bikjang && st->previous->bikjang) || (st->pass && st->previous->pass))) + { + result = var->materialCounting ? convert_mate_value(sideToMove == WHITE ? material_counting_result() + : -material_counting_result(), ply) + : VALUE_DRAW; return true; } // Tsume mode: Assume that side with king wins when not in check diff --git a/src/position.h b/src/position.h index 28d4aaa..4254f14 100644 --- a/src/position.h +++ b/src/position.h @@ -164,6 +164,7 @@ public: bool check_counting() const; int connect_n() const; CheckCount checks_remaining(Color c) const; + MaterialCounting material_counting() const; CountingRule counting_rule() const; // Variant-specific properties @@ -256,6 +257,7 @@ public: bool is_game_end(Value& result, int ply = 0) const; bool is_optional_game_end(Value& result, int ply = 0, int countStarted = 0) const; bool is_immediate_game_end(Value& result, int ply = 0) const; + Value material_counting_result() const; bool has_game_cycle(int ply) const; bool has_repeated() const; int counting_limit() const; @@ -718,6 +720,11 @@ inline CheckCount Position::checks_remaining(Color c) const { return st->checksRemaining[c]; } +inline MaterialCounting Position::material_counting() const { + assert(var != nullptr); + return var->materialCounting; +} + inline CountingRule Position::counting_rule() const { assert(var != nullptr); return var->countingRule; @@ -1081,6 +1088,30 @@ inline bool Position::bikjang() const { return st->bikjang; } +inline Value Position::material_counting_result() const { + auto weigth_count = [this](PieceType pt, int v){ return v * (count(WHITE, pt) - count(BLACK, pt)); }; + int materialCount; + switch (var->materialCounting) + { + case JANGGI_MATERIAL: + materialCount = weigth_count(ROOK, 13) + + weigth_count(JANGGI_CANNON, 7) + + weigth_count(HORSE, 5) + + weigth_count(JANGGI_ELEPHANT, 3) + + weigth_count(WAZIR, 3) + + weigth_count(SOLDIER, 2) + - 1; + return materialCount > 0 ? VALUE_MATE : -VALUE_MATE; + case UNWEIGHTED_MATERIAL: + return count(WHITE, ALL_PIECES) > count(BLACK, ALL_PIECES) ? VALUE_MATE + : count(WHITE, ALL_PIECES) < count(BLACK, ALL_PIECES) ? -VALUE_MATE + : VALUE_DRAW; + default: + assert(false); + return VALUE_DRAW; + } +} + inline void Position::add_to_hand(Piece pc) { pieceCountInHand[color_of(pc)][type_of(pc)]++; pieceCountInHand[color_of(pc)][ALL_PIECES]++; diff --git a/src/types.h b/src/types.h index a17be28..31a97ae 100644 --- a/src/types.h +++ b/src/types.h @@ -274,6 +274,10 @@ enum CheckCount : int { CHECKS_0 = 0, CHECKS_NB = 11 }; +enum MaterialCounting { + NO_MATERIAL_COUNTING, JANGGI_MATERIAL, UNWEIGHTED_MATERIAL +}; + enum CountingRule { NO_COUNTING, MAKRUK_COUNTING, ASEAN_COUNTING }; @@ -700,7 +704,7 @@ inline bool is_gating(Move m) { } inline bool is_pass(Move m) { - return type_of(m) == SPECIAL || from_sq(m) == to_sq(m); + return type_of(m) == SPECIAL && from_sq(m) == to_sq(m); } constexpr Move make_move(Square from, Square to) { diff --git a/src/variant.cpp b/src/variant.cpp index 8e0b517..621cfe0 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -872,7 +872,8 @@ namespace { v->mobilityRegion[BLACK][WAZIR] = black_castle; v->soldierPromotionRank = RANK_1; v->flyingGeneral = false; - v->bikjangValue = VALUE_MATE; + v->bikjangRule = true; + v->materialCounting = JANGGI_MATERIAL; v->diagonalLines = make_bitboard(SQ_D1, SQ_F1, SQ_E2, SQ_D3, SQ_F3, SQ_D8, SQ_F8, SQ_E9, SQ_D10, SQ_F10); v->kingPass = true; @@ -883,13 +884,15 @@ namespace { // Traditional rules of Janggi, where bikjang is a draw Variant* janggi_traditional_variant() { Variant* v = janggi_variant(); - v->bikjangValue = VALUE_DRAW; + v->bikjangRule = true; + v->materialCounting = NO_MATERIAL_COUNTING; return v; } // Casual rules of Janggi, where bikjang is not considered Variant* janggi_casual_variant() { Variant* v = janggi_variant(); - v->bikjangValue = VALUE_NONE; + v->bikjangRule = false; + v->materialCounting = JANGGI_MATERIAL; return v; } #endif diff --git a/src/variant.h b/src/variant.h index dfcf556..d9191f7 100644 --- a/src/variant.h +++ b/src/variant.h @@ -103,7 +103,7 @@ struct Variant { Value checkmateValue = -VALUE_MATE; bool shogiPawnDropMateIllegal = false; bool shatarMateRule = false; - Value bikjangValue = VALUE_NONE; + bool bikjangRule = false; Value bareKingValue = VALUE_NONE; Value extinctionValue = VALUE_NONE; bool bareKingMove = false; @@ -116,6 +116,7 @@ struct Variant { bool flagMove = false; bool checkCounting = false; int connectN = 0; + MaterialCounting materialCounting = NO_MATERIAL_COUNTING; CountingRule countingRule = NO_COUNTING; void add_piece(PieceType pt, char c, char c2 = ' ') { diff --git a/src/variants.ini b/src/variants.ini index 815e140..99448e6 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -93,6 +93,7 @@ # [PieceType]: a piece type [letters defined for pieces, e.g., p] # [Bitboard]: list of squares [e.g., d4 e4 d5 e5]. * can be used as wildcard for files (e.g., *1 is the first rank) # [Value]: game result for the side to move [win, loss, draw] +# [MaterialCounting]: material couting rules for adjudication [janggi, unweighted, none] # [CountingRule]: makruk or ASEAN counting rules [makruk, asean, none] ### Rule definition options @@ -162,7 +163,7 @@ # checkmateValue: result in case of checkmate [Value] (default: loss) # shogiPawnDropMateIllegal: prohibit checkmate via shogi pawn drops [bool] (default: false) # shatarMateRule: enable shatar mating rules [bool] (default: false) -# bikjangValue: result in case of Janggi bikjang (facing kings) for the player with more points [Value] (default: none) +# bikjangRule: consider Janggi bikjang (facing kings) rule [bool] (default: false) # bareKingValue: result when player only has a lone/bare king [Value] (default: none) # extinctionValue: result when one of extinctionPieceTypes is extinct [Value] (default: none) # bareKingMove: allow additional move by opponent after lone/bare king position [bool] (default: false) @@ -175,6 +176,7 @@ # flagMove: black gets one more move after white captures the flag [bool] (default: false) # checkCounting: enable check count win rule (check count is communicated via FEN, see 3check) [bool] (default: false) # connectN: number of aligned pieces for win [int] (default: 0) +# materialCounting: enable material counting rules [MaterialCounting] (default: none) # countingRule: enable counting rules [CountingRule] (default: none) ################################################