From 0ef14f8bc1fe4e747bede6b64d45b313bc8a273a Mon Sep 17 00:00:00 2001 From: ianfab Date: Fri, 17 Aug 2018 20:31:23 +0200 Subject: [PATCH] Support breakthrough https://en.wikipedia.org/wiki/Breakthrough_(board_game) bench: 5016237 --- src/bitboard.cpp | 6 ++++++ src/evaluate.cpp | 20 +++++++++++++------- src/position.h | 14 ++++++++++++-- src/psqt.cpp | 4 ++-- src/types.h | 48 +++++++++++++++++++++++++----------------------- src/variant.cpp | 17 +++++++++++++++++ src/variant.h | 1 + 7 files changed, 76 insertions(+), 34 deletions(-) diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 8794578..b92da2e 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -174,6 +174,7 @@ void Bitboards::init() { { -8, -1, 1, 7, 8, 9 }, // gold { -8, -1, 1, 8 }, // horse { -8, -1, 1, 8 }, // clobber + { 7, 9 }, // breakthrough { -9, -8, -7, -1, 1, 7, 8, 9 }, // commoner { -9, -8, -7, -1, 1, 7, 8, 9 } // king }; @@ -200,6 +201,7 @@ void Bitboards::init() { { -8, -1, 1, 7, 8, 9 }, // gold { -8, -1, 1, 8 }, // horse {}, // clobber + { 7, 8, 9 }, // breakthrough { -9, -8, -7, -1, 1, 7, 8, 9 }, // commoner { -9, -8, -7, -1, 1, 7, 8, 9 } // king }; @@ -226,6 +228,7 @@ void Bitboards::init() { {}, // gold { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse {}, // clobber + {}, // breakthrough {}, // commoner {} // king }; @@ -252,6 +255,7 @@ void Bitboards::init() { {}, // gold { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse {}, // clobber + {}, // breakthrough {}, // commoner {} // king }; @@ -278,6 +282,7 @@ void Bitboards::init() { 0, // gold 7, // horse 0, // clobber + 0, // breakthrough 0, // commoner 0 // king }; @@ -304,6 +309,7 @@ void Bitboards::init() { 0, // gold 7, // horse 0, // clobber + 0, // breakthrough 0, // commoner 0 // king }; diff --git a/src/evaluate.cpp b/src/evaluate.cpp index b9ffc8d..52c12d8 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -808,14 +808,20 @@ namespace { // Capture the flag if (pos.capture_the_flag(Us)) { - Bitboard target_squares = pos.capture_the_flag(Us); - while (target_squares) + bool can_block = pos.capture_the_flag_piece() == KING; + Bitboard ctfPieces = pos.pieces(Us, pos.capture_the_flag_piece()); + while (ctfPieces) { - Square s = pop_lsb(&target_squares); - int dist = distance(pos.square(Us), s) - + popcount(pos.attackers_to(s) & pos.pieces(Them)) - + !!(pos.pieces(Us) & s); - score += make_score(3000, 3000) / (1 + dist * (pos.checking_permitted() ? dist : 1)); + Square s1 = pop_lsb(&ctfPieces); + Bitboard target_squares = pos.capture_the_flag(Us); + while (target_squares) + { + Square s2 = pop_lsb(&target_squares); + int dist = distance(s1, s2) + + (can_block ? popcount(pos.attackers_to(s2) & pos.pieces(Them)) : 0) + + !!(pos.pieces(Us) & s2); + score += make_score(3000, 3000) / (1 + dist * (can_block && pos.checking_permitted() ? dist : 1)); + } } } diff --git a/src/position.h b/src/position.h index 7656a31..8e5e9fd 100644 --- a/src/position.h +++ b/src/position.h @@ -116,6 +116,7 @@ public: Value extinction_value(int ply = 0) const; bool bare_king_move() const; const std::set& extinction_piece_types() const; + PieceType capture_the_flag_piece() const; Bitboard capture_the_flag(Color c) const; bool flag_move() const; CheckCount max_check_count() const; @@ -400,6 +401,11 @@ inline const std::set& Position::extinction_piece_types() const { return var->extinctionPieceTypes; } +inline PieceType Position::capture_the_flag_piece() const { + assert(var != nullptr); + return var->flagPiece; +} + inline Bitboard Position::capture_the_flag(Color c) const { assert(var != nullptr); return c == WHITE ? var->whiteFlag : var->blackFlag; @@ -451,12 +457,16 @@ inline bool Position::is_variant_end(Value& result, int ply) const { } } // capture the flag - if (count(~sideToMove) && !flag_move() && (capture_the_flag(~sideToMove) & square(~sideToMove))) + if ( capture_the_flag_piece() + && !flag_move() + && (capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece()))) { result = mated_in(ply); return true; } - if (count( sideToMove) && flag_move() && (capture_the_flag( sideToMove) & square( sideToMove))) + if ( capture_the_flag_piece() + && flag_move() + && (capture_the_flag(sideToMove) & pieces(sideToMove, capture_the_flag_piece()))) { result = mate_in(ply); return true; diff --git a/src/psqt.cpp b/src/psqt.cpp index ae390a7..ed6fbc9 100644 --- a/src/psqt.cpp +++ b/src/psqt.cpp @@ -27,12 +27,12 @@ Value PieceValue[PHASE_NB][PIECE_NB] = { FersValueMg, AlfilValueMg, SilverValueMg, AiwokValueMg, BersValueMg, ChancellorValueMg, AmazonValueMg, KnibisValueMg, BiskniValueMg, ShogiPawnValueMg, LanceValueMg, ShogiKnightValueMg, EuroShogiKnightValueMg, GoldValueMg, HorseValueMg, - ClobberPieceValueMg, CommonerValueMg }, + ClobberPieceValueMg, BreakthroughPieceValueMg, CommonerValueMg }, { VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg, FersValueEg, AlfilValueEg, SilverValueEg, AiwokValueEg, BersValueEg, ChancellorValueEg, AmazonValueEg, KnibisValueMg, BiskniValueMg, ShogiPawnValueEg, LanceValueEg, ShogiKnightValueEg, EuroShogiKnightValueEg, GoldValueEg, HorseValueEg, - ClobberPieceValueEg, CommonerValueEg } + ClobberPieceValueEg, BreakthroughPieceValueEg, CommonerValueEg } }; namespace PSQT { diff --git a/src/types.h b/src/types.h index 66874ac..bdda9af 100644 --- a/src/types.h +++ b/src/types.h @@ -191,28 +191,29 @@ enum Value : int { VALUE_MATE_IN_MAX_PLY = VALUE_MATE - 2 * MAX_PLY, VALUE_MATED_IN_MAX_PLY = -VALUE_MATE + 2 * MAX_PLY, - PawnValueMg = 171, PawnValueEg = 240, - KnightValueMg = 764, KnightValueEg = 848, - BishopValueMg = 826, BishopValueEg = 891, - RookValueMg = 1282, RookValueEg = 1373, - QueenValueMg = 2500, QueenValueEg = 2670, - FersValueMg = 400, FersValueEg = 400, - AlfilValueMg = 300, AlfilValueEg = 300, - SilverValueMg = 600, SilverValueEg = 600, - AiwokValueMg = 2500, AiwokValueEg = 2500, - BersValueMg = 2000, BersValueEg = 2000, - ChancellorValueMg = 2500, ChancellorValueEg = 2500, - AmazonValueMg = 3000, AmazonValueEg = 3000, - KnibisValueMg = 800, KnibisValueEg = 800, - BiskniValueMg = 800, BiskniValueEg = 800, - ShogiPawnValueMg = 100, ShogiPawnValueEg = 100, - LanceValueMg = 300, LanceValueEg = 300, - ShogiKnightValueMg = 300, ShogiKnightValueEg = 300, - EuroShogiKnightValueMg = 400, EuroShogiKnightValueEg = 400, - GoldValueMg = 600, GoldValueEg = 600, - HorseValueMg = 1500, HorseValueEg = 1500, - ClobberPieceValueMg = 300, ClobberPieceValueEg = 300, - CommonerValueMg = 600, CommonerValueEg = 600, + PawnValueMg = 171, PawnValueEg = 240, + KnightValueMg = 764, KnightValueEg = 848, + BishopValueMg = 826, BishopValueEg = 891, + RookValueMg = 1282, RookValueEg = 1373, + QueenValueMg = 2500, QueenValueEg = 2670, + FersValueMg = 400, FersValueEg = 400, + AlfilValueMg = 300, AlfilValueEg = 300, + SilverValueMg = 600, SilverValueEg = 600, + AiwokValueMg = 2500, AiwokValueEg = 2500, + BersValueMg = 2000, BersValueEg = 2000, + ChancellorValueMg = 2500, ChancellorValueEg = 2500, + AmazonValueMg = 3000, AmazonValueEg = 3000, + KnibisValueMg = 800, KnibisValueEg = 800, + BiskniValueMg = 800, BiskniValueEg = 800, + ShogiPawnValueMg = 100, ShogiPawnValueEg = 100, + LanceValueMg = 300, LanceValueEg = 300, + ShogiKnightValueMg = 300, ShogiKnightValueEg = 300, + EuroShogiKnightValueMg = 400, EuroShogiKnightValueEg = 400, + GoldValueMg = 600, GoldValueEg = 600, + HorseValueMg = 1500, HorseValueEg = 1500, + ClobberPieceValueMg = 300, ClobberPieceValueEg = 300, + BreakthroughPieceValueMg = 300, BreakthroughPieceValueEg = 300, + CommonerValueMg = 600, CommonerValueEg = 600, MidgameLimit = 15258, EndgameLimit = 3915 }; @@ -222,7 +223,8 @@ const int PIECE_TYPE_BITS = 5; // PIECE_TYPE_NB = pow(2, PIECE_TYPE_BITS) enum PieceType { NO_PIECE_TYPE, PAWN, KNIGHT, BISHOP, ROOK, QUEEN, FERS, MET = FERS, ALFIL, SILVER, KHON = SILVER, AIWOK, BERS, DRAGON = BERS, CHANCELLOR, - AMAZON, KNIBIS, BISKNI, SHOGI_PAWN, LANCE, SHOGI_KNIGHT, EUROSHOGI_KNIGHT, GOLD, HORSE, CLOBBER_PIECE, COMMONER, KING, + AMAZON, KNIBIS, BISKNI, SHOGI_PAWN, LANCE, SHOGI_KNIGHT, EUROSHOGI_KNIGHT, GOLD, HORSE, + CLOBBER_PIECE, BREAKTHROUGH_PIECE, COMMONER, KING, ALL_PIECES = 0, PIECE_TYPE_NB = 1 << PIECE_TYPE_BITS diff --git a/src/variant.cpp b/src/variant.cpp index f2e7e11..216b73f 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -109,6 +109,7 @@ void VariantMap::init() { } (); const Variant* kingofthehill = [&]{ Variant* v = new Variant(); + v->flagPiece = KING; v->whiteFlag = make_bitboard(SQ_D4, SQ_E4, SQ_D5, SQ_E5); v->blackFlag = make_bitboard(SQ_D4, SQ_E4, SQ_D5, SQ_E5); v->flagMove = false; @@ -117,6 +118,7 @@ void VariantMap::init() { const Variant* racingkings = [&]{ Variant* v = new Variant(); v->startFen = "8/8/8/8/8/8/krbnNBRK/qrbnNBRQ w - - 0 1"; + v->flagPiece = KING; v->whiteFlag = Rank8BB; v->blackFlag = Rank8BB; v->flagMove = true; @@ -368,6 +370,20 @@ void VariantMap::init() { v->immobilityIllegal = false; return v; } (); + const Variant* breakthrough = [&]{ + Variant* v = new Variant(); + v->reset_pieces(); + v->add_piece(BREAKTHROUGH_PIECE, 'p'); + v->startFen = "pppppppp/pppppppp/8/8/8/8/PPPPPPPP/PPPPPPPP w 0 1"; + v->promotionPieceTypes = {}; + v->firstRankDoubleSteps = false; + v->castling = false; + v->stalemateValue = -VALUE_MATE; + v->flagPiece = BREAKTHROUGH_PIECE; + v->whiteFlag = Rank8BB; + v->blackFlag = Rank1BB; + return v; + } (); // Add to UCI_Variant option add("chess", chess); @@ -400,6 +416,7 @@ void VariantMap::init() { add("chigorin", chigorin); add("shatar", shatar); add("clobber", clobber); + add("breakthrough", breakthrough); } void VariantMap::add(std::string s, const Variant* v) { diff --git a/src/variant.h b/src/variant.h index 6126673..c976588 100644 --- a/src/variant.h +++ b/src/variant.h @@ -60,6 +60,7 @@ struct Variant { Value extinctionValue = VALUE_NONE; bool bareKingMove = false; std::set extinctionPieceTypes = {}; + PieceType flagPiece = NO_PIECE_TYPE; Bitboard whiteFlag = 0; Bitboard blackFlag = 0; bool flagMove = false; -- 1.7.0.4