ai: refactor
This commit is contained in:
parent
3a83afac0d
commit
f720014bf0
|
@ -103,12 +103,12 @@ const struct NineChess::Rule NineChess::RULES[N_RULES] = {
|
|||
};
|
||||
|
||||
// 名义上是个数组,实际上相当于一个判断是否在棋盘上的函数
|
||||
const char NineChess::onBoard[(N_RINGS + 2) * N_SEATS] = {
|
||||
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
|
||||
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
|
||||
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
|
||||
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
|
||||
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'
|
||||
const int NineChess::onBoard[(N_RINGS + 2) * N_SEATS] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// 招法表
|
||||
|
@ -1449,14 +1449,15 @@ int NineChess::isInMills(int pos)
|
|||
|
||||
int NineChess::addMills(int pos)
|
||||
{
|
||||
//成三用一个64位整数了,规则如下
|
||||
//0x 00 00 00 00 00 00 00 00
|
||||
// unused unused piece1 pos1 piece2 pos2 piece3 pos3
|
||||
//piece1、piece2、piece3按照序号从小到大顺序排放
|
||||
// 成三用一个64位整数了,规则如下
|
||||
// 0x 00 00 00 00 00 00 00 00
|
||||
// unused unused piece1 pos1 piece2 pos2 piece3 pos3
|
||||
// piece1、piece2、piece3按照序号从小到大顺序排放
|
||||
uint64_t mill = 0;
|
||||
int n = 0;
|
||||
int p[3], min, temp;
|
||||
char m = board_[pos] & '\x30';
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
p[0] = pos;
|
||||
p[1] = millTable[pos][i][0];
|
||||
|
@ -1464,6 +1465,7 @@ int NineChess::addMills(int pos)
|
|||
|
||||
// 如果成三
|
||||
if (m & board_[p[1]] & board_[p[2]]) {
|
||||
|
||||
// 排序
|
||||
for (int j = 0; j < 2; j++) {
|
||||
min = j;
|
||||
|
@ -1477,6 +1479,7 @@ int NineChess::addMills(int pos)
|
|||
p[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// 成三
|
||||
mill = (((uint64_t)board_[p[0]]) << 40)
|
||||
+ (((uint64_t)p[0]) << 32)
|
||||
|
@ -1489,6 +1492,7 @@ int NineChess::addMills(int pos)
|
|||
if (currentRule.allowRemovePiecesRepeatedly) {
|
||||
n++;
|
||||
}
|
||||
|
||||
// 如果不允许相同三连反复去子
|
||||
else {
|
||||
// 迭代器
|
||||
|
|
|
@ -171,7 +171,7 @@ public:
|
|||
|
||||
private:
|
||||
// 空棋盘点位,用于判断一个棋子位置是否在棋盘上
|
||||
static const char onBoard[(N_RINGS + 2) * N_SEATS];
|
||||
static const int onBoard[(N_RINGS + 2) * N_SEATS];
|
||||
|
||||
// 招法表,每个位置有最多4种走法:顺时针、逆时针、向内、向外
|
||||
// 这个表跟规则有关,一旦规则改变需要重新修改
|
||||
|
|
|
@ -37,6 +37,7 @@ void NineChessAi_ab::buildChildren(Node *node)
|
|||
|
||||
// 临时变量
|
||||
char opponent = chessTemp.context.turn == NineChess::PLAYER1 ? 0x20 : 0x10;
|
||||
|
||||
// 列出所有合法的下一招
|
||||
switch (chessTemp.context.action) {
|
||||
case NineChess::ACTION_CHOOSE:
|
||||
|
@ -59,8 +60,10 @@ void NineChessAi_ab::buildChildren(Node *node)
|
|||
for (int i = NineChess::N_SEATS; i < (NineChess::N_RINGS + 1) * NineChess::N_SEATS; i++) {
|
||||
if (!chessTemp.choose(i))
|
||||
continue;
|
||||
if ((chessTemp.context.turn == NineChess::PLAYER1 && (chessTemp.context.nPiecesOnBoard_1 > chessTemp.currentRule.nPiecesAtLeast || !chessTemp.currentRule.allowFlyWhenRemainThreePieces)) ||
|
||||
(chessTemp.context.turn == NineChess::PLAYER2 && (chessTemp.context.nPiecesOnBoard_2 > chessTemp.currentRule.nPiecesAtLeast || !chessTemp.currentRule.allowFlyWhenRemainThreePieces))) {
|
||||
if ((chessTemp.context.turn == NineChess::PLAYER1 &&
|
||||
(chessTemp.context.nPiecesOnBoard_1 > chessTemp.currentRule.nPiecesAtLeast || !chessTemp.currentRule.allowFlyWhenRemainThreePieces)) ||
|
||||
(chessTemp.context.turn == NineChess::PLAYER2 &&
|
||||
(chessTemp.context.nPiecesOnBoard_2 > chessTemp.currentRule.nPiecesAtLeast || !chessTemp.currentRule.allowFlyWhenRemainThreePieces))) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
newPos = chessTemp.moveTable[i][j];
|
||||
if (newPos && !chessTemp.board_[newPos]) {
|
||||
|
@ -247,6 +250,7 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
|
|||
{
|
||||
// 评价值
|
||||
int value;
|
||||
|
||||
// 当前节点的MinMax值,最终赋值给节点value,与alpha和Beta不同
|
||||
int minMax;
|
||||
|
||||
|
@ -270,8 +274,9 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
|
|||
return node->value;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// 检索hashmap
|
||||
/* uint64_t hash = chessTemp.chessHash();
|
||||
uint64_t hash = chessTemp.chessHash();
|
||||
mtx.lock();
|
||||
auto itor = findHash(hash);
|
||||
if (node != rootNode) {
|
||||
|
@ -287,14 +292,16 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
|
|||
}
|
||||
}
|
||||
}
|
||||
mtx.unlock();*/
|
||||
mtx.unlock();
|
||||
#endif
|
||||
|
||||
// 生成子节点树
|
||||
buildChildren(node);
|
||||
|
||||
// 排序子节点树
|
||||
sortChildren(node);
|
||||
|
||||
// 根据演算模型执行MiniMax检索,对先手,搜索Max
|
||||
// 根据演算模型执行 MiniMax 检索,对先手,搜索 Max
|
||||
if (chessTemp.whosTurn() == NineChess::PLAYER1) {
|
||||
minMax = -infinity;
|
||||
for (auto child : node->children) {
|
||||
|
@ -303,15 +310,19 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
|
|||
value = alphaBetaPruning(depth - 1, alpha, beta, child);
|
||||
chessTemp.context = dataStack.top();
|
||||
dataStack.pop();
|
||||
|
||||
// 取最大值
|
||||
if (value > minMax)
|
||||
minMax = value;
|
||||
|
||||
if (value > alpha)
|
||||
alpha = value;
|
||||
|
||||
// 剪枝返回
|
||||
if (alpha >= beta)
|
||||
break;
|
||||
}
|
||||
|
||||
// 取最大值
|
||||
node->value = minMax;
|
||||
}
|
||||
|
@ -324,15 +335,19 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
|
|||
value = alphaBetaPruning(depth - 1, alpha, beta, child);
|
||||
chessTemp.context = dataStack.top();
|
||||
dataStack.pop();
|
||||
|
||||
// 取最小值
|
||||
if (value < minMax)
|
||||
minMax = value;
|
||||
|
||||
if (value < beta)
|
||||
beta = value;
|
||||
|
||||
// 剪枝返回
|
||||
if (alpha >= beta)
|
||||
break;
|
||||
}
|
||||
|
||||
// 取最小值
|
||||
node->value = minMax;
|
||||
}
|
||||
|
@ -344,7 +359,8 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
|
|||
child->children.clear();
|
||||
}
|
||||
|
||||
/* // 添加到hashmap
|
||||
#if 0
|
||||
// 添加到hashmap
|
||||
mtx.lock();
|
||||
if (itor == hashmap.end()) {
|
||||
HashValue hashValue;
|
||||
|
@ -360,9 +376,10 @@ int NineChessAi_ab::alphaBetaPruning(int depth, int alpha, int beta, Node *node)
|
|||
itor->second.depth = depth;
|
||||
}
|
||||
}
|
||||
mtx.unlock();*/
|
||||
mtx.unlock();
|
||||
#endif
|
||||
|
||||
// 返回
|
||||
// 返回
|
||||
return node->value;
|
||||
}
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ private:
|
|||
static const size_t maxHashCount = 1024 * 1024;
|
||||
|
||||
// 定义极大值,等于16位有符号整形数字的最大值
|
||||
static const int infinity = INT16_MAX;
|
||||
static const int infinity = INT32_MAX;
|
||||
|
||||
private:
|
||||
// 命令行
|
||||
|
|
Loading…
Reference in New Issue