Skip to content

Commit

Permalink
Merge remote-tracking branch 'fairy/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
ianfab committed Jun 4, 2024
2 parents f242c53 + a449a8b commit 8cd9efb
Show file tree
Hide file tree
Showing 21 changed files with 660 additions and 212 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ jobs:
- uses: actions/setup-python@v3

- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.11.2
run: python -m pip install cibuildwheel==2.16.2

- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
# to supply options, put them in 'env', like:
env:
MACOSX_DEPLOYMENT_TARGET: "10.14"
CIBW_ARCHS_MACOS: "x86_64 arm64"
CIBW_SKIP: "pp* *-win32 *-manylinux_i686 *-musllinux_* cp36-*"
CIBW_SKIP: "pp* *-win32 *-manylinux_i686 *-musllinux_* cp36-* cp37-*"
CIBW_TEST_COMMAND: python {project}/test.py

- uses: actions/upload-artifact@v3
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ build_script:
$dummy = $nnuenet -match "(?<nnuenet>nn-[a-z0-9]{12}.nnue)"
$nnuenet = $Matches.nnuenet
Write-Host "Default net:" $nnuenet
$nnuedownloadurl = "https://tests.stockfishchess.org/api/nn/$nnuenet"
$nnuedownloadurl = "https://github.com/official-stockfish/networks/raw/master/$nnuenet"
$nnuefilepath = "src\${env:CONFIGURATION}\$nnuenet"
if (Test-Path -Path $nnuefilepath) {
Write-Host "Already available."
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
sources=sources,
extra_compile_args=args)

