From 50c7fef93c4c4eb0e5d46885f8770ddd39effd3e Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Sat, 8 May 2021 14:26:06 +0200 Subject: [PATCH] Support mobility region config for custom pieces --- src/apiutil.h | 2 +- src/parser.cpp | 71 ++++++++++++++++++++++++++++--------------------------- src/piece.h | 5 ++++ src/psqt.cpp | 2 +- src/types.h | 4 +++ src/variant.h | 2 +- 6 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/apiutil.h b/src/apiutil.h index 267e42e..7fe7c54 100644 --- a/src/apiutil.h +++ b/src/apiutil.h @@ -306,7 +306,7 @@ inline bool has_insufficient_material(Color c, const Position& pos) { for (PieceType pt : pos.piece_types()) if (pt == KING || !(pos.board_bb(c, pt) & pos.board_bb(~c, KING))) restricted |= pos.pieces(c, pt); - else if (pt >= CUSTOM_PIECES && pt <= CUSTOM_PIECES_END && pos.count(c, pt) > 0) + else if (is_custom(pt) && pos.count(c, pt) > 0) // to be conservative, assume any custom piece has mating potential return false; diff --git a/src/parser.cpp b/src/parser.cpp index 5f8de07..e25bf91 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -160,51 +160,38 @@ Variant* VariantParser::parse() { template Variant* VariantParser::parse(Variant* v) { // piece types - for (const auto& pieceInfo : pieceMap) + for (PieceType pt = PAWN; pt <= KING; ++pt) { // piece char - const auto& keyValue = config.find(pieceInfo.second->name); + std::string name = piece_name(pt); + + const auto& keyValue = config.find(name); if (keyValue != config.end() && !keyValue->second.empty()) { if (isalpha(keyValue->second.at(0))) - v->add_piece(pieceInfo.first, keyValue->second.at(0)); + v->add_piece(pt, keyValue->second.at(0)); else { if (DoCheck && keyValue->second.at(0) != '-') - std::cerr << pieceInfo.second->name << " - Invalid letter: " << keyValue->second.at(0) << std::endl; - v->remove_piece(pieceInfo.first); + std::cerr << name << " - Invalid letter: " << keyValue->second.at(0) << std::endl; + v->remove_piece(pt); + } + // betza + if (is_custom(pt)) + { + if (keyValue->second.size() > 1) + v->customPiece[pt - CUSTOM_PIECES] = keyValue->second.substr(2); + else if (DoCheck) + std::cerr << name << " - Missing Betza move notation" << std::endl; } } // mobility region - std::string capitalizedPiece = pieceInfo.second->name; + std::string capitalizedPiece = name; capitalizedPiece[0] = toupper(capitalizedPiece[0]); for (Color c : {WHITE, BLACK}) { std::string color = c == WHITE ? "White" : "Black"; - parse_attribute("mobilityRegion" + color + capitalizedPiece, v->mobilityRegion[c][pieceInfo.first]); - } - } - // custom piece types - for (PieceType pt = CUSTOM_PIECES; pt <= CUSTOM_PIECES_END; ++pt) - { - std::string customPieceName = "customPiece" + std::to_string(pt - CUSTOM_PIECES + 1); - const auto& itCustomPt = config.find(customPieceName); - if (itCustomPt != config.end() && !itCustomPt->second.empty()) - { - // piece char - if (isalpha(itCustomPt->second.at(0))) - v->add_piece(pt, itCustomPt->second.at(0)); - else - { - if (DoCheck && itCustomPt->second.at(0) != '-') - std::cerr << customPieceName << " - Invalid letter: " << itCustomPt->second.at(0) << std::endl; - v->remove_piece(pt); - } - // betza - if (itCustomPt->second.size() > 1) - v->customPiece[pt - CUSTOM_PIECES] = itCustomPt->second.substr(2); - else if (DoCheck) - std::cerr << customPieceName << " - Missing Betza move notation" << std::endl; + parse_attribute("mobilityRegion" + color + capitalizedPiece, v->mobilityRegion[c][pt]); } } // piece values @@ -375,6 +362,14 @@ Variant* VariantParser::parse(Variant* v) { // Check consistency if (DoCheck) { + // pieces + for (PieceType pt : v->pieceTypes) + { + for (Color c : {WHITE, BLACK}) + if (std::count(v->pieceToChar.begin(), v->pieceToChar.end(), v->pieceToChar[make_piece(c, pt)]) != 1) + std::cerr << piece_name(pt) << " - Ambiguous piece character: " << v->pieceToChar[make_piece(c, pt)] << std::endl; + } + // startFen if (FEN::validate_fen(v->startFen, v, v->chess960) != FEN::FEN_OK) std::cerr << "startFen - Invalid starting position: " << v->startFen << std::endl; @@ -418,11 +413,17 @@ Variant* VariantParser::parse(Variant* v) { std::cerr << "Can not use kings with blastOnCapture." << std::endl; if (v->flipEnclosedPieces) std::cerr << "Can not use kings with flipEnclosedPieces." << std::endl; - const PieceInfo* pi = pieceMap.find(v->kingType)->second; - if ( pi->hopper[MODALITY_QUIET].size() - || pi->hopper[MODALITY_CAPTURE].size() - || std::any_of(pi->steps[MODALITY_CAPTURE].begin(), pi->steps[MODALITY_CAPTURE].end(), [](const std::pair& d) { return d.second; })) - std::cerr << pi->name << " is not supported as kingType." << std::endl; + // We can not fully check custom king movements at this point + if (!is_custom(v->kingType)) + { + const PieceInfo* pi = pieceMap.find(v->kingType)->second; + if ( pi->hopper[MODALITY_QUIET].size() + || pi->hopper[MODALITY_CAPTURE].size() + || std::any_of(pi->steps[MODALITY_CAPTURE].begin(), + pi->steps[MODALITY_CAPTURE].end(), + [](const std::pair& d) { return d.second; })) + std::cerr << piece_name(v->kingType) << " is not supported as kingType." << std::endl; + } } } return v; diff --git a/src/piece.h b/src/piece.h index 0a9e9a1..ac73e6e 100644 --- a/src/piece.h +++ b/src/piece.h @@ -46,4 +46,9 @@ struct PieceMap : public std::map { extern PieceMap pieceMap; +inline std::string piece_name(PieceType pt) { + return is_custom(pt) ? "customPiece" + std::to_string(pt - CUSTOM_PIECES + 1) + : pieceMap.find(pt)->second->name; +} + #endif // #ifndef PIECE_H_INCLUDED diff --git a/src/psqt.cpp b/src/psqt.cpp index 273560b..64b8161 100644 --- a/src/psqt.cpp +++ b/src/psqt.cpp @@ -182,7 +182,7 @@ void init(const Variant* v) { PieceType strongestPiece = NO_PIECE_TYPE; for (PieceType pt : v->pieceTypes) { - if (pt >= CUSTOM_PIECES && pt <= CUSTOM_PIECES_END) + if (is_custom(pt)) { PieceValue[MG][pt] = piece_value(MG, pt); PieceValue[EG][pt] = piece_value(EG, pt); diff --git a/src/types.h b/src/types.h index a2ea3b9..a343f74 100644 --- a/src/types.h +++ b/src/types.h @@ -791,6 +791,10 @@ constexpr PieceType in_hand_piece_type(Move m) { return PieceType((m >> (2 * SQUARE_BITS + MOVE_TYPE_BITS + PIECE_TYPE_BITS)) & (PIECE_TYPE_NB - 1)); } +inline bool is_custom(PieceType pt) { + return pt >= CUSTOM_PIECES && pt <= CUSTOM_PIECES_END; +} + inline bool is_ok(Move m) { return from_sq(m) != to_sq(m) || type_of(m) == PROMOTION || type_of(m) == SPECIAL; // Catch MOVE_NULL and MOVE_NONE } diff --git a/src/variant.h b/src/variant.h index 61cbdf7..9faeec9 100644 --- a/src/variant.h +++ b/src/variant.h @@ -146,7 +146,7 @@ struct Variant { pieceToCharSynonyms[make_piece(BLACK, pt)] = tolower(c2); pieceTypes.insert(pt); // Add betza notation for custom piece - if (pt >= CUSTOM_PIECES && pt <= CUSTOM_PIECES_END) + if (is_custom(pt)) customPiece[pt - CUSTOM_PIECES] = betza; } -- 1.7.0.4