Skip to content

Commit

Permalink
Merge remote-tracking branch 'fairy/master' into nnue
Browse files Browse the repository at this point in the history
  • Loading branch information
ianfab committed Aug 27, 2023
2 parents 516e476 + 84e305f commit 0a48d23
Show file tree
Hide file tree
Showing 18 changed files with 454 additions and 172 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/stockfish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ jobs:
matrix:
config:
- {
name: "Ubuntu 20.04 GCC",
os: ubuntu-20.04,
name: "Ubuntu 22.04 GCC",
os: ubuntu-22.04,
compiler: g++,
comp: gcc,
run_expensive_tests: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macos-10.15]
os: [ubuntu-20.04, windows-2019, macos-11]

steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ before_build:
'add_compile_definitions(NNUE_EMBEDDING_OFF)',
'add_executable(stockfish ${source_files})'
# Write CMakeLists.txt withouth BOM
# Write CMakeLists.txt without BOM
$MyPath = (Get-Item -Path "." -Verbose).FullName + '\CMakeLists.txt'
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($MyPath, $t, $Utf8NoBomEncoding)
Expand Down
5 changes: 5 additions & 0 deletions src/apiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,11 @@ inline bool has_insufficient_material(Color c, const Position& pos) {
if ((pos.pieces(c) & unbound) && (popcount(pos.pieces() ^ restricted) >= 2 || pos.stalemate_value() != VALUE_DRAW || pos.check_counting() || pos.makpong()))
return false;

// Non-draw stalemate with lone custom king
if ( pos.stalemate_value() != VALUE_DRAW && pos.king_type() != KING
&& pos.pieces(c, KING) && (pos.board_bb(c, KING) & pos.board_bb(~c, KING)))
return false;

return true;
}

