From 287546b758bf81a3c13196b6d8482c849aa6eb3b Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Sat, 1 May 2021 11:02:34 +0200 Subject: [PATCH] Simplify piece initialization No functional change. --- src/bitboard.cpp | 124 ++++++++++++++++++++---------------------------------- src/parser.cpp | 5 +- src/piece.cpp | 25 ++++++----- src/piece.h | 11 ++--- src/psqt.cpp | 30 +++++++------- 5 files changed, 82 insertions(+), 113 deletions(-) diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 010381d..5bafcb9 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -214,67 +214,40 @@ void Bitboards::init_pieces() { { const PieceInfo* pi = pieceMap.find(pt)->second; - // Initialize rider types - AttackRiderTypes[pt] = NO_RIDER; - MoveRiderTypes[pt] = NO_RIDER; - - for (auto const& [d, limit] : pi->stepsCapture) - { - if (limit && HorseDirections.find(d) != HorseDirections.end()) - AttackRiderTypes[pt] |= RIDER_HORSE; - if (limit && ElephantDirections.find(d) != ElephantDirections.end()) - AttackRiderTypes[pt] |= RIDER_ELEPHANT; - if (limit && JanggiElephantDirections.find(d) != JanggiElephantDirections.end()) - AttackRiderTypes[pt] |= RIDER_JANGGI_ELEPHANT; - } - for (auto const& [d, limit] : pi->stepsQuiet) - { - if (limit && HorseDirections.find(d) != HorseDirections.end()) - MoveRiderTypes[pt] |= RIDER_HORSE; - if (limit && ElephantDirections.find(d) != ElephantDirections.end()) - MoveRiderTypes[pt] |= RIDER_ELEPHANT; - if (limit && JanggiElephantDirections.find(d) != JanggiElephantDirections.end()) - MoveRiderTypes[pt] |= RIDER_JANGGI_ELEPHANT; - } - for (auto const& [d, limit] : pi->sliderCapture) + // Detect rider types + for (auto modality : {MODALITY_QUIET, MODALITY_CAPTURE}) { - if (BishopDirections.find(d) != BishopDirections.end()) - AttackRiderTypes[pt] |= RIDER_BISHOP; - if (RookDirectionsH.find(d) != RookDirectionsH.end()) - AttackRiderTypes[pt] |= RIDER_ROOK_H; - if (RookDirectionsV.find(d) != RookDirectionsV.end()) - AttackRiderTypes[pt] |= RIDER_ROOK_V; - if (HorseDirections.find(d) != HorseDirections.end()) - AttackRiderTypes[pt] |= RIDER_NIGHTRIDER; - } - for (auto const& [d, limit] : pi->sliderQuiet) - { - if (BishopDirections.find(d) != BishopDirections.end()) - MoveRiderTypes[pt] |= RIDER_BISHOP; - if (RookDirectionsH.find(d) != RookDirectionsH.end()) - MoveRiderTypes[pt] |= RIDER_ROOK_H; - if (RookDirectionsV.find(d) != RookDirectionsV.end()) - MoveRiderTypes[pt] |= RIDER_ROOK_V; - if (HorseDirections.find(d) != HorseDirections.end()) - MoveRiderTypes[pt] |= RIDER_NIGHTRIDER; - } - for (auto const& [d, limit] : pi->hopperCapture) - { - if (!limit && RookDirectionsH.find(d) != RookDirectionsH.end()) - AttackRiderTypes[pt] |= RIDER_CANNON_H; - if (!limit && RookDirectionsV.find(d) != RookDirectionsV.end()) - AttackRiderTypes[pt] |= RIDER_CANNON_V; - if (!limit && BishopDirections.find(d) != BishopDirections.end()) - AttackRiderTypes[pt] |= RIDER_CANNON_DIAG; - } - for (auto const& [d, limit] : pi->hopperQuiet) - { - if (!limit && RookDirectionsH.find(d) != RookDirectionsH.end()) - MoveRiderTypes[pt] |= RIDER_CANNON_H; - if (!limit && RookDirectionsV.find(d) != RookDirectionsV.end()) - MoveRiderTypes[pt] |= RIDER_CANNON_V; - if (!limit && BishopDirections.find(d) != BishopDirections.end()) - MoveRiderTypes[pt] |= RIDER_CANNON_DIAG; + auto& riderTypes = modality == MODALITY_CAPTURE ? AttackRiderTypes[pt] : MoveRiderTypes[pt]; + riderTypes = NO_RIDER; + for (auto const& [d, limit] : pi->steps[modality]) + { + if (limit && HorseDirections.find(d) != HorseDirections.end()) + riderTypes |= RIDER_HORSE; + if (limit && ElephantDirections.find(d) != ElephantDirections.end()) + riderTypes |= RIDER_ELEPHANT; + if (limit && JanggiElephantDirections.find(d) != JanggiElephantDirections.end()) + riderTypes |= RIDER_JANGGI_ELEPHANT; + } + for (auto const& [d, limit] : pi->slider[modality]) + { + if (BishopDirections.find(d) != BishopDirections.end()) + riderTypes |= RIDER_BISHOP; + if (RookDirectionsH.find(d) != RookDirectionsH.end()) + riderTypes |= RIDER_ROOK_H; + if (RookDirectionsV.find(d) != RookDirectionsV.end()) + riderTypes |= RIDER_ROOK_V; + if (HorseDirections.find(d) != HorseDirections.end()) + riderTypes |= RIDER_NIGHTRIDER; + } + for (auto const& [d, limit] : pi->hopper[modality]) + { + if (!limit && RookDirectionsH.find(d) != RookDirectionsH.end()) + riderTypes |= RIDER_CANNON_H; + if (!limit && RookDirectionsV.find(d) != RookDirectionsV.end()) + riderTypes |= RIDER_CANNON_V; + if (!limit && BishopDirections.find(d) != BishopDirections.end()) + riderTypes |= RIDER_CANNON_DIAG; + } } // Initialize move/attack bitboards @@ -282,26 +255,21 @@ void Bitboards::init_pieces() { { for (Square s = SQ_A1; s <= SQ_MAX; ++s) { - PseudoAttacks[c][pt][s] = 0; - PseudoMoves[c][pt][s] = 0; - LeaperAttacks[c][pt][s] = 0; - LeaperMoves[c][pt][s] = 0; - for (auto const& [d, limit] : pi->stepsCapture) - { - PseudoAttacks[c][pt][s] |= safe_destination(s, c == WHITE ? d : -d); - if (!limit) - LeaperAttacks[c][pt][s] |= safe_destination(s, c == WHITE ? d : -d); - } - for (auto const& [d, limit] : pi->stepsQuiet) + for (auto modality : {MODALITY_QUIET, MODALITY_CAPTURE}) { - PseudoMoves[c][pt][s] |= safe_destination(s, c == WHITE ? d : -d); - if (!limit) - LeaperMoves[c][pt][s] |= safe_destination(s, c == WHITE ? d : -d); + auto& pseudo = modality == MODALITY_CAPTURE ? PseudoAttacks[c][pt][s] : PseudoMoves[c][pt][s]; + auto& leaper = modality == MODALITY_CAPTURE ? LeaperAttacks[c][pt][s] : LeaperMoves[c][pt][s]; + pseudo = 0; + leaper = 0; + for (auto const& [d, limit] : pi->steps[modality]) + { + pseudo |= safe_destination(s, c == WHITE ? d : -d); + if (!limit) + leaper |= safe_destination(s, c == WHITE ? d : -d); + } + pseudo |= sliding_attack(pi->slider[modality], s, 0, c); + pseudo |= sliding_attack(pi->hopper[modality], s, 0, c); } - PseudoAttacks[c][pt][s] |= sliding_attack(pi->sliderCapture, s, 0, c); - PseudoAttacks[c][pt][s] |= sliding_attack(pi->hopperCapture, s, 0, c); - PseudoMoves[c][pt][s] |= sliding_attack(pi->sliderQuiet, s, 0, c); - PseudoMoves[c][pt][s] |= sliding_attack(pi->hopperQuiet, s, 0, c); } } } diff --git a/src/parser.cpp b/src/parser.cpp index 85a5fd9..e925db3 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -418,8 +418,9 @@ Variant* VariantParser::parse(Variant* v) { if (v->flipEnclosedPieces) std::cerr << "Can not use kings with flipEnclosedPieces." << std::endl; const PieceInfo* pi = pieceMap.find(v->kingType)->second; - if (pi->hopperQuiet.size() || pi->hopperCapture.size() - || std::any_of(pi->stepsCapture.begin(), pi->stepsCapture.end(), [](const std::pair& d) { return d.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; } } diff --git a/src/piece.cpp b/src/piece.cpp index e52e195..6a900ce 100644 --- a/src/piece.cpp +++ b/src/piece.cpp @@ -54,7 +54,7 @@ namespace { PieceInfo* p = new PieceInfo(); p->name = name; p->betza = betza; - std::vector moveTypes = {}; + std::vector moveModalities = {}; bool hopper = false; bool rider = false; bool lame = false; @@ -63,13 +63,14 @@ namespace { for (std::string::size_type i = 0; i < betza.size(); i++) { char c = betza[i]; - // Move or capture + // Modality if (c == 'm' || c == 'c') - moveTypes.push_back(c); + moveModalities.push_back(c == 'c' ? MODALITY_CAPTURE : MODALITY_QUIET); // Hopper else if (c == 'p' || c == 'g') { hopper = true; + // Grasshopper if (c == 'g') distance = 1; } @@ -112,11 +113,11 @@ namespace { } if (!rider && lame) distance = -1; - // No type qualifier means m+c - if (moveTypes.size() == 0) + // No modality qualifier means m+c + if (moveModalities.size() == 0) { - moveTypes.push_back('m'); - moveTypes.push_back('c'); + moveModalities.push_back(MODALITY_QUIET); + moveModalities.push_back(MODALITY_CAPTURE); } // Define moves for (const auto& atom : atoms) @@ -133,11 +134,11 @@ namespace { else directions.push_back(s); // Add moves - for (char mt : moveTypes) + for (auto modality : moveModalities) { - auto& v = hopper ? ( mt == 'c' ? p->hopperCapture : p->hopperQuiet) - : rider ? (mt == 'c' ? p->sliderCapture : p->sliderQuiet) - : (mt == 'c' ? p->stepsCapture : p->stepsQuiet); + auto& v = hopper ? p->hopper[modality] + : rider ? p->slider[modality] + : p->steps[modality]; auto has_dir = [&](std::string s) { return std::find(directions.begin(), directions.end(), s) != directions.end(); }; @@ -160,7 +161,7 @@ namespace { } } // Reset state - moveTypes.clear(); + moveModalities.clear(); prelimDirections.clear(); hopper = false; rider = false; diff --git a/src/piece.h b/src/piece.h index 8f8479c..0a9e9a1 100644 --- a/src/piece.h +++ b/src/piece.h @@ -26,17 +26,16 @@ #include "variant.h" +enum MoveModality {MODALITY_QUIET, MODALITY_CAPTURE, MOVE_MODALITY_NB}; + /// PieceInfo struct stores information about the piece movements. struct PieceInfo { std::string name = ""; std::string betza = ""; - std::map stepsQuiet = {}; - std::map stepsCapture = {}; - std::map sliderQuiet = {}; - std::map sliderCapture = {}; - std::map hopperQuiet = {}; - std::map hopperCapture = {}; + std::map steps[MOVE_MODALITY_NB] = {}; + std::map slider[MOVE_MODALITY_NB] = {}; + std::map hopper[MOVE_MODALITY_NB] = {}; }; struct PieceMap : public std::map { diff --git a/src/psqt.cpp b/src/psqt.cpp index 026883f..273560b 100644 --- a/src/psqt.cpp +++ b/src/psqt.cpp @@ -153,16 +153,16 @@ constexpr Score PBonus[RANK_NB][FILE_NB] = Value piece_value(Phase phase, PieceType pt) { const PieceInfo* pi = pieceMap.find(pt)->second; - int v0 = (phase == MG ? 55 : 60) * pi->stepsCapture.size() - + (phase == MG ? 30 : 40) * pi->stepsQuiet.size() - + (phase == MG ? 185 : 180) * pi->sliderCapture.size() - + (phase == MG ? 55 : 50) * pi->sliderQuiet.size() + int v0 = (phase == MG ? 55 : 60) * pi->steps[MODALITY_CAPTURE].size() + + (phase == MG ? 30 : 40) * pi->steps[MODALITY_QUIET].size() + + (phase == MG ? 185 : 180) * pi->slider[MODALITY_CAPTURE].size() + + (phase == MG ? 55 : 50) * pi->slider[MODALITY_QUIET].size() // Hoppers are more useful with more pieces on the board - + (phase == MG ? 100 : 80) * pi->hopperCapture.size() - + (phase == MG ? 80 : 60) * pi->hopperQuiet.size() + + (phase == MG ? 100 : 80) * pi->hopper[MODALITY_CAPTURE].size() + + (phase == MG ? 80 : 60) * pi->hopper[MODALITY_QUIET].size() // Rook sliding directions are more valuable, especially in endgame - + (phase == MG ? 10 : 30) * std::count_if(pi->sliderCapture.begin(), pi->sliderCapture.end(), [](const std::pair& d) { return std::abs(d.first) == NORTH || std::abs(d.first) == 1; }) - + (phase == MG ? 30 : 45) * std::count_if(pi->sliderQuiet.begin(), pi->sliderQuiet.end(), [](const std::pair& d) { return std::abs(d.first) == NORTH || std::abs(d.first) == 1; }); + + (phase == MG ? 10 : 30) * std::count_if(pi->slider[MODALITY_CAPTURE].begin(), pi->slider[MODALITY_CAPTURE].end(), [](const std::pair& d) { return std::abs(d.first) == NORTH || std::abs(d.first) == 1; }) + + (phase == MG ? 30 : 45) * std::count_if(pi->slider[MODALITY_QUIET].begin(), pi->slider[MODALITY_QUIET].end(), [](const std::pair& d) { return std::abs(d.first) == NORTH || std::abs(d.first) == 1; }); return Value(v0 * exp(double(v0) / 10000)); } @@ -211,9 +211,9 @@ void init(const Variant* v) { } const PieceInfo* pi = pieceMap.find(pt)->second; - bool isSlider = pi->sliderQuiet.size() || pi->sliderCapture.size() || pi->hopperQuiet.size() || pi->hopperCapture.size(); - bool isPawn = !isSlider && pi->stepsQuiet.size() && !std::any_of(pi->stepsQuiet.begin(), pi->stepsQuiet.end(), [](const std::pair& d) { return d.first < SOUTH / 2; }); - bool isSlowLeaper = !isSlider && !std::any_of(pi->stepsQuiet.begin(), pi->stepsQuiet.end(), [](const std::pair& d) { return dist(d.first) > 1; }); + bool isSlider = pi->slider[MODALITY_QUIET].size() || pi->slider[MODALITY_CAPTURE].size() || pi->hopper[MODALITY_QUIET].size() || pi->hopper[MODALITY_CAPTURE].size(); + bool isPawn = !isSlider && pi->steps[MODALITY_QUIET].size() && !std::any_of(pi->steps[MODALITY_QUIET].begin(), pi->steps[MODALITY_QUIET].end(), [](const std::pair& d) { return d.first < SOUTH / 2; }); + bool isSlowLeaper = !isSlider && !std::any_of(pi->steps[MODALITY_QUIET].begin(), pi->steps[MODALITY_QUIET].end(), [](const std::pair& d) { return dist(d.first) > 1; }); // Scale slider piece values with board size if (isSlider) @@ -222,8 +222,8 @@ void init(const Variant* v) { constexpr int rm = 5; constexpr int r0 = rm + RANK_8; int r1 = rm + (v->maxRank + v->maxFile - 2 * v->capturesToHand) / 2; - int leaper = pi->stepsQuiet.size() + pi->stepsCapture.size(); - int slider = pi->sliderQuiet.size() + pi->sliderCapture.size() + pi->hopperQuiet.size() + pi->hopperCapture.size(); + int leaper = pi->steps[MODALITY_QUIET].size() + pi->steps[MODALITY_CAPTURE].size(); + int slider = pi->slider[MODALITY_QUIET].size() + pi->slider[MODALITY_CAPTURE].size() + pi->hopper[MODALITY_QUIET].size() + pi->hopper[MODALITY_CAPTURE].size(); score = make_score(mg_value(score) * (lc * leaper + r1 * slider) / (lc * leaper + r0 * slider), eg_value(score) * (lc * leaper + r1 * slider) / (lc * leaper + r0 * slider)); } @@ -246,7 +246,7 @@ void init(const Variant* v) { // Increase leapers' value in makpong else if (v->makpongRule) { - if (std::any_of(pi->stepsCapture.begin(), pi->stepsCapture.end(), [](const std::pair& d) { return dist(d.first) > 1 && !d.second; })) + if (std::any_of(pi->steps[MODALITY_CAPTURE].begin(), pi->steps[MODALITY_CAPTURE].end(), [](const std::pair& d) { return dist(d.first) > 1 && !d.second; })) score = make_score(mg_value(score) * 4200 / (3500 + mg_value(score)), eg_value(score) * 4700 / (3500 + mg_value(score))); } @@ -269,7 +269,7 @@ void init(const Variant* v) { // For antichess variants, use negative piece values if (v->extinctionValue == VALUE_MATE) - score = -make_score(mg_value(score) / 8, eg_value(score) / 8 / (1 + !pi->sliderCapture.size())); + score = -make_score(mg_value(score) / 8, eg_value(score) / 8 / (1 + !pi->slider[MODALITY_CAPTURE].size())); // Override variant piece value if (v->pieceValue[MG][pt]) -- 1.7.0.4