movegen: refactor
This commit is contained in:
parent
83e36576e3
commit
957b19c712
|
@ -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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue