for (std::string v : variants.get_keys())
if (v != "chess")
vars += "," + v;
- sync_cout << "feature setboard=1 usermove=1 time=1 memory=1 smp=1 colors=0 draw=0 name=0 sigint=0 ping=1 myname=Fairy-Stockfish variants=\""
+ sync_cout << "feature setboard=1 usermove=1 time=1 memory=1 smp=1 colors=0 draw=0 "
+ << "highlight=1 name=0 sigint=0 ping=1 myname=Fairy-Stockfish variants=\""
<< vars << "\""
<< Options << sync_endl;
sync_cout << "feature done=1" << sync_endl;
}
else if (token == "accepted" || token == "rejected" || token == "result" || token == "?") {}
+ else if (token == "hover" || token == "put") {}
+ else if (token == "lift")
+ {
+ if (is >> token)
+ {
+ Bitboard promotions = 0, captures = 0, quiets = 0;
+ // Collect targets
+ for (const auto& m : MoveList<LEGAL>(pos))
+ {
+ Square from = from_sq(m), to = to_sq(m);
+ if (is_ok(from) && UCI::square(pos, from) == token)
+ {
+ if (type_of(m) == PROMOTION)
+ promotions |= to;
+ else if (pos.capture(m))
+ captures |= to;
+ else
+ {
+ if (type_of(m) == CASTLING && !pos.is_chess960())
+ to = make_square(to > from ? pos.castling_kingside_file()
+ : pos.castling_queenside_file(), rank_of(from));
+ quiets |= to;
+ }
+ }
+ }
+ // Generate color FEN
+ int emptyCnt;
+ std::ostringstream ss;
+ for (Rank r = pos.max_rank(); r >= RANK_1; --r)
+ {
+ for (File f = FILE_A; f <= pos.max_file(); ++f)
+ {
+ for (emptyCnt = 0; f <= pos.max_file() && !((promotions | captures | quiets) & make_square(f, r)); ++f)
+ ++emptyCnt;
+
+ if (emptyCnt)
+ ss << emptyCnt;
+
+ if (f <= pos.max_file())
+ ss << (promotions & make_square(f, r) ? "M" : captures & make_square(f, r) ? "R" : "Y");
+ }
+
+ if (r > RANK_1)
+ ss << '/';
+ }
+ sync_cout << "highlight " << ss.str() << sync_endl;
+ }
+ }
else if (token == "ping")
{
if (!(is >> token))