movegen: refactor

This commit is contained in:
Calcitem 2020-12-29 10:13:16 +08:00
parent 83e36576e3
commit 957b19c712
4 changed files with 83 additions and 64 deletions

View File

@ -17,14 +17,31 @@
*/ */
#include <cstring> #include <cstring>
#include <random>
#include "bitboard.h" #include "bitboard.h"
#include "rule.h" #include "rule.h"
#include "movegen.h" #include "movegen.h"
#include "mills.h" #include "mills.h"
#include "misc.h"
#include "option.h"
namespace Mills namespace Mills
{ {
/*
31 ----- 24 ----- 25
| \ | / |
| 23 -- 16 -- 17 |
| | \ | / | |
| | 15 08 09 | |
30-22-14 10-18-26
| | 13 12 11 | |
| | / | \ | |
| 21 -- 20 -- 19 |
| / | \ |
29 ----- 28 ----- 27
*/
void adjacent_squares_init() void adjacent_squares_init()
{ {
// Note: Not follow order of MoveDirection array // Note: Not follow order of MoveDirection array
@ -250,4 +267,49 @@ void adjacent_squares_init()
} }
void move_priority_list_shuffle()
{
std::array<Square, 4> movePriorityList0;
std::array<Square, 8> movePriorityList1;
std::array<Square, 4> movePriorityList2;
std::array<Square, 8> movePriorityList3;
if (rule.nTotalPiecesEachSide == 9) {
movePriorityList0 = { SQ_16, SQ_18, SQ_20, SQ_22 };
movePriorityList1 = { SQ_24, SQ_26, SQ_28, SQ_30, SQ_8, SQ_10, SQ_12, SQ_14 };
movePriorityList2 = { SQ_17, SQ_19, SQ_21, SQ_23 };
movePriorityList3 = { SQ_25, SQ_27, SQ_29, SQ_31, SQ_9, SQ_11, SQ_13, SQ_15 };
} else if (rule.nTotalPiecesEachSide == 12) {
movePriorityList0 = { SQ_17, SQ_19, SQ_21, SQ_23 };
movePriorityList1 = { SQ_25, SQ_27, SQ_29, SQ_31, SQ_9, SQ_11, SQ_13, SQ_15 };
movePriorityList2 = { SQ_16, SQ_18, SQ_20, SQ_22 };
movePriorityList3 = { SQ_24, SQ_26, SQ_28, SQ_30, SQ_8, SQ_10, SQ_12, SQ_14 };
}
if (gameOptions.getRandomMoveEnabled()) {
uint32_t seed = static_cast<uint32_t>(now());
std::shuffle(movePriorityList0.begin(), movePriorityList0.end(), std::default_random_engine(seed));
std::shuffle(movePriorityList1.begin(), movePriorityList1.end(), std::default_random_engine(seed));
std::shuffle(movePriorityList2.begin(), movePriorityList2.end(), std::default_random_engine(seed));
std::shuffle(movePriorityList3.begin(), movePriorityList3.end(), std::default_random_engine(seed));
}
for (size_t i = 0; i < 4; i++) {
MoveList<LEGAL>::movePriorityList[i + 0] = movePriorityList0[i];
}
for (size_t i = 0; i < 8; i++) {
MoveList<LEGAL>::movePriorityList[i + 4] = movePriorityList1[i];
}
for (size_t i = 0; i < 4; i++) {
MoveList<LEGAL>::movePriorityList[i + 12] = movePriorityList2[i];
}
for (size_t i = 0; i < 8; i++) {
MoveList<LEGAL>::movePriorityList[i + 16] = movePriorityList3[i];
}
}
} }

View File

@ -26,7 +26,7 @@ namespace Mills
{ {
void adjacent_squares_init(); void adjacent_squares_init();
void move_priority_list_shuffle();
} }
#endif // #ifndef MILL_H_INCLUDED #endif // #ifndef MILL_H_INCLUDED

View File