setup(name="pyffish", version="0.0.78",
setup(name="pyffish", version="0.0.82",
description="Fairy-Stockfish Python wrapper",
long_description=long_description,
long_description_content_type="text/markdown",
Expand Down
45 changes: 29 additions & 16 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,10 @@ ifeq ($(optimize),yes)
endif

ifeq ($(comp),clang)
CXXFLAGS += -fexperimental-new-pass-manager
clangmajorversion = $(shell $(CXX) -dumpversion 2>/dev/null | cut -f1 -d.)
ifeq ($(shell expr $(clangmajorversion) \< 16),1)
CXXFLAGS += -fexperimental-new-pass-manager
endif
endif
endif

Expand Down Expand Up @@ -821,25 +824,35 @@ clean: objclean profileclean
net:
$(eval nnuenet := $(shell grep EvalFileDefaultName evaluate.h | grep define | sed 's/.*\(nn-[a-z0-9]\{12\}.nnue\).*/\1/'))
@echo "Default net: $(nnuenet)"
$(eval nnuedownloadurl := https://tests.stockfishchess.org/api/nn/$(nnuenet))
$(eval nnuedownloadurl1 := https://tests.stockfishchess.org/api/nn/$(nnuenet))
$(eval nnuedownloadurl2 := https://github.com/official-stockfish/networks/raw/master/$(nnuenet))
$(eval curl_or_wget := $(shell if hash curl 2>/dev/null; then echo "curl -skL"; elif hash wget 2>/dev/null; then echo "wget -qO-"; fi))
@if test -f "$(nnuenet)"; then \
echo "Already available."; \
else \
if [ "x$(curl_or_wget)" = "x" ]; then \
echo "Automatic download failed: neither curl nor wget is installed. Install one of these tools or download the net manually"; exit 1; \
else \
echo "Downloading $(nnuedownloadurl)"; $(curl_or_wget) $(nnuedownloadurl) > $(nnuenet);\
fi; \
fi;
@if [ "x$(curl_or_wget)" = "x" ]; then \
echo "Automatic download failed: neither curl nor wget is installed. Install one of these tools or download the net manually"; exit 1; \
fi
$(eval shasum_command := $(shell if hash shasum 2>/dev/null; then echo "shasum -a 256 "; elif hash sha256sum 2>/dev/null; then echo "sha256sum "; fi))
@if [ "x$(shasum_command)" != "x" ]; then \
if [ "$(nnuenet)" != "nn-"`$(shasum_command) $(nnuenet) | cut -c1-12`".nnue" ]; then \
echo "Failed download or $(nnuenet) corrupted, please delete!"; exit 1; \
fi \
else \
@if [ "x$(shasum_command)" = "x" ]; then \
echo "shasum / sha256sum not found, skipping net validation"; \
fi
@for nnuedownloadurl in "$(nnuedownloadurl1)" "$(nnuedownloadurl2)"; do \
if test -f "$(nnuenet)"; then \
echo "$(nnuenet) available."; \
else \
if [ "x$(curl_or_wget)" != "x" ]; then \
echo "Downloading $${nnuedownloadurl}"; $(curl_or_wget) $${nnuedownloadurl} > $(nnuenet);\
fi; \
fi; \
if [ "x$(shasum_command)" != "x" ]; then \
if [ "$(nnuenet)" != "nn-"`$(shasum_command) $(nnuenet) | cut -c1-12`".nnue" ]; then \
echo "Removing failed download"; rm -f $(nnuenet); \
else \
echo "Network validated"; break; \
fi; \
fi; \
done
@if ! test -f "$(nnuenet)"; then \
echo "Failed to download $(nnuenet)."; \
fi

# clean binaries and objects
objclean:
Expand Down
12 changes: 11 additions & 1 deletion src/apiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ inline Disambiguation disambiguation_level(const Position& pos, Move m, Notation
return SQUARE_DISAMBIGUATION;
}

// A disambiguation occurs if we have more then one piece of type 'pt'
// A disambiguation occurs if we have more than one piece of type 'pt'
// that can reach 'to' with a legal move.
Bitboard b = pos.pieces(us, pt) ^ from;
Bitboard others = 0;
Expand Down Expand Up @@ -821,6 +821,16 @@ inline Validation check_number_of_kings(const std::string& fenBoard, const std::
int nbWhiteKingsStart = piece_count(startFenBoard, WHITE, KING, v);
int nbBlackKingsStart = piece_count(startFenBoard, BLACK, KING, v);

if (nbWhiteKings > 1)
{
std::cerr << "Invalid number of white kings. Maximum: 1. Given: " << nbWhiteKings << std::endl;
return NOK;
}
if (nbBlackKings > 1)
{
std::cerr << "Invalid number of black kings. Maximum: 1. Given: " << nbBlackKings << std::endl;
return NOK;
}
if (nbWhiteKings != nbWhiteKingsStart)
{
std::cerr << "Invalid number of white kings. Expected: " << nbWhiteKingsStart << ". Given: " << nbWhiteKings << std::endl;
Expand Down
10 changes: 6 additions & 4 deletions src/bitboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ namespace {
const std::map<Direction, int> GrasshopperDirectionsH { {EAST, 1}, {WEST, 1} };
const std::map<Direction, int> GrasshopperDirectionsD { {NORTH_EAST, 1}, {SOUTH_EAST, 1}, {SOUTH_WEST, 1}, {NORTH_WEST, 1} };

enum MovementType { RIDER, HOPPER, LAME_LEAPER, UNLIMITED_RIDER };
enum MovementType { RIDER, HOPPER, LAME_LEAPER, HOPPER_RANGE };

template <MovementType MT>
#ifdef PRECOMPUTED_MAGICS
Expand All @@ -137,7 +137,9 @@ namespace {
if (MT != HOPPER || hurdle)
{
attack |= s;
if (limit && MT != UNLIMITED_RIDER && ++count >= limit)
// For hoppers we consider limit == 1 as a grasshopper,
// but limit > 1 as a limited distance hopper
if (limit && !(MT == HOPPER_RANGE && limit == 1) && ++count >= limit)
break;
}

Expand Down Expand Up @@ -300,7 +302,7 @@ void Bitboards::init_pieces() {
leaper |= safe_destination(s, c == WHITE ? d : -d);
}
pseudo |= sliding_attack<RIDER>(pi->slider[initial][modality], s, 0, c);
pseudo |= sliding_attack<UNLIMITED_RIDER>(pi->hopper[initial][modality], s, 0, c);
pseudo |= sliding_attack<HOPPER_RANGE>(pi->hopper[initial][modality], s, 0, c);
}
}
}
Expand Down Expand Up @@ -420,7 +422,7 @@ namespace {
// apply to the 64 or 32 bits word to get the index.
Magic& m = magics[s];
// The mask for hoppers is unlimited distance, even if the hopper is limited distance (e.g., grasshopper)
m.mask = (MT == LAME_LEAPER ? lame_leaper_path(directions, s) : sliding_attack<MT == HOPPER ? UNLIMITED_RIDER : MT>(directions, s, 0)) & ~edges;
m.mask = (MT == LAME_LEAPER ? lame_leaper_path(directions, s) : sliding_attack<MT == HOPPER ? HOPPER_RANGE : MT>(directions, s, 0)) & ~edges;
#ifdef LARGEBOARDS
m.shift = 128 - popcount(m.mask);
#else
Expand Down
13 changes: 10 additions & 3 deletions src/movegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ namespace {
ExtMove* make_move_and_gating(const Position& pos, ExtMove* moveList, Color us, Square from, Square to, PieceType pt = NO_PIECE_TYPE) {

// Wall placing moves
if (pos.walling())
//if it's "wall or move", and they chose non-null move, skip even generating wall move
if (pos.walling() && !(pos.variant()->wallOrMove && (from!=to)))
{
Bitboard b = pos.board_bb() & ~((pos.pieces() ^ from) | to);
if (T == CASTLING)
Expand Down Expand Up @@ -441,8 +442,14 @@ namespace {
}

// Workaround for passing: Execute a non-move with any piece
if (pos.pass() && !pos.count<KING>(Us) && pos.pieces(Us))
if (pos.pass(Us) && !pos.count<KING>(Us) && pos.pieces(Us))
*moveList++ = make<SPECIAL>(lsb(pos.pieces(Us)), lsb(pos.pieces(Us)));

//if "wall or move", generate walling action with null move
if (pos.variant()->wallOrMove)
{
moveList = make_move_and_gating<SPECIAL>(pos, moveList, Us, lsb(pos.pieces(Us)), lsb(pos.pieces(Us)));
}
}

// King moves
Expand All @@ -454,7 +461,7 @@ namespace {
moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, ksq, pop_lsb(b));

// Passing move by king
if (pos.pass())
if (pos.pass(Us))
*moveList++ = make<SPECIAL>(ksq, ksq);

if ((Type == QUIETS || Type == NON_EVASIONS) && pos.can_castle(Us & ANY_CASTLING))
Expand Down
34 changes: 32 additions & 2 deletions src/movegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,37 @@ inline bool operator<(const ExtMove& f, const ExtMove& s) {
template<GenType>
ExtMove* generate(const Position& pos, ExtMove* moveList);

constexpr size_t moveListSize = sizeof(ExtMove) * MAX_MOVES;

/// The MoveList struct is a simple wrapper around generate(). It sometimes comes
/// in handy to use this class instead of the low level generate() function.
template<GenType T>
struct MoveList {

explicit MoveList(const Position& pos) : last(generate<T>(pos, moveList)) {}

#ifdef USE_HEAP_INSTEAD_OF_STACK_FOR_MOVE_LIST
explicit MoveList(const Position& pos)
{
this->moveList = (ExtMove*)malloc(moveListSize);
if (this->moveList == 0)
{
printf("Error: Failed to allocate memory in heap.");
exit(1);
}
this->last = generate<T>(pos, this->moveList);
}

~MoveList()
{
free(this->moveList);
}
#else
explicit MoveList(const Position& pos) : last(generate<T>(pos, moveList))
{
;
}
#endif

const ExtMove* begin() const { return moveList; }
const ExtMove* end() const { return last; }
size_t size() const { return last - moveList; }
Expand All @@ -69,7 +94,12 @@ struct MoveList {
}

private:
ExtMove moveList[MAX_MOVES], *last;
ExtMove* last;
#ifdef USE_HEAP_INSTEAD_OF_STACK_FOR_MOVE_LIST
ExtMove* moveList = 0;
#else
ExtMove moveList[MAX_MOVES];
#endif
};

} // namespace Stockfish
Expand Down
58 changes: 48 additions & 10 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ namespace {
: value == "ataxx" ? ATAXX
: value == "quadwrangle" ? QUADWRANGLE
: value == "snort" ? SNORT
: value == "anyside" ? ANYSIDE
: value == "top" ? TOP
: NO_ENCLOSING;
return value == "reversi" || value == "ataxx" || value == "quadwrangle" || value =="snort" || value == "none";
return value == "reversi" || value == "ataxx" || value == "quadwrangle" || value =="snort" || value =="anyside" || value =="top" || value == "none";
}

template <> bool set(const std::string& value, WallingRule& target) {
Expand All @@ -122,19 +124,36 @@ namespace {
}

template <> bool set(const std::string& value, Bitboard& target) {
char file;
int rank;
std::string symbol;
std::stringstream ss(value);
target = 0;
while (!ss.eof() && ss >> file && file != '-' && ss >> rank)
while (!ss.eof() && ss >> symbol && symbol != "-")
{
if (Rank(rank - 1) > RANK_MAX || (file != '*' && File(tolower(file) - 'a') > FILE_MAX))
if (symbol.back() == '*') {
if (isalpha(symbol[0]) && symbol.length() == 2) {
char file = tolower(symbol[0]);
if (File(file - 'a') > FILE_MAX) return false;
target |= file_bb(File(file - 'a'));
} else {
return false;
}
} else if (symbol[0] == '*') {
int rank = std::stoi(symbol.substr(1));
if (Rank(rank - 1) > RANK_MAX) return false;
target |= rank_bb(Rank(rank - 1));
} else if (isalpha(symbol[0]) && symbol.length() > 1) {
char file = tolower(symbol[0]);
int rank = std::stoi(symbol.substr(1));
if (Rank(rank - 1) > RANK_MAX || File(file - 'a') > FILE_MAX) return false;
target |= square_bb(make_square(File(file - 'a'), Rank(rank - 1)));
} else {
return false;
target |= file == '*' ? rank_bb(Rank(rank - 1)) : square_bb(make_square(File(tolower(file) - 'a'), Rank(rank - 1)));
}
}
return !ss.fail();
}


template <> bool set(const std::string& value, CastlingRights& target) {
char c;
CastlingRights castlingRight;
Expand Down Expand Up @@ -327,6 +346,10 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
parse_attribute<false>("castlingRookPiece", v->castlingRookPieces[WHITE], v->pieceToChar);
parse_attribute<false>("castlingRookPiece", v->castlingRookPieces[BLACK], v->pieceToChar);

bool dropOnTop = false;
parse_attribute<false>("dropOnTop", dropOnTop);
if (dropOnTop) v->enclosingDrop=TOP;

// Parse aliases
parse_attribute("pawnTypes", v->promotionPawnType[WHITE], v->pieceToChar);
parse_attribute("pawnTypes", v->promotionPawnType[BLACK], v->pieceToChar);
Expand Down Expand Up @@ -433,7 +456,6 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
parse_attribute("capturesToHand", v->capturesToHand);
parse_attribute("firstRankPawnDrops", v->firstRankPawnDrops);
parse_attribute("promotionZonePawnDrops", v->promotionZonePawnDrops);
parse_attribute("dropOnTop", v->dropOnTop);
parse_attribute("enclosingDrop", v->enclosingDrop);
parse_attribute("enclosingDropStart", v->enclosingDropStart);
parse_attribute("whiteDropRegion", v->whiteDropRegion);
Expand All @@ -450,11 +472,18 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
parse_attribute("wallingRegionBlack", v->wallingRegion[BLACK]);
parse_attribute("wallingRegion", v->wallingRegion[WHITE]);
parse_attribute("wallingRegion", v->wallingRegion[BLACK]);
parse_attribute("wallOrMove", v->wallOrMove);
parse_attribute("seirawanGating", v->seirawanGating);
parse_attribute("cambodianMoves", v->cambodianMoves);
parse_attribute("diagonalLines", v->diagonalLines);
parse_attribute("pass", v->pass);
parse_attribute("passOnStalemate", v->passOnStalemate);
parse_attribute("pass", v->pass[WHITE]);
parse_attribute("pass", v->pass[BLACK]);
parse_attribute("passWhite", v->pass[WHITE]);
parse_attribute("passBlack", v->pass[BLACK]);
parse_attribute("passOnStalemate", v->passOnStalemate[WHITE]);
parse_attribute("passOnStalemate", v->passOnStalemate[BLACK]);
parse_attribute("passOnStalemateWhite", v->passOnStalemate[WHITE]);
parse_attribute("passOnStalemateBlack", v->passOnStalemate[BLACK]);
parse_attribute("makpongRule", v->makpongRule);
parse_attribute("flyingGeneral", v->flyingGeneral);
parse_attribute("soldierPromotionRank", v->soldierPromotionRank);
Expand Down Expand Up @@ -499,17 +528,26 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
parse_attribute("flagPieceSafe", v->flagPieceSafe);
parse_attribute("checkCounting", v->checkCounting);
parse_attribute("connectN", v->connectN);
parse_attribute("connectPieceTypes", v->connectPieceTypes, v->pieceToChar);
parse_attribute("connectHorizontal", v->connectHorizontal);
parse_attribute("connectVertical", v->connectVertical);
parse_attribute("connectDiagonal", v->connectDiagonal);
parse_attribute("connectRegion1White", v->connectRegion1[WHITE]);
parse_attribute("connectRegion2White", v->connectRegion2[WHITE]);
parse_attribute("connectRegion1Black", v->connectRegion1[BLACK]);
parse_attribute("connectRegion2Black", v->connectRegion2[BLACK]);
parse_attribute("connectNxN", v->connectNxN);
parse_attribute("collinearN", v->collinearN);
parse_attribute("connectValue", v->connectValue);
parse_attribute("materialCounting", v->materialCounting);
parse_attribute("adjudicateFullBoard", v->adjudicateFullBoard);
parse_attribute("countingRule", v->countingRule);
parse_attribute("castlingWins", v->castlingWins);

// Report invalid options
if (DoCheck)
{
const std::set<std::string>& parsedKeys = config.get_comsumed_keys();
const std::set<std::string>& parsedKeys = config.get_consumed_keys();
for (const auto& it : config)
if (parsedKeys.find(it.first) == parsedKeys.end())
std::cerr << "Invalid option: " << it.first << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion src/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Config : public std::map<std::string, std::string> {
consumedKeys.insert(s);
return std::map<std::string, std::string>::find(s);
}
const std::set<std::string>& get_comsumed_keys() {
const std::set<std::string>& get_consumed_keys() {
return consumedKeys;
}
private:
Expand Down
Loading

0 comments on commit 8cd9efb

Please sign in to comment.