sources=sources,
extra_compile_args=args)
-setup(name="pyffish", version="0.0.84",
+setup(name="pyffish", version="0.0.85",
description="Fairy-Stockfish Python wrapper",
long_description=long_description,
long_description_content_type="text/markdown",
/// Position::fen() returns a FEN representation of the position. In case of
/// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
-string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string holdings) const {
+string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string holdings, Bitboard fogArea) const {
int emptyCnt;
std::ostringstream ss;
{
for (File f = FILE_A; f <= max_file(); ++f)
{
- for (emptyCnt = 0; f <= max_file() && !(pieces() & make_square(f, r)); ++f)
+ for (emptyCnt = 0; f <= max_file() && !(pieces() & make_square(f, r)) && !(fogArea & make_square(f, r)); ++f)
++emptyCnt;
if (emptyCnt)
if (f <= max_file())
{
- if (empty(make_square(f, r)))
+ if (empty(make_square(f, r)) || fogArea & make_square(f, r))
// Wall square
ss << "*";
else if (unpromoted_piece_on(make_square(f, r)))
// FEN string input/output
Position& set(const Variant* v, const std::string& fenStr, bool isChess960, StateInfo* si, Thread* th, bool sfen = false);
Position& set(const std::string& code, Color c, StateInfo* si);
- std::string fen(bool sfen = false, bool showPromoted = false, int countStarted = 0, std::string holdings = "-") const;
+ std::string fen(bool sfen = false, bool showPromoted = false, int countStarted = 0, std::string holdings = "-", Bitboard fogArea = 0) const;
// Variant rule properties
const Variant* variant() const;
Score psq_score() const;
Value non_pawn_material(Color c) const;
Value non_pawn_material() const;
+ Bitboard fog_area() const;
// Position consistency check, for debugging
bool pos_is_ok() const;
return st->capturedPiece;
}
+inline Bitboard Position::fog_area() const {
+ Bitboard b = board_bb();
+ // Our own pieces are visible
+ Bitboard visible = pieces(sideToMove);
+ // Squares where we can move to are visible as well
+ for (const auto& m : MoveList<LEGAL>(*this))
+ {
+ Square to = to_sq(m);
+ visible |= to;
+ }
+ // Everything else is invisible
+ return ~visible & b;
+}
+
inline const std::string Position::piece_to_partner() const {
if (!st->capturedPiece) return std::string();
Color color = color_of(st->capturedPiece);
}
extern "C" PyObject* pyffish_version(PyObject* self) {
- return Py_BuildValue("(iii)", 0, 0, 84);
+ return Py_BuildValue("(iii)", 0, 0, 85);
}
extern "C" PyObject* pyffish_info(PyObject* self) {
return Py_BuildValue("i", FEN::validate_fen(std::string(fen), variants.find(std::string(variant))->second, chess960));
}
+// INPUT variant, fen
+extern "C" PyObject* pyffish_getFogFEN(PyObject* self, PyObject *args) {
+ PyObject* moveList = PyList_New(0);
+ Position pos;
+ const char *fen, *variant;
+
+ int chess960 = false, sfen = false, showPromoted = false, countStarted = 0;
+ if (!PyArg_ParseTuple(args, "ss|p", &fen, &variant, &chess960)) {
+ return NULL;
+ }
+ StateListPtr states(new std::deque<StateInfo>(1));
+ buildPosition(pos, states, variant, fen, moveList, chess960);
+
+ Py_XDECREF(moveList);
+ return Py_BuildValue("s", pos.fen(sfen, showPromoted, countStarted, "-", pos.fog_area()).c_str());
+}
static PyMethodDef PyFFishMethods[] = {
{"version", (PyCFunction)pyffish_version, METH_NOARGS, "Get package version."},
{"is_optional_game_end", (PyCFunction)pyffish_isOptionalGameEnd, METH_VARARGS, "Get result from given FEN it rules enable game end by player."},
{"has_insufficient_material", (PyCFunction)pyffish_hasInsufficientMaterial, METH_VARARGS, "Checks for insufficient material."},
{"validate_fen", (PyCFunction)pyffish_validateFen, METH_VARARGS, "Validate an input FEN."},
+ {"get_fog_fen", (PyCFunction)pyffish_getFogFEN, METH_VARARGS, "Get Fog of War FEN from given FEN."},
{NULL, NULL, 0, NULL}, // sentinel
};
customPiece5 = f:mBpBmWpR2
promotedPieceType = u:w a:w c:f i:f
startFen = lnsgkgsnl/1rci1uab1/p1p1p1p1p/9/9/9/P1P1P1P1P/1BAU1ICR1/LNSGKGSNL[-] w 0 1
+
+[fogofwar:chess]
+king = -
+commoner = k
+castlingKingPiece = k
+extinctionValue = loss
+extinctionPieceTypes = k
"""
sf.load_variant_config(ini_text)
fen = sf.start_fen(variant)
self.assertEqual(sf.validate_fen(fen, variant), sf.FEN_OK)
+ def test_get_fog_fen(self):
+ fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" # startpos
+ result = sf.get_fog_fen(fen, "fogofwar")
+ self.assertEqual(result, "********/********/********/********/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
+
+ fen = "rnbqkbnr/p1p2ppp/8/Pp1pp3/4P3/8/1PPP1PPP/RNBQKBNR w KQkq b6 0 1"
+ result = sf.get_fog_fen(fen, "fogofwar")
+ self.assertEqual(result, "********/********/2******/Pp*p***1/4P3/4*3/1PPP1PPP/RNBQKBNR w KQkq b6 0 1")
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)