AI: 添加移动方向的enum以及其他一些重构
This commit is contained in:
parent
81ceed4271
commit
4aacd59e08
|
@ -112,7 +112,7 @@ const int NineChess::onBoard[(N_RINGS + 2) * N_SEATS] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 招法表
|
// 招法表
|
||||||
int NineChess::moveTable[(N_RINGS + 2) * N_SEATS][4] = { 0 };
|
int NineChess::moveTable[(N_RINGS + 2) * N_SEATS][N_MOVE_DIRECTIONS] = { 0 };
|
||||||
|
|
||||||
// 成三表
|
// 成三表
|
||||||
int NineChess::millTable[(N_RINGS + 2) * N_SEATS][N_DIRECTIONS][N_RINGS - 1] = { 0 };
|
int NineChess::millTable[(N_RINGS + 2) * N_SEATS][N_DIRECTIONS][N_RINGS - 1] = { 0 };
|
||||||
|
@ -194,21 +194,21 @@ void NineChess::createMoveTable()
|
||||||
for (int r = 1; r <= N_RINGS; r++) {
|
for (int r = 1; r <= N_RINGS; r++) {
|
||||||
for (int s = 0; s < N_SEATS; s++) {
|
for (int s = 0; s < N_SEATS; s++) {
|
||||||
// 顺时针走一步的位置
|
// 顺时针走一步的位置
|
||||||
moveTable[r * N_SEATS + s][0] = r * N_SEATS + (s + 1) % N_SEATS;
|
moveTable[r * N_SEATS + s][MOVE_DIRECTION_CLOCKWISE] = r * N_SEATS + (s + 1) % N_SEATS;
|
||||||
|
|
||||||
// 逆时针走一步的位置
|
// 逆时针走一步的位置
|
||||||
moveTable[r * N_SEATS + s][1] = r * N_SEATS + (s + N_SEATS - 1) % N_SEATS;
|
moveTable[r * N_SEATS + s][MOVE_DIRECTION_ANTICLOCKWISE] = r * N_SEATS + (s + N_SEATS - 1) % N_SEATS;
|
||||||
|
|
||||||
// 如果是 0、2、4、6位(偶数位)或是有斜线
|
// 如果是 0、2、4、6位(偶数位)或是有斜线
|
||||||
if (!(s & 1) || this->currentRule.hasObliqueLines) {
|
if (!(s & 1) || this->currentRule.hasObliqueLines) {
|
||||||
if (r > 1) {
|
if (r > 1) {
|
||||||
// 向内走一步的位置
|
// 向内走一步的位置
|
||||||
moveTable[r * N_SEATS + s][2] = (r - 1) * N_SEATS + s;
|
moveTable[r * N_SEATS + s][MOVE_DIRECTION_INWARD] = (r - 1) * N_SEATS + s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < N_RINGS) {
|
if (r < N_RINGS) {
|
||||||
// 向外走一步的位置
|
// 向外走一步的位置
|
||||||
moveTable[r * N_SEATS + s][3] = (r + 1) * N_SEATS + s;
|
moveTable[r * N_SEATS + s][MOVE_DIRECTION_OUTWARD] = (r + 1) * N_SEATS + s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -33,9 +33,20 @@ public:
|
||||||
// 8位,禁止修改!
|
// 8位,禁止修改!
|
||||||
static const int N_SEATS = 8;
|
static const int N_SEATS = 8;
|
||||||
|
|
||||||
// 横直斜2个方向,禁止修改!
|
// 横直斜3个方向,禁止修改!
|
||||||
static const int N_DIRECTIONS = 3;
|
static const int N_DIRECTIONS = 3;
|
||||||
|
|
||||||
|
// 移动方向,包括顺时针、逆时针、向内、向外4个方向
|
||||||
|
enum MoveDirection
|
||||||
|
{
|
||||||
|
MOVE_DIRECTION_CLOCKWISE = 0, // 顺时针
|
||||||
|
MOVE_DIRECTION_ANTICLOCKWISE = 1, // 逆时针
|
||||||
|
MOVE_DIRECTION_INWARD = 2, // 向内
|
||||||
|
MOVE_DIRECTION_OUTWARD = 3, // 向外
|
||||||
|
MOVE_DIRECTION_FLY = 4, // 飞子
|
||||||
|
N_MOVE_DIRECTIONS = 4 // 移动方向数
|
||||||
|
};
|
||||||
|
|
||||||
// 遍历棋盘点所用的起始位置,即 [8, 32)
|
// 遍历棋盘点所用的起始位置,即 [8, 32)
|
||||||
static const int POS_BEGIN = N_SEATS;
|
static const int POS_BEGIN = N_SEATS;
|
||||||
static const int POS_END = ((N_RINGS + 1) * N_SEATS);
|
static const int POS_END = ((N_RINGS + 1) * N_SEATS);
|
||||||
|
@ -196,7 +207,7 @@ private:
|
||||||
|
|
||||||
// 招法表,每个位置有最多4种走法:顺时针、逆时针、向内、向外
|
// 招法表,每个位置有最多4种走法:顺时针、逆时针、向内、向外
|
||||||
// 这个表跟规则有关,一旦规则改变需要重新修改
|
// 这个表跟规则有关,一旦规则改变需要重新修改
|
||||||
static int moveTable[(N_RINGS + 2) * N_SEATS][4];
|
static int moveTable[(N_RINGS + 2) * N_SEATS][N_MOVE_DIRECTIONS];
|
||||||
|
|
||||||
// 成三表,表示棋盘上各个位置有成三关系的对应位置表
|
// 成三表,表示棋盘上各个位置有成三关系的对应位置表
|
||||||
// 这个表跟规则有关,一旦规则改变需要重新修改
|
// 这个表跟规则有关,一旦规则改变需要重新修改
|
||||||
|
|
|
@ -81,6 +81,7 @@ void NineChessAi_ab::buildChildren(Node *node)
|
||||||
|
|
||||||
// 列出所有合法的下一招
|
// 列出所有合法的下一招
|
||||||
switch (chessTemp.context.action) {
|
switch (chessTemp.context.action) {
|
||||||
|
// 对于选子和落子动作
|
||||||
case NineChess::ACTION_CHOOSE:
|
case NineChess::ACTION_CHOOSE:
|
||||||
case NineChess::ACTION_PLACE:
|
case NineChess::ACTION_PLACE:
|
||||||
// 对于摆子阶段
|
// 对于摆子阶段
|
||||||
|
@ -111,17 +112,21 @@ void NineChessAi_ab::buildChildren(Node *node)
|
||||||
(chessTemp.context.nPiecesOnBoard_1 > chessTemp.currentRule.nPiecesAtLeast || !chessTemp.currentRule.allowFlyWhenRemainThreePieces)) ||
|
(chessTemp.context.nPiecesOnBoard_1 > chessTemp.currentRule.nPiecesAtLeast || !chessTemp.currentRule.allowFlyWhenRemainThreePieces)) ||
|
||||||
(chessTemp.context.turn == NineChess::PLAYER2 &&
|
(chessTemp.context.turn == NineChess::PLAYER2 &&
|
||||||
(chessTemp.context.nPiecesOnBoard_2 > chessTemp.currentRule.nPiecesAtLeast || !chessTemp.currentRule.allowFlyWhenRemainThreePieces))) {
|
(chessTemp.context.nPiecesOnBoard_2 > chessTemp.currentRule.nPiecesAtLeast || !chessTemp.currentRule.allowFlyWhenRemainThreePieces))) {
|
||||||
for (int j = 0; j < 4; j++) {
|
// 对于棋盘上还有3个子以上,或不允许飞子的情况,要求必须在招法表中
|
||||||
newPos = chessTemp.moveTable[oldPos][j];
|
for (int moveDirection = NineChess::MOVE_DIRECTION_CLOCKWISE; moveDirection <= NineChess::MOVE_DIRECTION_OUTWARD; moveDirection++) {
|
||||||
|
// 对于原有位置,遍历四个方向的招法,如果棋盘上为空位就加到结点列表中
|
||||||
|
newPos = chessTemp.moveTable[oldPos][moveDirection];
|
||||||
if (newPos && !chessTemp.board_[newPos]) {
|
if (newPos && !chessTemp.board_[newPos]) {
|
||||||
int move = (oldPos << 8) + newPos;
|
int move = (oldPos << 8) + newPos;
|
||||||
addNode(node, 0, move);
|
addNode(node, 0, move);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int j = NineChess::POS_BEGIN; j < NineChess::POS_END; j++) {
|
// 对于棋盘上还有不到3个字,但允许飞子的情况,不要求在招法表中,是空位就行
|
||||||
if (!chessTemp.board_[j]) {
|
for (newPos = NineChess::POS_BEGIN; newPos < NineChess::POS_END; newPos++) {
|
||||||
addNode(node, 0, (oldPos << 8) + j);
|
if (!chessTemp.board_[newPos]) {
|
||||||
|
int move = (oldPos << 8) + newPos;
|
||||||
|
addNode(node, 0, move);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,19 +134,21 @@ void NineChessAi_ab::buildChildren(Node *node)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// 对于吃子动作
|
||||||
case NineChess::ACTION_CAPTURE:
|
case NineChess::ACTION_CAPTURE:
|
||||||
// 全成三的情况
|
|
||||||
if (chessTemp.isAllInMills(opponent)) {
|
if (chessTemp.isAllInMills(opponent)) {
|
||||||
for (int i = NineChess::POS_BEGIN; i < NineChess::POS_END; i++) {
|
// 全成三的情况
|
||||||
if (chessTemp.board_[i] & opponent) {
|
for (int pos = NineChess::POS_BEGIN; pos < NineChess::POS_END; pos++) {
|
||||||
addNode(node, 0, -i);
|
if (chessTemp.board_[pos] & opponent) {
|
||||||
|
addNode(node, 0, -pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!chessTemp.isAllInMills(opponent)) {
|
} else {
|
||||||
for (int i = NineChess::POS_BEGIN; i < NineChess::POS_END; i++) {
|
// 不是全成三的情况
|
||||||
if (chessTemp.board_[i] & opponent) {
|
for (int pos = NineChess::POS_BEGIN; pos < NineChess::POS_END; pos++) {
|
||||||
if (!chessTemp.isInMills(i)) {
|
if (chessTemp.board_[pos] & opponent) {
|
||||||
addNode(node, 0, -i);
|
if (!chessTemp.isInMills(pos)) {
|
||||||
|
addNode(node, 0, -pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue