摆子优先考虑占据斜线
This commit is contained in:
parent
b0d2884dbf
commit
cc522bff7f
|
@ -1,7 +1,7 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#define DEBUG
|
||||
//#define DEBUG
|
||||
|
||||
//#define DEAL_WITH_HORIZON_EFFECT
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
|||
|
||||
//#define HASH_MAP_ENABLE
|
||||
|
||||
#define MOVE_PRIORITY_TABLE_SUPPORT
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DONOT_PLAY_SOUND
|
||||
#define DEBUG_AB_TREE
|
||||
|
@ -21,7 +23,7 @@
|
|||
//#define DONOT_PLAY_SOUND
|
||||
|
||||
#ifdef DEBUG
|
||||
#define GAME_PLACING_FIXED_DEPTH 5
|
||||
#define GAME_PLACING_FIXED_DEPTH 4
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -42,7 +44,7 @@
|
|||
#define DRAW_SEAT_NUMBER
|
||||
#endif
|
||||
|
||||
//#define IDS_SUPPORT
|
||||
#define IDS_SUPPORT
|
||||
|
||||
#define SAVE_CHESSBOOK_WHEN_ACTION_NEW_TRIGGERED
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ struct NineChessAi_ab::Node *NineChessAi_ab::addNode(Node *parent, int value, in
|
|||
|
||||
newNode->rand = rand() % 24;
|
||||
|
||||
newNode->pruned = false;
|
||||
|
||||
#ifdef DEBUG_AB_TREE
|
||||
newNode->player = player;
|
||||
newNode->root = rootNode;
|
||||
|
@ -65,7 +67,6 @@ struct NineChessAi_ab::Node *NineChessAi_ab::addNode(Node *parent, int value, in
|
|||
newNode->result = 0;
|
||||
newNode->isHash = false;
|
||||
newNode->visited = false;
|
||||
newNode->pruned = false;
|
||||
#endif
|
||||
int c, p;
|
||||
char cmd[32] = { 0 };
|
||||
|
@ -99,6 +100,26 @@ unordered_map<uint64_t, NineChessAi_ab::HashValue> NineChessAi_ab::hashmap;
|
|||
|
||||
void NineChessAi_ab::generateLegalMoves(Node *node)
|
||||
{
|
||||
const int MOVE_PRIORITY_TABLE_SIZE = NineChess::N_RINGS * NineChess::N_SEATS;
|
||||
int pos = 0;
|
||||
|
||||
#ifdef MOVE_PRIORITY_TABLE_SUPPORT
|
||||
int movePriorityTable[MOVE_PRIORITY_TABLE_SIZE] = {
|
||||
17, 19, 21, 23, // 星位
|
||||
25, 27, 29, 31, // 外圈四个顶点
|
||||
9, 11, 13, 15, // 内圈四个顶点
|
||||
16, 18, 20, 22, // 中圈十字架
|
||||
24, 26, 28, 30, // 外圈十字架
|
||||
8, 10, 12, 14, // 中圈十字架
|
||||
};
|
||||
#else
|
||||
int movePriorityTable[MOVE_PRIORITY_TABLE_SIZE] = {
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31,
|
||||
};
|
||||
#endif
|
||||
|
||||
// 如果有子节点,则返回,避免重复建立
|
||||
if (node->children.size()) {
|
||||
return;
|
||||
|
@ -114,7 +135,8 @@ void NineChessAi_ab::generateLegalMoves(Node *node)
|
|||
case NineChess::ACTION_PLACE:
|
||||
// 对于摆子阶段
|
||||
if (chessTemp.context.stage & (NineChess::GAME_PLACING | NineChess::GAME_NOTSTARTED)) {
|
||||
for (int pos = NineChess::POS_BEGIN; pos < NineChess::POS_END; pos++) {
|
||||
for (int i = 0; i < MOVE_PRIORITY_TABLE_SIZE; i++) {
|
||||
pos = movePriorityTable[i];
|
||||
if (!chessTemp.board_[pos]) {
|
||||
if (node == rootNode && chessTemp.context.stage == NineChess::GAME_NOTSTARTED) {
|
||||
// 若为先手,则抢占星位
|
||||
|
@ -131,8 +153,14 @@ void NineChessAi_ab::generateLegalMoves(Node *node)
|
|||
|
||||
// 对于移子阶段
|
||||
if (chessTemp.context.stage & NineChess::GAME_MOVING) {
|
||||
int newPos;
|
||||
for (int oldPos = NineChess::POS_BEGIN; oldPos < NineChess::POS_END; oldPos++) {
|
||||
int newPos, oldPos;
|
||||
#ifdef MOVE_PRIORITY_TABLE_SUPPORT
|
||||
// 尽量从位置理论上较差的位置向位置较好的地方移动
|
||||
for (int i = MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) {
|
||||
#else
|
||||
for (int i = 0; i < MOVE_PRIORITY_TABLE_SIZE; i++) {
|
||||
#endif // MOVE_PRIORITY_TABLE_SUPPORT
|
||||
oldPos = movePriorityTable[i];
|
||||
if (!chessTemp.choose(oldPos))
|
||||
continue;
|
||||
|
||||
|
@ -166,14 +194,16 @@ void NineChessAi_ab::generateLegalMoves(Node *node)
|
|||
case NineChess::ACTION_CAPTURE:
|
||||
if (chessTemp.isAllInMills(opponent)) {
|
||||
// 全成三的情况
|
||||
for (int pos = NineChess::POS_BEGIN; pos < NineChess::POS_END; pos++) {
|
||||
for (int i = 0; i < MOVE_PRIORITY_TABLE_SIZE; i++) {
|
||||
pos = movePriorityTable[i];
|
||||
if (chessTemp.board_[pos] & opponent) {
|
||||
addNode(node, 0, -pos, chessTemp.context.turn);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 不是全成三的情况
|
||||
for (int pos = NineChess::POS_BEGIN; pos < NineChess::POS_END; pos++) {
|
||||
for (int i = 0; i < MOVE_PRIORITY_TABLE_SIZE; i++) {
|
||||
pos = movePriorityTable[i];
|
||||
if (chessTemp.board_[pos] & opponent) {
|
||||
if (chessTemp.getRule()->allowRemoveMill || !chessTemp.isInMills(pos)) {
|
||||
addNode(node, 0, -pos, chessTemp.context.turn);
|
||||
|
@ -256,6 +286,7 @@ void NineChessAi_ab::setChess(const NineChess &chess)
|
|||
rootNode->value = 0;
|
||||
rootNode->move = 0;
|
||||
rootNode->parent = nullptr;
|
||||
rootNode->pruned = false;
|
||||
#ifdef DEBUG_AB_TREE
|
||||
rootNode->action = NineChess::ACTION_NONE;
|
||||
rootNode->stage = NineChess::GAME_NONE;
|
||||
|
@ -680,10 +711,8 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
|
|||
// 如果某个着法的结果大于 α 但小于β,那么这个着法就是走棋一方可以考虑走的
|
||||
// 否则剪枝返回
|
||||
if (alpha >= beta) {
|
||||
#ifdef DEBUG_AB_TREE
|
||||
node->pruned = true;
|
||||
break;
|
||||
#endif // DEBUG_AB_TREE
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
int rand; // 随机数,对于 value 一致的结点随机排序用
|
||||
uint64_t hash;
|
||||
bool isHash; // 是否从 Hash 读取
|
||||
bool pruned; // 是否在此处剪枝
|
||||
#ifdef DEBUG_AB_TREE
|
||||
string cmd;
|
||||
enum NineChess::Player player; // 此招是谁下的
|
||||
|
@ -64,7 +65,6 @@ public:
|
|||
bool isTimeout; // 是否遍历到此结点时因为超时而被迫退出
|
||||
bool isLeaf; // 是否为叶子结点, 叶子结点是决胜局面
|
||||
bool visited; // 是否在遍历时访问过
|
||||
bool pruned; // 是否在此处剪枝
|
||||
NineChess::GameStage stage; // 摆棋阶段还是走棋阶段
|
||||
NineChess::Action action; // 动作状态
|
||||
int nPiecesOnBoardDiff; // 场上棋子个数和对手的差值
|
||||
|
|
Loading…
Reference in New Issue