@ -35,12 +35,12 @@ ExtMove *generate<PLACE>(Position &pos, ExtMove *moveList)
{ {
ExtMove *cur = moveList; ExtMove *cur = moveList;
for (auto i : MoveList<LEGAL>::movePriorityTable) { for (auto s : MoveList<LEGAL>::movePriorityList) {
if (pos.get_board()[i]) { if (pos.get_board()[s]) {
continue; continue;
} }
*cur++ = (Move)i; *cur++ = (Move)s;
} }
return cur; return cur;
@ -51,32 +51,30 @@ ExtMove *generate<PLACE>(Position &pos, ExtMove *moveList)
template<> template<>
ExtMove *generate<MOVE>(Position &pos, ExtMove *moveList) ExtMove *generate<MOVE>(Position &pos, ExtMove *moveList)
{ {
Square newSquare, oldSquare; Square from, to;
ExtMove *cur = moveList; ExtMove *cur = moveList;
// move piece that location weak first // move piece that location weak first
for (int i = EFFECTIVE_SQUARE_NB - 1; i >= 0; i--) { for (int i = EFFECTIVE_SQUARE_NB - 1; i >= 0; i--) {
oldSquare = MoveList<LEGAL>::movePriorityTable[i]; from = MoveList<LEGAL>::movePriorityList[i];
if (!pos.select_piece(oldSquare)) { if (!pos.select_piece(from)) {
continue; continue;
} }
if (pos.pieces_count_on_board(pos.side_to_move()) > rule.nPiecesAtLeast || if (pos.pieces_count_on_board(pos.side_to_move()) > rule.nPiecesAtLeast ||
!rule.allowFlyWhenRemainThreePieces) { !rule.allowFlyWhenRemainThreePieces) {
for (int direction = MD_BEGIN; direction < MD_NB; direction++) { for (int direction = MD_BEGIN; direction < MD_NB; direction++) {
newSquare = static_cast<Square>(MoveList<LEGAL>::adjacentSquares[oldSquare][direction]); to = static_cast<Square>(MoveList<LEGAL>::adjacentSquares[from][direction]);
if (newSquare && !pos.get_board()[newSquare]) { if (to && !pos.get_board()[to]) {
Move m = make_move(oldSquare, newSquare); *cur++ = make_move(from, to);
*cur++ = (Move)m;
} }
} }
} else { } else {
// piece count < 3£¬and allow fly, if is empty point, that's ok, do not need in move list // piece count < 3£¬and allow fly, if is empty point, that's ok, do not need in move list
for (newSquare = SQ_BEGIN; newSquare < SQ_END; newSquare = static_cast<Square>(newSquare + 1)) { for (to = SQ_BEGIN; to < SQ_END; ++to) {
if (!pos.get_board()[newSquare]) { if (!pos.get_board()[to]) {
Move m = make_move(oldSquare, newSquare); *cur++ = make_move(from, to);
*cur++ = (Move)m;
} }
} }
} }
@ -99,7 +97,7 @@ ExtMove *generate<REMOVE>(Position &pos, ExtMove *moveList)
if (pos.is_all_in_mills(them)) { if (pos.is_all_in_mills(them)) {
for (int i = EFFECTIVE_SQUARE_NB - 1; i >= 0; i--) { for (int i = EFFECTIVE_SQUARE_NB - 1; i >= 0; i--) {
s = MoveList<LEGAL>::movePriorityTable[i]; s = MoveList<LEGAL>::movePriorityList[i];
if (pos.get_board()[s] & make_piece(them)) { if (pos.get_board()[s] & make_piece(them)) {
*cur++ = (Move)-s; *cur++ = (Move)-s;
} }
@ -109,7 +107,7 @@ ExtMove *generate<REMOVE>(Position &pos, ExtMove *moveList)
// not is all in mills // not is all in mills
for (int i = EFFECTIVE_SQUARE_NB - 1; i >= 0; i--) { for (int i = EFFECTIVE_SQUARE_NB - 1; i >= 0; i--) {
s = MoveList<LEGAL>::movePriorityTable[i]; s = MoveList<LEGAL>::movePriorityList[i];
if (pos.get_board()[s] & make_piece(them)) { if (pos.get_board()[s] & make_piece(them)) {
if (rule.allowRemovePieceInMill || !pos.in_how_many_mills(s, NOBODY)) { if (rule.allowRemovePieceInMill || !pos.in_how_many_mills(s, NOBODY)) {
*cur++ = (Move)-s; *cur++ = (Move)-s;
@ -154,7 +152,6 @@ ExtMove *generate<LEGAL>(Position &pos, ExtMove *moveList)
return cur; return cur;
} }
///////////////////////////////////////////////////////////////////////////////
template<> template<>
void MoveList<LEGAL>::create() void MoveList<LEGAL>::create()
@ -165,42 +162,5 @@ void MoveList<LEGAL>::create()
template<> template<>
void MoveList<LEGAL>::shuffle() void MoveList<LEGAL>::shuffle()
{ {
std::array<Square, 4> movePriorityTable0 = { SQ_17, SQ_19, SQ_21, SQ_23 }; Mills::move_priority_list_shuffle();
std::array<Square, 8> movePriorityTable1 = { SQ_25, SQ_27, SQ_29, SQ_31, SQ_9, SQ_11, SQ_13, SQ_15 };
std::array<Square, 4> movePriorityTable2 = { SQ_16, SQ_18, SQ_20, SQ_22 };
std::array<Square, 8> movePriorityTable3 = { SQ_24, SQ_26, SQ_28, SQ_30, SQ_8, SQ_10, SQ_12, SQ_14 };
if (rule.nTotalPiecesEachSide == 9)
{
movePriorityTable0 = { SQ_16, SQ_18, SQ_20, SQ_22 };
movePriorityTable1 = { SQ_24, SQ_26, SQ_28, SQ_30, SQ_8, SQ_10, SQ_12, SQ_14 };
movePriorityTable2 = { SQ_17, SQ_19, SQ_21, SQ_23 };
movePriorityTable3 = { SQ_25, SQ_27, SQ_29, SQ_31, SQ_9, SQ_11, SQ_13, SQ_15 };
}
if (gameOptions.getRandomMoveEnabled()) {
uint32_t seed = static_cast<uint32_t>(now());
std::shuffle(movePriorityTable0.begin(), movePriorityTable0.end(), std::default_random_engine(seed));
std::shuffle(movePriorityTable1.begin(), movePriorityTable1.end(), std::default_random_engine(seed));
std::shuffle(movePriorityTable2.begin(), movePriorityTable2.end(), std::default_random_engine(seed));
std::shuffle(movePriorityTable3.begin(), movePriorityTable3.end(), std::default_random_engine(seed));
}
for (size_t i = 0; i < 4; i++) {
movePriorityTable[i + 0] = movePriorityTable0[i];
}
for (size_t i = 0; i < 8; i++) {
movePriorityTable[i + 4] = movePriorityTable1[i];
}
for (size_t i = 0; i < 4; i++) {
movePriorityTable[i + 12] = movePriorityTable2[i];
}
for (size_t i = 0; i < 8; i++) {
movePriorityTable[i + 16] = movePriorityTable3[i];
}
} }

View File

@ -43,6 +43,7 @@ struct ExtMove
{ {
return move; return move;
} }
void operator=(Move m) void operator=(Move m)
{ {
move = m; move = m;
@ -59,14 +60,14 @@ inline bool operator<(const ExtMove &f, const ExtMove &s)
} }
template<GenType> template<GenType>
ExtMove *generate(/* const */ Position &pos, ExtMove *moveList); ExtMove *generate(Position &pos, ExtMove *moveList);
/// The MoveList struct is a simple wrapper around generate(). It sometimes comes /// The MoveList struct is a simple wrapper around generate(). It sometimes comes
/// in handy to use this class instead of the low level generate() function. /// in handy to use this class instead of the low level generate() function.
template<GenType T> template<GenType T>
struct MoveList struct MoveList
{ {
explicit MoveList(/* const */ Position &pos) : last(generate<T>(pos, moveList)) explicit MoveList(Position &pos) : last(generate<T>(pos, moveList))
{ {
} }
@ -93,13 +94,9 @@ struct MoveList
static void create(); static void create();
static void shuffle(); static void shuffle();
inline static std::array<Square, EFFECTIVE_SQUARE_NB> movePriorityTable { inline static std::array<Square, EFFECTIVE_SQUARE_NB> movePriorityList {SQ_NONE};
SQ_8, SQ_9, SQ_10, SQ_11, SQ_12, SQ_13, SQ_14, SQ_15,
SQ_16, SQ_17, SQ_18, SQ_19, SQ_20, SQ_21, SQ_22, SQ_23,
SQ_24, SQ_25, SQ_26, SQ_27, SQ_28, SQ_29, SQ_30, SQ_31,
};
inline static Square adjacentSquares[SQUARE_NB][MD_NB] = { {SQ_0} }; inline static Square adjacentSquares[SQUARE_NB][MD_NB] = { {SQ_NONE} };
inline static Bitboard adjacentSquaresBB[SQUARE_NB] = { 0 }; inline static Bitboard adjacentSquaresBB[SQUARE_NB] = { 0 };
private: private: