为调试AB树加入更多代码

This commit is contained in:
CalciteM 2019-06-29 17:09:37 +08:00
parent 1f04bde3ad
commit 81ceed4271
3 changed files with 50 additions and 26 deletions

Binary file not shown.

View File

@ -76,35 +76,37 @@ void NineChessAi_ab::buildChildren(Node *node)
return;
}
// 临时变量
// 对手
NineChess::Player opponent = NineChess::getOpponent(chessTemp.context.turn);
// 列出所有合法的下一招
switch (chessTemp.context.action) {
case NineChess::ACTION_CHOOSE:
case NineChess::ACTION_PLACE:
// 对于开局落子
if ((chessTemp.context.stage) & (NineChess::GAME_PLACING | NineChess::GAME_NOTSTARTED)) {
for (int i = NineChess::POS_BEGIN; i < NineChess::POS_END; i++) {
if (!chessTemp.board_[i]) {
// 对于摆子阶段
if (chessTemp.context.stage & (NineChess::GAME_PLACING | NineChess::GAME_NOTSTARTED)) {
for (int pos = NineChess::POS_BEGIN; pos < NineChess::POS_END; pos++) {
if (!chessTemp.board_[pos]) {
if (node == rootNode && chessTemp.context.stage == NineChess::GAME_NOTSTARTED) {
// 若为先手,则抢占星位
if (NineChess::isStartPoint(i)) {
addNode(node, INT32_MAX, i);
if (NineChess::isStartPoint(pos)) {
addNode(node, INF_VALUE, pos);
}
} else {
addNode(node, 0, i);
addNode(node, 0, pos);
}
}
}
}
// 对于中局移子
else {
break;
}
// 对于移子阶段
if (chessTemp.context.stage & NineChess::GAME_MOVING) {
int newPos;
for (int oldPos = NineChess::POS_BEGIN; oldPos < NineChess::POS_END; oldPos++) {
if (!chessTemp.choose(oldPos))
continue;
if ((chessTemp.context.turn == NineChess::PLAYER1 &&
(chessTemp.context.nPiecesOnBoard_1 > chessTemp.currentRule.nPiecesAtLeast || !chessTemp.currentRule.allowFlyWhenRemainThreePieces)) ||
(chessTemp.context.turn == NineChess::PLAYER2 &&
@ -112,7 +114,8 @@ void NineChessAi_ab::buildChildren(Node *node)
for (int j = 0; j < 4; j++) {
newPos = chessTemp.moveTable[oldPos][j];
if (newPos && !chessTemp.board_[newPos]) {
addNode(node, 0, (oldPos << 8) + newPos);
int move = (oldPos << 8) + newPos;
addNode(node, 0, move);
}
}
} else {
@ -406,7 +409,8 @@ int NineChessAi_ab::alphaBetaPruning(int depth)
qDebug() << "Depth:" << depth;
return alphaBetaPruning(depth, -infinity, infinity, rootNode);
return alphaBetaPruning(depth, -INF_VALUE, INF_VALUE, rootNode);
// 生成了 Alpha-Beta 树
}
int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
@ -417,24 +421,32 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
// 当前节点的MinMax值最终赋值给节点value与alpha和Beta不同
int minMax;
// 统计遍历次数
nodeCount++;
#ifdef DEBUG_AB_TREE
// 记录深度
node->depth = depth;
// 记录根节点
node->root = rootNode;
node->id = nodeCount;
node->player = chessContext->turn;
// 初始化
node->isLeaf = false;
node->isTimeout = false;
#endif
// 遍历总次数增加
nodeCount++;
// 搜索到叶子节点(决胜局面)
if (chessContext->stage == NineChess::GAME_OVER) {
node->value = evaluate(node);
if (node->value > 0)
node->value += depth;
else
node->value -= depth;
#ifdef DEBUG_AB_TREE
node->isLeaf = true;
#endif
return node->value;
}
@ -445,7 +457,12 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
node->value += depth;
else
node->value -= depth;
#ifdef DEBUG_AB_TREE
if (requiredQuit) {
node->isTimeout = true;
}
#endif
return node->value;
}
@ -478,7 +495,7 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
// 根据演算模型执行 MiniMax 检索,对先手,搜索 Max
if (chessTemp.whosTurn() == NineChess::PLAYER1) {
minMax = -infinity;
minMax = -INF_VALUE;
for (auto child : node->children) {
dataStack.push(chessTemp.context);
chessTemp.command(child->move);
@ -503,7 +520,7 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
}
// 对后手搜索Min
else {
minMax = infinity;
minMax = INF_VALUE;
for (auto child : node->children) {
dataStack.push(chessTemp.context);
chessTemp.command(child->move);

View File

@ -41,10 +41,17 @@ public:
struct Node *parent; // 父节点
list<struct Node *> children; // 子节点列表
#ifdef DEBUG_AB_TREE
struct Node *root;
NineChess::GameStage stage;
size_t id; // 结点编号
struct Node *root; // 根节点
bool isLeaf; // 是否为叶子结点, 叶子结点是决胜局面
enum NineChess::Player player; // 此招是谁下的
NineChess::GameStage stage; // 摆棋阶段还是走棋阶段
NineChess::Action action;
int depth;
int alpha;
int beta;
int minMax;
bool isTimeout; // 是否遍历到此结点时因为超时而被迫退出
string cmd;
#endif /* DEBUG_AB_TREE */
};
@ -129,7 +136,7 @@ private:
static const size_t maxHashCount = 1024 * 1024;
// 定义极大值等于16位有符号整形数字的最大值
static const int infinity = INT32_MAX;
static const int INF_VALUE = INT32_MAX;
private:
// 命令行