From 082893d61333b5c7776a7945067fcf074e590c5d Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Thu, 6 Aug 2020 22:25:52 +0200 Subject: [PATCH] Support Ataxx https://en.wikipedia.org/wiki/Ataxx bench: 5499014 --- src/evaluate.cpp | 30 +++++++++++------ src/parser.cpp | 7 ++++ src/piece.cpp | 10 ++++++ src/position.cpp | 95 +++++++++++++++++++++++++++++------------------------ src/position.h | 40 +++++++++++++++-------- src/psqt.cpp | 2 +- src/types.h | 23 ++++++++----- src/variant.cpp | 22 ++++++++++++ src/variant.h | 4 +- src/variants.ini | 10 +++-- tests/perft.sh | 2 + 11 files changed, 161 insertions(+), 84 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 9be2f55..f155c04 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -1010,15 +1010,18 @@ namespace { if (pos.flip_enclosed_pieces()) { // Stable pieces - Bitboard edges = (FileABB | file_bb(pos.max_file()) | Rank1BB | rank_bb(pos.max_rank())) & pos.board_bb(); - Bitboard edgePieces = pos.pieces(Us) & edges; - while (edgePieces) + if (pos.flip_enclosed_pieces() == REVERSI) { - Bitboard connectedEdge = attacks_bb(Us, ROOK, pop_lsb(&edgePieces), ~(pos.pieces(Us) & edges)) & edges; - if (!more_than_one(connectedEdge & ~pos.pieces(Us))) - score += make_score(300, 300); - else if (!(connectedEdge & ~pos.pieces())) - score += make_score(200, 200); + Bitboard edges = (FileABB | file_bb(pos.max_file()) | Rank1BB | rank_bb(pos.max_rank())) & pos.board_bb(); + Bitboard edgePieces = pos.pieces(Us) & edges; + while (edgePieces) + { + Bitboard connectedEdge = attacks_bb(Us, ROOK, pop_lsb(&edgePieces), ~(pos.pieces(Us) & edges)) & edges; + if (!more_than_one(connectedEdge & ~pos.pieces(Us))) + score += make_score(300, 300); + else if (!(connectedEdge & ~pos.pieces())) + score += make_score(200, 200); + } } // Unstable @@ -1027,9 +1030,14 @@ namespace { while (drops) { Square s = pop_lsb(&drops); - Bitboard b = attacks_bb(Them, QUEEN, s, ~pos.pieces(Us)) & ~PseudoAttacks[Them][KING][s] & pos.pieces(Them); - while(b) - unstable |= between_bb(s, pop_lsb(&b)); + if (pos.flip_enclosed_pieces() == REVERSI) + { + Bitboard b = attacks_bb(Them, QUEEN, s, ~pos.pieces(Us)) & ~PseudoAttacks[Them][KING][s] & pos.pieces(Them); + while(b) + unstable |= between_bb(s, pop_lsb(&b)); + } + else + unstable |= PseudoAttacks[Them][KING][s] & pos.pieces(Us); } score -= make_score(200, 200) * popcount(unstable); } diff --git a/src/parser.cpp b/src/parser.cpp index dca83f8..405487f 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -92,6 +92,13 @@ namespace { return value == "makruk" || value == "asean" || value == "none"; } + template <> bool set(const std::string& value, EnclosingRule& target) { + target = value == "reversi" ? REVERSI + : value == "ataxx" ? ATAXX + : NO_ENCLOSING; + return value == "reversi" || value == "ataxx" || value == "none"; + } + template <> bool set(const std::string& value, Bitboard& target) { char file; int rank; diff --git a/src/piece.cpp b/src/piece.cpp index f37333e..63344d5 100644 --- a/src/piece.cpp +++ b/src/piece.cpp @@ -290,6 +290,15 @@ namespace { p->name = "immobile"; return p; } + PieceInfo* ataxx_piece() { + PieceInfo* p = new PieceInfo(); + p->name = "ataxx"; + p->betza = "mDNA"; + p->stepsQuiet = {2 * NORTH_WEST, 2 * NORTH + WEST, 2 * NORTH, 2 * NORTH + EAST, 2 * NORTH_EAST, + NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * WEST, 2 * EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST, + 2 * SOUTH_WEST, 2 * SOUTH + WEST, 2 * SOUTH, 2 * SOUTH + EAST, 2 * SOUTH_EAST}; + return p; + } PieceInfo* cannon_piece() { PieceInfo* p = new PieceInfo(); p->name = "cannon"; @@ -393,6 +402,7 @@ void PieceMap::init() { add(CLOBBER_PIECE, clobber_piece()); add(BREAKTHROUGH_PIECE, breakthrough_piece()); add(IMMOBILE_PIECE, immobile_piece()); + add(ATAXX_PIECE, ataxx_piece()); add(CANNON, cannon_piece()); add(JANGGI_CANNON, janggi_cannon_piece()); add(SOLDIER, soldier_piece()); diff --git a/src/position.cpp b/src/position.cpp index db17d95..706c587 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1314,6 +1314,45 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { st->castlingRights &= ~cr; } + // Flip enclosed pieces + st->flippedPieces = 0; + if (flip_enclosed_pieces() && !is_pass(m)) + { + // Find end of rows to be flipped + if (flip_enclosed_pieces() == REVERSI) + { + Bitboard b = attacks_bb(us, QUEEN, to, board_bb() & ~pieces(~us)) & ~PseudoAttacks[us][KING][to] & pieces(us); + while(b) + st->flippedPieces |= between_bb(to, pop_lsb(&b)); + } + else + { + assert(flip_enclosed_pieces() == ATAXX); + st->flippedPieces = PseudoAttacks[us][KING][to] & pieces(~us); + } + + // Flip pieces + Bitboard to_flip = st->flippedPieces; + while(to_flip) + { + Square s = pop_lsb(&to_flip); + Piece flipped = piece_on(s); + Piece resulting = ~flipped; + + // remove opponent's piece + remove_piece(s); + k ^= Zobrist::psq[flipped][s]; + st->materialKey ^= Zobrist::psq[flipped][pieceCount[flipped]]; + st->nonPawnMaterial[them] -= PieceValue[MG][flipped]; + + // add our piece + put_piece(resulting, s); + k ^= Zobrist::psq[resulting][s]; + st->materialKey ^= Zobrist::psq[resulting][pieceCount[resulting]-1]; + st->nonPawnMaterial[us] += PieceValue[MG][resulting]; + } + } + // Move the piece. The tricky Chess960 castling is handled earlier if (type_of(m) == DROP) { @@ -1339,35 +1378,6 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { set_castling_right(us, to); } } - // Flip enclosed pieces - if (flip_enclosed_pieces()) - { - st->flippedPieces = 0; - // Find end of rows to be flipped - Bitboard b = attacks_bb(us, QUEEN, to, board_bb() & ~pieces(~us)) & ~PseudoAttacks[us][KING][to] & pieces(us); - while(b) - st->flippedPieces |= between_bb(to, pop_lsb(&b)); - // Flip pieces - Bitboard to_flip = st->flippedPieces; - while(to_flip) - { - Square s = pop_lsb(&to_flip); - Piece flipped = piece_on(s); - Piece resulting = ~flipped; - - // remove opponent's piece - remove_piece(s); - k ^= Zobrist::psq[flipped][s]; - st->materialKey ^= Zobrist::psq[flipped][pieceCount[flipped]]; - st->nonPawnMaterial[them] -= PieceValue[MG][flipped]; - - // add our piece - put_piece(resulting, s); - k ^= Zobrist::psq[resulting][s]; - st->materialKey ^= Zobrist::psq[resulting][pieceCount[resulting]-1]; - st->nonPawnMaterial[us] += PieceValue[MG][resulting]; - } - } } else if (type_of(m) != CASTLING) move_piece(from, to); @@ -1572,21 +1582,7 @@ void Position::undo_move(Move m) { else { if (type_of(m) == DROP) - { - if (flip_enclosed_pieces()) - { - // Flip pieces - Bitboard to_flip = st->flippedPieces; - while(to_flip) - { - Square s = pop_lsb(&to_flip); - Piece resulting = ~piece_on(s); - remove_piece(s); - put_piece(resulting, s); - } - } undrop_piece(make_piece(us, in_hand_piece_type(m)), to); // Remove the dropped piece - } else move_piece(to, from); // Put the piece back at the source square @@ -1613,6 +1609,19 @@ void Position::undo_move(Move m) { } } + if (flip_enclosed_pieces()) + { + // Flip pieces + Bitboard to_flip = st->flippedPieces; + while(to_flip) + { + Square s = pop_lsb(&to_flip); + Piece resulting = ~piece_on(s); + remove_piece(s); + put_piece(resulting, s); + } + } + // Finally point our state pointer back to the previous state st = st->previous; --gamePly; diff --git a/src/position.h b/src/position.h index 4446b08..ad6b854 100644 --- a/src/position.h +++ b/src/position.h @@ -133,7 +133,7 @@ public: bool captures_to_hand() const; bool first_rank_pawn_drops() const; bool drop_on_top() const; - bool enclosing_drop() const; + EnclosingRule enclosing_drop() const; Bitboard drop_region(Color c) const; Bitboard drop_region(Color c, PieceType pt) const; bool sittuyin_rook_drop() const; @@ -149,7 +149,7 @@ public: bool pass_on_stalemate() const; Bitboard promoted_soldiers(Color c) const; bool makpong() const; - bool flip_enclosed_pieces() const; + EnclosingRule flip_enclosed_pieces() const; // winning conditions int n_move_rule() const; int n_fold_rule() const; @@ -511,7 +511,7 @@ inline bool Position::drop_on_top() const { return var->dropOnTop; } -inline bool Position::enclosing_drop() const { +inline EnclosingRule Position::enclosing_drop() const { assert(var != nullptr); return var->enclosingDrop; } @@ -552,17 +552,29 @@ inline Bitboard Position::drop_region(Color c, PieceType pt) const { b &= var->enclosingDropStart; else { - Bitboard theirs = pieces(~c); - b &= shift(theirs) | shift(theirs) - | shift(theirs) | shift(theirs) - | shift(theirs) | shift(theirs) - | shift(theirs) | shift(theirs); - Bitboard b2 = b; - while (b2) + if (enclosing_drop() == REVERSI) { - Square s = pop_lsb(&b2); - if (!(attacks_bb(c, QUEEN, s, board_bb() & ~pieces(~c)) & ~PseudoAttacks[c][KING][s] & pieces(c))) - b ^= s; + Bitboard theirs = pieces(~c); + b &= shift(theirs) | shift(theirs) + | shift(theirs) | shift(theirs) + | shift(theirs) | shift(theirs) + | shift(theirs) | shift(theirs); + Bitboard b2 = b; + while (b2) + { + Square s = pop_lsb(&b2); + if (!(attacks_bb(c, QUEEN, s, board_bb() & ~pieces(~c)) & ~PseudoAttacks[c][KING][s] & pieces(c))) + b ^= s; + } + } + else + { + assert(enclosing_drop() == ATAXX); + Bitboard ours = pieces(c); + b &= shift(ours) | shift(ours) + | shift(ours) | shift(ours) + | shift(ours) | shift(ours) + | shift(ours) | shift(ours); } } } @@ -645,7 +657,7 @@ inline int Position::n_fold_rule() const { return var->nFoldRule; } -inline bool Position::flip_enclosed_pieces() const { +inline EnclosingRule Position::flip_enclosed_pieces() const { assert(var != nullptr); return var->flipEnclosedPieces; } diff --git a/src/psqt.cpp b/src/psqt.cpp index 2c8aabf..f853dbf 100644 --- a/src/psqt.cpp +++ b/src/psqt.cpp @@ -190,7 +190,7 @@ void init(const Variant* v) { : make_score(10, 10) * (1 + isSlowLeaper) * (f + std::max(std::min(r, Rank(v->maxRank - r)), RANK_1) - v->maxFile / 2)); if (pt == SOLDIER && r < v->soldierPromotionRank) psq[pc][s] -= score * (v->soldierPromotionRank - r) / (4 + f); - if (v->enclosingDrop) + if (v->enclosingDrop == REVERSI) { if (f == FILE_A && (r == RANK_1 || r == v->maxRank)) psq[pc][s] += make_score(1000, 1000); diff --git a/src/types.h b/src/types.h index edc7c68..006ac75 100644 --- a/src/types.h +++ b/src/types.h @@ -282,6 +282,10 @@ enum CountingRule { NO_COUNTING, MAKRUK_COUNTING, ASEAN_COUNTING }; +enum EnclosingRule { + NO_ENCLOSING, REVERSI, ATAXX +}; + enum Phase { PHASE_ENDGAME, PHASE_MIDGAME = 128, @@ -343,6 +347,7 @@ enum Value : int { ClobberPieceValueMg = 300, ClobberPieceValueEg = 300, BreakthroughPieceValueMg = 300, BreakthroughPieceValueEg = 300, ImmobilePieceValueMg = 50, ImmobilePieceValueEg = 50, + AtaxxPieceValueMg = 100, AtaxxPieceValueEg = 100, CannonPieceValueMg = 800, CannonPieceValueEg = 700, JanggiCannonPieceValueMg = 800, JanggiCannonPieceValueEg = 600, SoldierValueMg = 200, SoldierValueEg = 270, @@ -365,7 +370,7 @@ enum PieceType { FERS, MET = FERS, ALFIL, FERS_ALFIL, SILVER, KHON = SILVER, AIWOK, BERS, DRAGON = BERS, ARCHBISHOP, CHANCELLOR, AMAZON, KNIBIS, BISKNI, KNIROO, ROOKNI, SHOGI_PAWN, LANCE, SHOGI_KNIGHT, EUROSHOGI_KNIGHT, GOLD, DRAGON_HORSE, - CLOBBER_PIECE, BREAKTHROUGH_PIECE, IMMOBILE_PIECE, CANNON, JANGGI_CANNON, + CLOBBER_PIECE, BREAKTHROUGH_PIECE, IMMOBILE_PIECE, ATAXX_PIECE, CANNON, JANGGI_CANNON, SOLDIER, HORSE, ELEPHANT, JANGGI_ELEPHANT, BANNER, WAZIR, COMMONER, CENTAUR, KING, ALL_PIECES = 0, @@ -402,9 +407,9 @@ constexpr Value PieceValue[PHASE_NB][PIECE_NB] = { FersValueMg, AlfilValueMg, FersAlfilValueMg, SilverValueMg, AiwokValueMg, BersValueMg, ArchbishopValueMg, ChancellorValueMg, AmazonValueMg, KnibisValueMg, BiskniValueMg, KnirooValueMg, RookniValueMg, ShogiPawnValueMg, LanceValueMg, ShogiKnightValueMg, EuroShogiKnightValueMg, GoldValueMg, DragonHorseValueMg, - ClobberPieceValueMg, BreakthroughPieceValueMg, ImmobilePieceValueMg, + ClobberPieceValueMg, BreakthroughPieceValueMg, ImmobilePieceValueMg, AtaxxPieceValueMg, CannonPieceValueMg, JanggiCannonPieceValueMg, SoldierValueMg, HorseValueMg, ElephantValueMg, JanggiElephantValueMg, BannerValueMg, - WazirValueMg, CommonerValueMg, CentaurValueMg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, + WazirValueMg, CommonerValueMg, CentaurValueMg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, @@ -414,9 +419,9 @@ constexpr Value PieceValue[PHASE_NB][PIECE_NB] = { FersValueMg, AlfilValueMg, FersAlfilValueMg, SilverValueMg, AiwokValueMg, BersValueMg, ArchbishopValueMg, ChancellorValueMg, AmazonValueMg, KnibisValueMg, BiskniValueMg, KnirooValueMg, RookniValueMg, ShogiPawnValueMg, LanceValueMg, ShogiKnightValueMg, EuroShogiKnightValueMg, GoldValueMg, DragonHorseValueMg, - ClobberPieceValueMg, BreakthroughPieceValueMg, ImmobilePieceValueMg, + ClobberPieceValueMg, BreakthroughPieceValueMg, ImmobilePieceValueMg, AtaxxPieceValueMg, CannonPieceValueMg, JanggiCannonPieceValueMg, SoldierValueMg, HorseValueMg, ElephantValueMg, JanggiElephantValueMg, BannerValueMg, - WazirValueMg, CommonerValueMg, CentaurValueMg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, + WazirValueMg, CommonerValueMg, CentaurValueMg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, @@ -426,9 +431,9 @@ constexpr Value PieceValue[PHASE_NB][PIECE_NB] = { FersValueEg, AlfilValueEg, FersAlfilValueEg, SilverValueEg, AiwokValueEg, BersValueEg, ArchbishopValueMg, ChancellorValueEg, AmazonValueEg, KnibisValueMg, BiskniValueMg, KnirooValueEg, RookniValueEg, ShogiPawnValueEg, LanceValueEg, ShogiKnightValueEg, EuroShogiKnightValueEg, GoldValueEg, DragonHorseValueEg, - ClobberPieceValueEg, BreakthroughPieceValueEg, ImmobilePieceValueEg, + ClobberPieceValueEg, BreakthroughPieceValueEg, ImmobilePieceValueEg, AtaxxPieceValueEg, CannonPieceValueEg, JanggiCannonPieceValueEg, SoldierValueEg, HorseValueEg, ElephantValueEg, JanggiElephantValueEg, BannerValueEg, - WazirValueEg, CommonerValueEg, CentaurValueEg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, + WazirValueEg, CommonerValueEg, CentaurValueEg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, @@ -438,9 +443,9 @@ constexpr Value PieceValue[PHASE_NB][PIECE_NB] = { FersValueEg, AlfilValueEg, FersAlfilValueEg, SilverValueEg, AiwokValueEg, BersValueEg, ArchbishopValueMg, ChancellorValueEg, AmazonValueEg, KnibisValueMg, BiskniValueMg, KnirooValueEg, RookniValueEg, ShogiPawnValueEg, LanceValueEg, ShogiKnightValueEg, EuroShogiKnightValueEg, GoldValueEg, DragonHorseValueEg, - ClobberPieceValueEg, BreakthroughPieceValueEg, ImmobilePieceValueEg, + ClobberPieceValueEg, BreakthroughPieceValueEg, ImmobilePieceValueEg, AtaxxPieceValueEg, CannonPieceValueEg, JanggiCannonPieceValueEg, SoldierValueEg, HorseValueEg, ElephantValueEg, JanggiElephantValueEg, BannerValueEg, - WazirValueEg, CommonerValueEg, CentaurValueEg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, + WazirValueEg, CommonerValueEg, CentaurValueEg, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, VALUE_ZERO, diff --git a/src/variant.cpp b/src/variant.cpp index 77365f5..999198d 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -606,6 +606,27 @@ namespace { v->blackFlag = Rank1BB; return v; } + Variant* ataxx_variant() { + Variant* v = fairy_variant_base(); + v->pieceToCharTable = "P.................p................."; + v->maxRank = RANK_7; + v->maxFile = FILE_G; + v->reset_pieces(); + v->add_piece(ATAXX_PIECE, 'p'); + v->startFen = "P5p/7/7/7/7/7/p5P[PPPPPPPPPPPPPPPPPPPPPPPPPppppppppppppppppppppppppp] w 0 1"; + v->promotionPieceTypes = {}; + v->pieceDrops = true; + v->doubleStep = false; + v->castling = false; + v->immobilityIllegal = false; + v->stalemateValue = -VALUE_MATE; + v->stalematePieceCount = true; + v->passOnStalemate = true; + v->enclosingDrop = ATAXX; + v->flipEnclosedPieces = ATAXX; + v->materialCounting = UNWEIGHTED_MATERIAL; + return v; + } Variant* minixiangqi_variant() { Variant* v = fairy_variant_base(); v->variantTemplate = "xiangqi"; @@ -967,6 +988,7 @@ void VariantMap::init() { add("shatar", shatar_variant()); add("clobber", clobber_variant()); add("breakthrough", breakthrough_variant()); + add("ataxx", ataxx_variant()); add("minixiangqi", minixiangqi_variant()); #ifdef LARGEBOARDS add("shogi", shogi_variant()); diff --git a/src/variant.h b/src/variant.h index 27065dc..ad51aa5 100644 --- a/src/variant.h +++ b/src/variant.h @@ -76,7 +76,7 @@ struct Variant { bool firstRankPawnDrops = false; bool promotionZonePawnDrops = false; bool dropOnTop = false; - bool enclosingDrop = false; + EnclosingRule enclosingDrop = NO_ENCLOSING; Bitboard enclosingDropStart = 0; Bitboard whiteDropRegion = AllSquares; Bitboard blackDropRegion = AllSquares; @@ -94,7 +94,7 @@ struct Variant { bool makpongRule = false; bool flyingGeneral = false; Rank soldierPromotionRank = RANK_1; - bool flipEnclosedPieces = false; + EnclosingRule flipEnclosedPieces = NO_ENCLOSING; // game end int nMoveRule = 50; int nFoldRule = 3; diff --git a/src/variants.ini b/src/variants.ini index 1dcfc0d..d0f62e9 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -73,6 +73,7 @@ # clobber # breakthrough # immobile (piece without moves) +# ataxx (mDNA) # cannon # janggiCannon # soldier @@ -95,6 +96,7 @@ # [Value]: game result for the side to move [win, loss, draw] # [MaterialCounting]: material couting rules for adjudication [janggi, unweighted, whitedrawodds, blackdrawodds, none] # [CountingRule]: makruk or ASEAN counting rules [makruk, asean, none] +# [EnclosingRule]: reversi or ataxx enclosing rules [reversi, ataxx, none] ### Rule definition options # variantTemplate: only relevant for usage in XBoard/WinBoard GUI [values: fairy, shogi] (default: fairy) @@ -138,7 +140,7 @@ # firstRankPawnDrops: allow pawn drops to first rank [bool] (default: false) # promotionZonePawnDrops: allow pawn drops in promotion zone [bool] (default: false) # dropOnTop: piece drops need to be on top of pieces on board (e.g., for connect4) [bool] (default: false) -# enclosingDrop: require piece drop to enclose opponent's pieces (e.g., for othello) [bool] (default: false) +# enclosingDrop: require piece drop to enclose pieces [EnclosingRule] (default: none) # enclosingDropStart: drop region for starting phase disregarding enclosingDrop (e.g., for reversi) [Bitboard] # whiteDropRegion: restrict region for piece drops of all white pieces [Bitboard] # blackDropRegion: restrict region for piece drops of all black pieces [Bitboard] @@ -156,7 +158,7 @@ # makpongRule: the king may not move away from check [bool] (default: false) # flyingGeneral: disallow general face-off like in xiangqi [bool] (default: false) # soldierPromotionRank: restrict soldier to shogi pawn movements until reaching n-th rank [bool] (default: 1) -# flipEnclosedPieces: change color of pieces that are enclosed by a drop (e.g., for othello) [bool] (default: false) +# flipEnclosedPieces: change color of pieces that are enclosed by a drop [EnclosingRule] (default: none) # nMoveRule: move count for 50/n-move rule [int] (default: 50) # nFoldRule: move count for 3/n-fold repetition rule [int] (default: 3) # nFoldValue: result in case of 3/n-fold repetition [Value] (default: draw) @@ -314,10 +316,10 @@ castling = false stalemateValue = loss stalematePieceCount = true materialCounting = unweighted -enclosingDrop = true +enclosingDrop = reversi enclosingDropStart = d4 e4 d5 e5 immobilityIllegal = false -flipEnclosedPieces = true +flipEnclosedPieces = reversi passOnStalemate = false [othello:reversi] diff --git a/tests/perft.sh b/tests/perft.sh index 354fc9b..5606723 100755 --- a/tests/perft.sh +++ b/tests/perft.sh @@ -62,6 +62,8 @@ if [[ $1 == "" || $1 == "variant" ]]; then expect perft.exp sittuyin "fen 8/6s1/5P2/3n4/pR2K2S/1P6/1k4p1/8[] w - - 1 50" 4 268869 > /dev/null expect perft.exp seirawan startpos 5 27639803 > /dev/null expect perft.exp seirawan "fen reb1k2r/ppppqppp/2nb1n2/4p3/4P3/N1P2N2/PB1PQPPP/RE2KBHR[h] b KQkqc - 3 7" 5 31463761 > /dev/null + expect perft.exp ataxx startpos 4 155888 > /dev/null + expect perft.exp ataxx "fen 7/7/7/7/ppppppp/ppppppp/PPPPPPP[PPPPPPPPPPPPPPPPPPPPPppppppppppppppppppppp] w 0 1" 5 452980 > /dev/null fi # large-board variants -- 1.7.0.4