movepick: Refactor

partial_insertion_sort param 3 changed from -100 to INT_MIN.
This commit is contained in:
Calcitem 2020-12-31 15:59:04 +08:00
parent ad3742cb49
commit 94a8de7e7e
3 changed files with 48 additions and 69 deletions

View File

@ -44,7 +44,6 @@ void partial_insertion_sort(ExtMove *begin, ExtMove *end, int limit)
MovePicker::MovePicker(Position &p) MovePicker::MovePicker(Position &p)
: pos(p) : pos(p)
{ {
} }
/// MovePicker::score() assigns a numerical value to each move in a list, used /// MovePicker::score() assigns a numerical value to each move in a list, used
@ -53,51 +52,56 @@ template<GenType Type>
void MovePicker::score() void MovePicker::score()
{ {
cur = moves; cur = moves;
Square from, to;
Move m;
int ourMillsCount = 0;
int theirMillsCount = 0;
int ourPieceCount = 0;
int theirPiecesCount = 0;
int bannedCount = 0;
int emptyCount = 0;
while (cur++->move != MOVE_NONE) { while (cur++->move != MOVE_NONE) {
Move m = cur->move; m = cur->move;
Square to = to_sq(m); to = to_sq(m);
Square from = from_sq(m); from = from_sq(m);
// if stat before moving, moving phrase maybe from @-0-@ to 0-@-@, but no mill, so need sqsrc to judge // if stat before moving, moving phrase maybe from @-0-@ to 0-@-@, but no mill, so need |from| to judge
int nOurMills = pos.potential_mills_count(to, pos.side_to_move(), from); ourMillsCount = pos.potential_mills_count(to, pos.side_to_move(), from);
int nTheirMills = 0;
#ifndef SORT_MOVE_WITHOUT_HUMAN_KNOWLEDGES #ifndef SORT_MOVE_WITHOUT_HUMAN_KNOWLEDGES
// TODO: rule.mayRemoveMultiple adapt other rules // TODO: rule.mayRemoveMultiple adapt other rules
if (type_of(m) != MOVETYPE_REMOVE) { if (type_of(m) != MOVETYPE_REMOVE) {
// all phrase, check if place sq can close mill // all phrase, check if place sq can close mill
if (nOurMills > 0) { if (ourMillsCount > 0) {
cur->value += RATING_ONE_MILL * nOurMills; cur->value += RATING_ONE_MILL * ourMillsCount;
} else if (pos.get_phase() == Phase::placing) { } else if (pos.get_phase() == Phase::placing) {
// placing phrase, check if place sq can block their close mill // placing phrase, check if place sq can block their close mill
nTheirMills = pos.potential_mills_count(to, ~pos.side_to_move()); theirMillsCount = pos.potential_mills_count(to, ~pos.side_to_move());
cur->value += RATING_BLOCK_ONE_MILL * nTheirMills; cur->value += RATING_BLOCK_ONE_MILL * theirMillsCount;
} }
#if 1 #if 1
else if (pos.get_phase() == Phase::moving) { else if (pos.get_phase() == Phase::moving) {
// moving phrase, check if place sq can block their close mill // moving phrase, check if place sq can block their close mill
nTheirMills = pos.potential_mills_count(to, ~pos.side_to_move()); theirMillsCount = pos.potential_mills_count(to, ~pos.side_to_move());
if (nTheirMills) { if (theirMillsCount) {
int nOurPieces = 0; ourPieceCount = theirPiecesCount = bannedCount = emptyCount = 0;
int nTheirPieces = 0;
int nBanned = 0;
int nEmpty = 0;
pos.surrounded_pieces_count(to, nOurPieces, nTheirPieces, nBanned, nEmpty); pos.surrounded_pieces_count(to, ourPieceCount, theirPiecesCount, bannedCount, emptyCount);
if (to % 2 == 0 && nTheirPieces == 3) { if (to % 2 == 0 && theirPiecesCount == 3) {
cur->value += RATING_BLOCK_ONE_MILL * nTheirMills; cur->value += RATING_BLOCK_ONE_MILL * theirMillsCount;
} else if (to % 2 == 1 && nTheirPieces == 2 && rule.piecesCount == 12) { } else if (to % 2 == 1 && theirPiecesCount == 2 && rule.piecesCount == 12) {
cur->value += RATING_BLOCK_ONE_MILL * nTheirMills; cur->value += RATING_BLOCK_ONE_MILL * theirMillsCount;
} }
} }
} }
#endif #endif
//cur->value += nBanned; // placing phrase, place nearby ban point //cur->value += bannedCount; // placing phrase, place nearby ban point
// for 12 men, white 's 2nd move place star point is as important as close mill (TODO) // for 12 men, white 's 2nd move place star point is as important as close mill (TODO)
if (rule.piecesCount == 12 && if (rule.piecesCount == 12 &&
@ -106,35 +110,32 @@ void MovePicker::score()
cur->value += RATING_STAR_SQUARE; cur->value += RATING_STAR_SQUARE;
} }
} else { // Remove } else { // Remove
int nOurPieces = 0; ourPieceCount = theirPiecesCount = bannedCount = emptyCount = 0;
int nTheirPieces = 0;
int nBanned = 0;
int nEmpty = 0;
pos.surrounded_pieces_count(to, nOurPieces, nTheirPieces, nBanned, nEmpty); pos.surrounded_pieces_count(to, ourPieceCount, theirPiecesCount, bannedCount, emptyCount);
if (nOurMills > 0) { if (ourMillsCount > 0) {
// remove point is in our mill // remove point is in our mill
//cur->value += RATING_REMOVE_ONE_MILL * nOurMills; //cur->value += RATING_REMOVE_ONE_MILL * ourMillsCount;
if (nTheirPieces == 0) { if (theirPiecesCount == 0) {
// if remove point nearby has no their stone, preferred. // if remove point nearby has no their stone, preferred.
cur->value += 1; cur->value += 1;
if (nOurPieces > 0) { if (ourPieceCount > 0) {
// if remove point nearby our stone, preferred // if remove point nearby our stone, preferred
cur->value += nOurPieces; cur->value += ourPieceCount;
} }
} }
} }
// remove point is in their mill // remove point is in their mill
nTheirMills = pos.potential_mills_count(to, ~pos.side_to_move()); theirMillsCount = pos.potential_mills_count(to, ~pos.side_to_move());
if (nTheirMills) { if (theirMillsCount) {
if (nTheirPieces >= 2) { if (theirPiecesCount >= 2) {
// if nearby their piece, prefer do not remove // if nearby their piece, prefer do not remove
cur->value -= nTheirPieces; cur->value -= theirPiecesCount;
if (nOurPieces == 0) { if (ourPieceCount == 0) {
// if nearby has no our piece, more prefer do not remove // if nearby has no our piece, more prefer do not remove
cur->value -= 1; cur->value -= 1;
} }
@ -142,28 +143,12 @@ void MovePicker::score()
} }
// prefer remove piece that mobility is strong // prefer remove piece that mobility is strong
cur->value += nEmpty; cur->value += emptyCount;
} }
#endif // !SORT_MOVE_WITHOUT_HUMAN_KNOWLEDGES #endif // !SORT_MOVE_WITHOUT_HUMAN_KNOWLEDGES
} }
} }
/// MovePicker::select() returns the next move satisfying a predicate function.
/// It never returns the TT move.
template<MovePicker::PickType T, typename Pred>
Move MovePicker::select(Pred filter)
{
while (cur < endMoves) {
if (T == Best)
std::swap(*cur, *std::max_element(cur, endMoves));
if (*cur != ttMove && filter())
return *cur++;
cur++;
}
return MOVE_NONE;
}
/// MovePicker::next_move() is the most important method of the MovePicker class. It /// MovePicker::next_move() is the most important method of the MovePicker class. It
/// returns a new pseudo legal move every time it is called until there are no more /// returns a new pseudo legal move every time it is called until there are no more
@ -174,7 +159,7 @@ Move MovePicker::next_move()
moveCount = int(endMoves - moves); moveCount = int(endMoves - moves);
score<LEGAL>(); score<LEGAL>();
partial_insertion_sort(moves, endMoves, -100); // TODO: limit = -3000 * depth partial_insertion_sort(moves, endMoves, INT_MIN);
return *moves; return *moves;
} }

