{ -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
};
{ -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
};
{}, // gold
{ NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse
{}, // clobber
+ {}, // breakthrough
{}, // commoner
{} // king
};
{}, // gold
{ NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse
{}, // clobber
+ {}, // breakthrough
{}, // commoner
{} // king
};
0, // gold
7, // horse
0, // clobber
+ 0, // breakthrough
0, // commoner
0 // king
};
0, // gold
7, // horse
0, // clobber
+ 0, // breakthrough
0, // commoner
0 // king
};
// 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<KING>(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));
+ }
}
}
Value extinction_value(int ply = 0) const;
bool bare_king_move() const;
const std::set<PieceType>& 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;
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;
}
}
// capture the flag
- if (count<KING>(~sideToMove) && !flag_move() && (capture_the_flag(~sideToMove) & square<KING>(~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<KING>( sideToMove) && flag_move() && (capture_the_flag( sideToMove) & square<KING>( sideToMove)))
+ if ( capture_the_flag_piece()
+ && flag_move()
+ && (capture_the_flag(sideToMove) & pieces(sideToMove, capture_the_flag_piece())))
{
result = mate_in(ply);
return true;
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 {
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
};
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
} ();
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;
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;
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);
add("chigorin", chigorin);
add("shatar", shatar);
add("clobber", clobber);
+ add("breakthrough", breakthrough);
}
void VariantMap::add(std::string s, const Variant* v) {
Value extinctionValue = VALUE_NONE;
bool bareKingMove = false;
std::set<PieceType> extinctionPieceTypes = {};
+ PieceType flagPiece = NO_PIECE_TYPE;
Bitboard whiteFlag = 0;
Bitboard blackFlag = 0;
bool flagMove = false;