From 86ae467afdf6a42558d5e99f1a18fba6677944c1 Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Mon, 10 Sep 2018 22:54:18 +0200 Subject: [PATCH] Support connect4 bench: 4832716 --- src/bitboard.cpp | 6 ++++++ src/bitboard.h | 11 +++++++++++ src/movegen.cpp | 3 +++ src/position.h | 28 ++++++++++++++++++++++++++++ src/psqt.cpp | 4 ++-- src/types.h | 3 ++- src/variant.cpp | 18 ++++++++++++++++++ src/variant.h | 2 ++ 8 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/bitboard.cpp b/src/bitboard.cpp index b92da2e..ec90623 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -175,6 +175,7 @@ void Bitboards::init() { { -8, -1, 1, 8 }, // horse { -8, -1, 1, 8 }, // clobber { 7, 9 }, // breakthrough + {}, // immobile { -9, -8, -7, -1, 1, 7, 8, 9 }, // commoner { -9, -8, -7, -1, 1, 7, 8, 9 } // king }; @@ -202,6 +203,7 @@ void Bitboards::init() { { -8, -1, 1, 8 }, // horse {}, // clobber { 7, 8, 9 }, // breakthrough + {}, // immobile { -9, -8, -7, -1, 1, 7, 8, 9 }, // commoner { -9, -8, -7, -1, 1, 7, 8, 9 } // king }; @@ -229,6 +231,7 @@ void Bitboards::init() { { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse {}, // clobber {}, // breakthrough + {}, // immobile {}, // commoner {} // king }; @@ -256,6 +259,7 @@ void Bitboards::init() { { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse {}, // clobber {}, // breakthrough + {}, // immobile {}, // commoner {} // king }; @@ -283,6 +287,7 @@ void Bitboards::init() { 7, // horse 0, // clobber 0, // breakthrough + 0, // immobile 0, // commoner 0 // king }; @@ -310,6 +315,7 @@ void Bitboards::init() { 7, // horse 0, // clobber 0, // breakthrough + 0, // immobile 0, // commoner 0 // king }; diff --git a/src/bitboard.h b/src/bitboard.h index cc2852c..9f3819d 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -199,6 +199,17 @@ constexpr Bitboard shift(Bitboard b) { } +/// shift() moves a bitboard one step along direction D (mainly for pawns) + +constexpr Bitboard shift(Direction D, Bitboard b) { + return D == NORTH ? b << 8 : D == SOUTH ? b >> 8 + : D == EAST ? (b & ~FileHBB) << 1 : D == WEST ? (b & ~FileABB) >> 1 + : D == NORTH_EAST ? (b & ~FileHBB) << 9 : D == NORTH_WEST ? (b & ~FileABB) << 7 + : D == SOUTH_EAST ? (b & ~FileHBB) >> 7 : D == SOUTH_WEST ? (b & ~FileABB) >> 9 + : 0; +} + + /// pawn_attacks_bb() returns the pawn attacks for the given color from the /// squares in the given bitboard. diff --git a/src/movegen.cpp b/src/movegen.cpp index 4f80959..17dad19 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -86,6 +86,9 @@ namespace { ExtMove* generate_drops(const Position& pos, ExtMove* moveList, PieceType pt, Bitboard b) { if (pos.count_in_hand(Us, pt)) { + // Consider only drops on top of already placed pieces + if (pos.drop_on_top()) + b &= shift(pos.pieces()) | Rank1BB; if (pt == PAWN) { b &= ~promotion_zone_bb(Us, pos.promotion_rank(), pos.max_rank()); diff --git a/src/position.h b/src/position.h index 8e5e9fd..680a1f1 100644 --- a/src/position.h +++ b/src/position.h @@ -108,6 +108,7 @@ public: bool drop_loop() const; bool captures_to_hand() const; bool first_rank_drops() const; + bool drop_on_top() const; bool immobility_illegal() const; // winning conditions Value stalemate_value(int ply = 0) const; @@ -120,6 +121,7 @@ public: Bitboard capture_the_flag(Color c) const; bool flag_move() const; CheckCount max_check_count() const; + int connect_n() const; CheckCount checks_given(Color c) const; bool is_variant_end() const; bool is_variant_end(Value& result, int ply = 0) const; @@ -354,6 +356,11 @@ inline bool Position::first_rank_drops() const { return var->firstRankDrops; } +inline bool Position::drop_on_top() const { + assert(var != nullptr); + return var->dropOnTop; +} + inline bool Position::immobility_illegal() const { assert(var != nullptr); return var->immobilityIllegal; @@ -421,6 +428,11 @@ inline CheckCount Position::max_check_count() const { return var->maxCheckCount; } +inline int Position::connect_n() const { + assert(var != nullptr); + return var->connectN; +} + inline CheckCount Position::checks_given(Color c) const { return st->checksGiven[c]; } @@ -477,6 +489,22 @@ inline bool Position::is_variant_end(Value& result, int ply) const { result = mated_in(ply); return true; } + // Connect-n + if (connect_n() > 0) + { + Bitboard b; + for (Direction d : {NORTH, NORTH_EAST, EAST, SOUTH_EAST}) + { + b = pieces(~sideToMove); + for (int i = 1; i < connect_n() && b; i++) + b &= shift(d, b); + if (b) + { + result = mated_in(ply); + return true; + } + } + } return false; } diff --git a/src/psqt.cpp b/src/psqt.cpp index ed6fbc9..33ab404 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, BreakthroughPieceValueMg, CommonerValueMg }, + ClobberPieceValueMg, BreakthroughPieceValueMg, ImmobilePieceValueMg, CommonerValueMg }, { VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg, FersValueEg, AlfilValueEg, SilverValueEg, AiwokValueEg, BersValueEg, ChancellorValueEg, AmazonValueEg, KnibisValueMg, BiskniValueMg, ShogiPawnValueEg, LanceValueEg, ShogiKnightValueEg, EuroShogiKnightValueEg, GoldValueEg, HorseValueEg, - ClobberPieceValueEg, BreakthroughPieceValueEg, CommonerValueEg } + ClobberPieceValueEg, BreakthroughPieceValueEg, ImmobilePieceValueEg, CommonerValueEg } }; namespace PSQT { diff --git a/src/types.h b/src/types.h index bdda9af..ecf1e05 100644 --- a/src/types.h +++ b/src/types.h @@ -213,6 +213,7 @@ enum Value : int { HorseValueMg = 1500, HorseValueEg = 1500, ClobberPieceValueMg = 300, ClobberPieceValueEg = 300, BreakthroughPieceValueMg = 300, BreakthroughPieceValueEg = 300, + ImmobilePieceValueMg = 100, ImmobilePieceValueEg = 100, CommonerValueMg = 600, CommonerValueEg = 600, MidgameLimit = 15258, EndgameLimit = 3915 @@ -224,7 +225,7 @@ 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, BREAKTHROUGH_PIECE, COMMONER, KING, + CLOBBER_PIECE, BREAKTHROUGH_PIECE, IMMOBILE_PIECE, COMMONER, KING, ALL_PIECES = 0, PIECE_TYPE_NB = 1 << PIECE_TYPE_BITS diff --git a/src/variant.cpp b/src/variant.cpp index 5903fb5..6fa1f9b 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -395,6 +395,23 @@ void VariantMap::init() { v->blackFlag = Rank1BB; return v; } (); + const Variant* connect4 = [&]{ + Variant* v = new Variant(); + v->maxRank = RANK_6; + v->maxFile = FILE_G; + v->reset_pieces(); + v->add_piece(IMMOBILE_PIECE, 'p'); + v->startFen = "7/7/7/7/7/7[PPPPPPPPPPPPPPPPPPPPPppppppppppppppppppppp] w 0 1"; + v->pieceDrops = true; + v->dropOnTop = true; + v->promotionPieceTypes = {}; + v->doubleStep = false; + v->castling = false; + v->stalemateValue = -VALUE_MATE; + v->immobilityIllegal = false; + v->connectN = 4; + return v; + } (); // Add to UCI_Variant option add("chess", chess); @@ -429,6 +446,7 @@ void VariantMap::init() { add("shatar", shatar); add("clobber", clobber); add("breakthrough", breakthrough); + add("connect4", connect4); } void VariantMap::add(std::string s, const Variant* v) { diff --git a/src/variant.h b/src/variant.h index c976588..a52196a 100644 --- a/src/variant.h +++ b/src/variant.h @@ -52,6 +52,7 @@ struct Variant { bool dropLoop = false; bool capturesToHand = false; bool firstRankDrops = false; + bool dropOnTop = false; bool immobilityIllegal = false; // game end Value stalemateValue = VALUE_DRAW; @@ -65,6 +66,7 @@ struct Variant { Bitboard blackFlag = 0; bool flagMove = false; CheckCount maxCheckCount = CheckCount(0); + int connectN = 0; void add_piece(PieceType pt, char c) { pieceToChar[make_piece(WHITE, pt)] = toupper(c); -- 1.7.0.4