View File

@ -41,11 +41,6 @@ void partial_insertion_sort(ExtMove *begin, ExtMove *end, int limit);
/// to get a cut-off first. /// to get a cut-off first.
class MovePicker class MovePicker
{ {
enum PickType
{
Next, Best
};
public: public:
MovePicker(const MovePicker &) = delete; MovePicker(const MovePicker &) = delete;
MovePicker &operator=(const MovePicker &) = delete; MovePicker &operator=(const MovePicker &) = delete;
@ -53,7 +48,6 @@ public:
Move next_move(); Move next_move();
template<PickType T, typename Pred> Move select(Pred);
template<GenType> void score(); template<GenType> void score();
ExtMove *begin() ExtMove *begin()
@ -70,9 +64,9 @@ public:
Move ttMove { MOVE_NONE }; Move ttMove { MOVE_NONE };
ExtMove *cur { nullptr }; ExtMove *cur { nullptr };
ExtMove *endMoves { nullptr }; ExtMove *endMoves { nullptr };
ExtMove moves[MAX_MOVES]{ {MOVE_NONE, 0} }; ExtMove moves[MAX_MOVES] { {MOVE_NONE, 0} };
int moveCount{ 0 }; int moveCount { 0 };
int move_count() int move_count()
{ {

View File

@ -1504,7 +1504,7 @@ int Position::surrounded_empty_squares_count(Square s, bool includeFobidden)
return n; return n;
} }
void Position::surrounded_pieces_count(Square s, int &nOurPieces, int &nTheirPieces, int &nBanned, int &nEmpty) void Position::surrounded_pieces_count(Square s, int &ourPieceCount, int &theirPieceCount, int &bannedCount, int &emptyCount)
{ {
Square moveSquare; Square moveSquare;
@ -1519,16 +1519,16 @@ void Position::surrounded_pieces_count(Square s, int &nOurPieces, int &nTheirPie
switch (pieceType) { switch (pieceType) {
case NO_PIECE: case NO_PIECE:
nEmpty++; emptyCount++;
break; break;
case BAN_STONE: case BAN_STONE:
nBanned++; bannedCount++;
break; break;
default: default:
if (color_of(pieceType) == sideToMove) { if (color_of(pieceType) == sideToMove) {
nOurPieces++; ourPieceCount++;
} else { } else {
nTheirPieces++; theirPieceCount++;
} }
break; break;
} }