Expand Down
3 changes: 2 additions & 1 deletion src/evaluate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1292,7 +1292,8 @@ namespace {
// Connect-n
if (pos.connect_n() > 0)
{
for (Direction d : {NORTH, NORTH_EAST, EAST, SOUTH_EAST})
for (const Direction& d : pos.getConnectDirections())

{
// Find sufficiently large gaps
Bitboard b = pos.board_bb() & ~pos.pieces(Them);
Expand Down
22 changes: 20 additions & 2 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ namespace {
int rank;
std::stringstream ss(value);
target = 0;
while (!ss.eof() && ss >> file && ss >> rank)
while (!ss.eof() && ss >> file && file != '-' && ss >> rank)
{
if (Rank(rank - 1) > RANK_MAX || (file != '*' && File(tolower(file) - 'a') > FILE_MAX))
return false;
Expand Down Expand Up @@ -172,7 +172,7 @@ template <bool Current, class T> bool VariantParser<DoCheck>::parse_attribute(co
{
target = T();
char token;
size_t idx;
size_t idx = std::string::npos;
std::stringstream ss(it->second);
while (ss >> token && (idx = token == '*' ? size_t(ALL_PIECES) : pieceToChar.find(toupper(token))) != std::string::npos)
set(PieceType(idx), target);
Expand Down Expand Up @@ -357,7 +357,10 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
parse_attribute("mandatoryPiecePromotion", v->mandatoryPiecePromotion);
parse_attribute("pieceDemotion", v->pieceDemotion);
parse_attribute("blastOnCapture", v->blastOnCapture);
parse_attribute("blastImmuneTypes", v->blastImmuneTypes, v->pieceToChar);
parse_attribute("mutuallyImmuneTypes", v->mutuallyImmuneTypes, v->pieceToChar);
parse_attribute("petrifyOnCapture", v->petrifyOnCapture);
parse_attribute("petrifyBlastPieces", v->petrifyBlastPieces);
parse_attribute("doubleStep", v->doubleStep);
parse_attribute("doubleStepRegionWhite", v->doubleStepRegion[WHITE]);
parse_attribute("doubleStepRegionBlack", v->doubleStepRegion[BLACK]);
Expand Down Expand Up @@ -459,6 +462,9 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
parse_attribute("flagMove", v->flagMove);
parse_attribute("checkCounting", v->checkCounting);
parse_attribute("connectN", v->connectN);
parse_attribute("connectHorizontal", v->connectHorizontal);
parse_attribute("connectVertical", v->connectVertical);
parse_attribute("connectDiagonal", v->connectDiagonal);
parse_attribute("materialCounting", v->materialCounting);
parse_attribute("countingRule", v->countingRule);

Expand Down Expand Up @@ -520,6 +526,7 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
// Check for limitations
if (v->pieceDrops && (v->arrowGating || v->duckGating || v->staticGating || v->pastGating))
std::cerr << "pieceDrops and arrowGating/duckGating are incompatible." << std::endl;

// Options incompatible with royal kings
if (v->pieceTypes & KING)
{
Expand All @@ -543,6 +550,17 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
std::cerr << piece_name(v->kingType) << " is not supported as kingType." << std::endl;
}
}
// Options incompatible with royal kings OR pseudo-royal kings. Possible in theory though:
// 1. In blast variants, moving a (pseudo-)royal blastImmuneType into another piece is legal.
// 2. In blast variants, capturing a piece next to a (pseudo-)royal blastImmuneType is legal.
// 3. Moving a (pseudo-)royal mutuallyImmuneType into a square threatened by the same type is legal.
if ((v->extinctionPseudoRoyal) || (v->pieceTypes & KING))
{
if (v->blastImmuneTypes)
std::cerr << "Can not use kings or pseudo-royal with blastImmuneTypes." << std::endl;
if (v->mutuallyImmuneTypes)
std::cerr << "Can not use kings or pseudo-royal with mutuallyImmuneTypes." << std::endl;
}
}
return v;
}
Expand Down
2 changes: 1 addition & 1 deletion src/partner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ void PartnerHandler::parse_ptell(std::istringstream& is, const Position& pos) {
ptell<HUMAN>("If you specify a valid move, e.g., 'move e2e4', I will play it.");
}
else if (token == "fast")
ptell<HUMAN>("After receiving 'go', I will play fast.");
ptell<HUMAN>("After receiving 'fast', I will play fast.");
else if (token == "slow")
ptell<HUMAN>("After receiving 'slow', I will play at normal speed.");
else if (token == "dead")
Expand Down
36 changes: 26 additions & 10 deletions src/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,10 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960,

token = char(toupper(token));

if (token == 'K')
if (castling_enabled() && token == 'K')
for (rsq = make_square(var->castlingRookKingsideFile, castling_rank(c)); !(castling_rook_pieces(c) & type_of(piece_on(rsq))) || color_of(piece_on(rsq)) != c; --rsq) {}

else if (token == 'Q')
else if (castling_enabled() && token == 'Q')
for (rsq = make_square(var->castlingRookQueensideFile, castling_rank(c)); !(castling_rook_pieces(c) & type_of(piece_on(rsq))) || color_of(piece_on(rsq)) != c; ++rsq) {}

else if (token >= 'A' && token <= 'A' + max_file())
Expand Down Expand Up @@ -428,6 +428,7 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960,
// c) there is no piece on epSquare or behind epSquare
if ( (var->enPassantRegion & epSquare)
&& ( !var->fastAttacks
|| (var->enPassantTypes[sideToMove] & ~piece_set(PAWN))
|| ( pawn_attacks_bb(~sideToMove, epSquare) & pieces(sideToMove, PAWN)
&& ( (pieces(~sideToMove, PAWN) & (epSquare + pawn_push(~sideToMove)))
|| (pieces(~sideToMove, PAWN) & (epSquare + 2 * pawn_push(~sideToMove))))
Expand Down Expand Up @@ -698,7 +699,7 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string
ss << piece_to_char()[piece_on(make_square(f, r))];

// Set promoted pieces
if (((captures_to_hand() && !drop_loop()) || showPromoted) && is_promoted(make_square(f, r)))
if (((captures_to_hand() && !drop_loop()) || two_boards() || showPromoted) && is_promoted(make_square(f, r)))
ss << "~";
}
}
Expand Down Expand Up @@ -1175,6 +1176,14 @@ bool Position::legal(Move m) const {
if (var->petrifyOnCapture && capture(m) && type_of(moved_piece(m)) == KING)
return false;

// mutuallyImmuneTypes (diplomacy in Atomar)-- In no-check Atomic, kings can be beside each other, but in Atomar, this prevents them from actually taking.
// Generalized to allow a custom set of pieces that can't capture a piece of the same type.
if (capture(m) &&
(mutually_immune_types() & type_of(moved_piece(m))) &&
(type_of(moved_piece(m)) == type_of(piece_on(to)))
)
return false;

// En passant captures are a tricky special case. Because they are rather
// uncommon, we do it simply by testing whether the king is attacked after
// the move is made.
Expand Down Expand Up @@ -1660,7 +1669,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
// 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);
Bitboard b = attacks_bb(us, QUEEN, to, ~pieces(~us)) & ~PseudoAttacks[us][KING][to] & pieces(us);
while(b)
st->flippedPieces |= between_bb(pop_lsb(b), to) ^ to;
}
Expand Down Expand Up @@ -1790,15 +1799,15 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|| std::abs(int(to) - int(from)) == 3 * NORTH))
{
if ( (var->enPassantRegion & (to - pawn_push(us)))
&& (pawn_attacks_bb(us, to - pawn_push(us)) & pieces(them, PAWN))
&& ((pawn_attacks_bb(us, to - pawn_push(us)) & pieces(them, PAWN)) || var->enPassantTypes[them] & ~piece_set(PAWN))
&& !(wall_gating() && gating_square(m) == to - pawn_push(us)))
{
st->epSquares |= to - pawn_push(us);
k ^= Zobrist::enpassant[file_of(to)];
}
if ( std::abs(int(to) - int(from)) == 3 * NORTH
&& (var->enPassantRegion & (to - 2 * pawn_push(us)))
&& (pawn_attacks_bb(us, to - 2 * pawn_push(us)) & pieces(them, PAWN))
&& ((pawn_attacks_bb(us, to - 2 * pawn_push(us)) & pieces(them, PAWN)) || var->enPassantTypes[them] & ~piece_set(PAWN))
&& !(wall_gating() && gating_square(m) == to - 2 * pawn_push(us)))
{
st->epSquares |= to - 2 * pawn_push(us);
Expand Down Expand Up @@ -1920,13 +1929,19 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
if (cambodian_moves() && type_of(pc) == ROOK && (square<KING>(them) & gates(them) & attacks_bb<ROOK>(to)))
st->gatesBB[them] ^= square<KING>(them);


// Remove the blast pieces
if (captured && (blast_on_capture() || var->petrifyOnCapture))
{
std::memset(st->unpromotedBycatch, 0, sizeof(st->unpromotedBycatch));
st->demotedBycatch = st->promotedBycatch = 0;
Bitboard blast = blast_on_capture() ? (attacks_bb<KING>(to) & ((pieces(WHITE) | pieces(BLACK)) ^ pieces(PAWN))) | to
: type_of(pc) != PAWN ? square_bb(to) : Bitboard(0);
Bitboard blastImmune = 0;
for (PieceSet ps = blast_immune_types(); ps;){
PieceType pt = pop_lsb(ps);
blastImmune |= pieces(pt);
};
Bitboard blast = blast_on_capture() ? ((attacks_bb<KING>(to) & ((pieces(WHITE) | pieces(BLACK)) ^ pieces(PAWN))) | to)
& (pieces() ^ blastImmune) : type_of(pc) != PAWN ? square_bb(to) : Bitboard(0);
while (blast)
{
Square bsq = pop_lsb(blast);
Expand Down Expand Up @@ -1988,7 +2003,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
}

// Make a wall square where the piece was
if (var->petrifyOnCapture)
if (bsq == to ? var->petrifyOnCapture : var->petrifyBlastPieces)
{
st->wallSquares |= bsq;
byTypeBB[ALL_PIECES] |= bsq;
Expand Down Expand Up @@ -2716,7 +2731,8 @@ bool Position::is_immediate_game_end(Value& result, int ply) const {
if (connect_n() > 0)
{
Bitboard b;
for (Direction d : {NORTH, NORTH_EAST, EAST, SOUTH_EAST})

for (Direction d : var->connect_directions)
{
b = pieces(~sideToMove);
for (int i = 1; i < connect_n() && b; i++)
Expand Down
49 changes: 42 additions & 7 deletions src/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ class Position {
bool mandatory_piece_promotion() const;
bool piece_demotion() const;
bool blast_on_capture() const;
PieceSet blast_immune_types() const;
PieceSet mutually_immune_types() const;
bool endgame_eval() const;
Bitboard double_step_region(Color c) const;
Bitboard triple_step_region(Color c) const;
Expand Down Expand Up @@ -203,6 +205,11 @@ class Position {
bool flag_reached(Color c) const;
bool check_counting() const;
int connect_n() const;
bool connect_horizontal() const;
bool connect_vertical() const;
bool connect_diagonal() const;
const std::vector<Direction>& getConnectDirections() const;

CheckCount checks_remaining(Color c) const;
MaterialCounting material_counting() const;
CountingRule counting_rule() const;
Expand Down Expand Up @@ -485,6 +492,16 @@ inline bool Position::blast_on_capture() const {
return var->blastOnCapture;
}

inline PieceSet Position::blast_immune_types() const {
assert(var != nullptr);
return var->blastImmuneTypes;
}

inline PieceSet Position::mutually_immune_types() const {
assert(var != nullptr);
return var->mutuallyImmuneTypes;
}

inline bool Position::endgame_eval() const {
assert(var != nullptr);
return var->endgameEval && !count_in_hand(ALL_PIECES) && count<KING>() == 2;
Expand Down Expand Up @@ -948,6 +965,24 @@ inline int Position::connect_n() const {
return var->connectN;
}

inline bool Position::connect_horizontal() const {
assert(var != nullptr);
return var->connectHorizontal;
}
inline bool Position::connect_vertical() const {
assert(var != nullptr);
return var->connectVertical;
}
inline bool Position::connect_diagonal() const {
assert(var != nullptr);
return var->connectDiagonal;
}

inline const std::vector<Direction>& Position::getConnectDirections() const {
assert(var != nullptr);
return var->connect_directions;
}

inline CheckCount Position::checks_remaining(Color c) const {
return st->checksRemaining[c];
}
Expand Down Expand Up @@ -1373,18 +1408,18 @@ inline bool Position::allow_virtual_drop(Color c, PieceType pt) const {
}

inline Value Position::material_counting_result() const {
auto weigth_count = [this](PieceType pt, int v){ return v * (count(WHITE, pt) - count(BLACK, pt)); };
auto weight_count = [this](PieceType pt, int v){ return v * (count(WHITE, pt) - count(BLACK, pt)); };
int materialCount;
Value result;
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)
materialCount = weight_count(ROOK, 13)
+ weight_count(JANGGI_CANNON, 7)
+ weight_count(HORSE, 5)
+ weight_count(JANGGI_ELEPHANT, 3)
+ weight_count(WAZIR, 3)
+ weight_count(SOLDIER, 2)
- 1;
result = materialCount > 0 ? VALUE_MATE : -VALUE_MATE;
break;
Expand Down
2 changes: 1 addition & 1 deletion src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ namespace {
&& (ss-1)->statScore < 23767
&& eval >= beta
&& eval >= ss->staticEval
&& ss->staticEval >= beta - 20 * depth - 22 * improving + 168 * ss->ttPv + 159 + 200 * (!pos.double_step_region(pos.side_to_move()) && pos.piece_to_char()[PAWN] != ' ')
&& ss->staticEval >= beta - 20 * depth - 22 * improving + 168 * ss->ttPv + 159 + 200 * (!pos.double_step_region(pos.side_to_move()) && (pos.piece_types() & PAWN))
&& !excludedMove
&& pos.non_pawn_material(us)
&& pos.count<ALL_PIECES>(~us) != pos.count<PAWN>(~us)
Expand Down
6 changes: 3 additions & 3 deletions src/syzygy/tbprobe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
goto encode_remaining; // With pawns we have finished special treatments
}

// In positions withouth pawns, we further flip the squares to ensure leading
// In positions without pawns, we further flip the squares to ensure leading
// piece is below RANK_5.
if (rank_of(squares[0]) > RANK_4)
for (int i = 0; i < size; ++i)
Expand Down Expand Up @@ -821,7 +821,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
int adjust2 = (squares[2] > squares[0]) + (squares[2] > squares[1]);

// First piece is below a1-h8 diagonal. MapA1D1D4[] maps the b1-d1-d3
// triangle to 0...5. There are 63 squares for second piece and and 62
// triangle to 0...5. There are 63 squares for second piece and 62
// (mapped to 0...61) for the third.
if (off_A1H8(squares[0]))
idx = ( MapA1D1D4[squares[0]] * 63
Expand Down Expand Up @@ -1326,7 +1326,7 @@ void Tablebases::init(const std::string& paths) {
for (auto p : bothOnDiagonal)
MapKK[p.first][p.second] = code++;

// Binomial[] stores the Binomial Coefficents using Pascal rule. There
// Binomial[] stores the Binomial Coefficients using Pascal rule. There
// are Binomial[k][n] ways to choose k elements from a set of n elements.
Binomial[0][0] = 1;

Expand Down
2 changes: 1 addition & 1 deletion src/syzygy/tbprobe.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ enum WDLScore {
// Possible states after a probing operation
enum ProbeState {
FAIL = 0, // Probe failed (missing file table)
OK = 1, // Probe succesful
OK = 1, // Probe successful
CHANGE_STM = -1, // DTZ should check the other side
ZEROING_BEST_MOVE = 2 // Best move zeroes DTZ (capture or pawn move)
};
Expand Down
Loading

0 comments on commit 0a48d23

Please sign in to comment.