From: Fabian Fichter Date: Sat, 6 Nov 2021 14:21:38 +0000 (+0100) Subject: Support validation of lichess 3check FENs X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=8f9ddc9a0ef395e62104a10eb0cf9055b8172952;p=fairystockfish.git Support validation of lichess 3check FENs Closes #288. --- diff --git a/src/apiutil.h b/src/apiutil.h index 243d8b3..c1e717d 100644 --- a/src/apiutil.h +++ b/src/apiutil.h @@ -786,6 +786,23 @@ inline Validation check_check_count(const std::string& checkCountInfo) { return OK; } +inline Validation check_lichess_check_count(const std::string& checkCountInfo) { + if (checkCountInfo.size() != 4) + { + std::cerr << "Invalid check count '" << checkCountInfo << "'. Expects 4 characters. Actual: " << checkCountInfo.size() << " character(s)." << std::endl; + return NOK; + } + if (!isdigit(checkCountInfo[1]) || checkCountInfo[1] - '0' > 3) + { + std::cerr << "Invalid check count '" << checkCountInfo << "'. Expects 2nd character to be a digit up to 3." << std::endl; + return NOK; + } + if (!isdigit(checkCountInfo[3]) || checkCountInfo[3] - '0' > 3) { + std::cerr << "Invalid check count '" << checkCountInfo << "'. Expects 4th character to be a digit up to 3." << std::endl; + return NOK; + } + return OK; +} inline Validation check_digit_field(const std::string& field) { if (field.size() == 1 && field[0] == '-') @@ -927,17 +944,25 @@ inline FenValidation validate_fen(const std::string& fen, const Variant* v, bool // 5) Part // check check count - unsigned int optionalFields = 2 * !skipCastlingAndEp; - if (fenParts.size() >= 3 + optionalFields && v->checkCounting && fenParts.size() % 2) + unsigned int optionalInbetweenFields = 2 * !skipCastlingAndEp; + unsigned int optionalTrailingFields = 0; + if (fenParts.size() >= 3 + optionalInbetweenFields && v->checkCounting && fenParts.size() % 2) { - if (check_check_count(fenParts[2 + optionalFields]) == NOK) - return FEN_INVALID_CHECK_COUNT; - optionalFields++; + if (check_check_count(fenParts[2 + optionalInbetweenFields]) == NOK) + { + // allow valid lichess style check as alternative + if (fenParts.size() < 5 + optionalInbetweenFields || check_lichess_check_count(fenParts[fenParts.size() - 1]) == NOK) + return FEN_INVALID_CHECK_COUNT; + else + optionalTrailingFields++; + } + else + optionalInbetweenFields++; } // 6) Part // check half move counter - if (fenParts.size() >= 3 + optionalFields && !check_digit_field(fenParts[fenParts.size()-2])) + if (fenParts.size() >= 3 + optionalInbetweenFields && !check_digit_field(fenParts[fenParts.size() - 2 - optionalTrailingFields])) { std::cerr << "Invalid half move counter: '" << fenParts[fenParts.size()-2] << "'." << std::endl; return FEN_INVALID_HALF_MOVE_COUNTER; @@ -945,7 +970,7 @@ inline FenValidation validate_fen(const std::string& fen, const Variant* v, bool // 7) Part // check move counter - if (fenParts.size() >= 4 + optionalFields && !check_digit_field(fenParts[fenParts.size()-1])) + if (fenParts.size() >= 4 + optionalInbetweenFields && !check_digit_field(fenParts[fenParts.size() - 1 - optionalTrailingFields])) { std::cerr << "Invalid move counter: '" << fenParts[fenParts.size()-1] << "'." << std::endl; return FEN_INVALID_MOVE_COUNTER; diff --git a/test.py b/test.py index 7d8fc84..ff195a0 100644 --- a/test.py +++ b/test.py @@ -98,8 +98,12 @@ variant_positions = { "k7/p7/8/8/8/8/8/K7 w - - 0 1": (True, False), # K vs KP "k7/q7/8/8/8/8/8/K7 w - - 0 1": (True, False), # K vs KQ }, + "crazyhouse": { + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR/ w KQkq - 0 1": (False, False), # lichess style startpos + }, "3check": { "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 3+3 0 1": (False, False), # startpos + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 +0+2": (False, False), # lichess style check count "k7/n7/8/8/8/8/8/K7 w - - 1+2 0 1": (True, False), # K vs KN "k7/b7/8/8/8/8/8/K7 w - - 3+1 0 1": (True, False), # K vs KB }, @@ -200,6 +204,8 @@ invalid_variant_positions = { ), "3check": ( "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 3+a 0 1", # invalid check count + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 +a+2", # invalid lichess check count + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 +1+4", # invalid lichess check count ), "horde": ( "rnbqkbnr/pppppppp/8/1PP2PP1/PPPPPPPP/PPPPPPPP/PPPPPPPP/PPPPPPPK w kq - 0 1", # wrong king count