diff --git a/NineChess/src/ninechess.cpp b/NineChess/src/ninechess.cpp index ded987af..72fc6f7c 100644 --- a/NineChess/src/ninechess.cpp +++ b/NineChess/src/ninechess.cpp @@ -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 }; @@ -194,21 +194,21 @@ void NineChess::createMoveTable() for (int r = 1; r <= N_RINGS; r++) { 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位(偶数位)或是有斜线 if (!(s & 1) || this->currentRule.hasObliqueLines) { 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) { // 向外走一步的位置 - 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 diff --git a/NineChess/src/ninechess.h b/NineChess/src/ninechess.h index 9e0cb1f1..1af18430 100644 --- a/NineChess/src/ninechess.h +++ b/NineChess/src/ninechess.h @@ -33,9 +33,20 @@ public: // 8位,禁止修改! static const int N_SEATS = 8; - // 横直斜2个方向,禁止修改! + // 横直斜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) static const int POS_BEGIN = N_SEATS; static const int POS_END = ((N_RINGS + 1) * N_SEATS); @@ -196,7 +207,7 @@ private: // 招法表,每个位置有最多4种走法:顺时针、逆时针、向内、向外 // 这个表跟规则有关,一旦规则改变需要重新修改 - static int moveTable[(N_RINGS + 2) * N_SEATS][4]; + static int moveTable[(N_RINGS + 2) * N_SEATS][N_MOVE_DIRECTIONS]; // 成三表,表示棋盘上各个位置有成三关系的对应位置表 // 这个表跟规则有关,一旦规则改变需要重新修改 diff --git a/NineChess/src/ninechessai_ab.cpp b/NineChess/src/ninechessai_ab.cpp index e5318603..8ffe45f1 100644 --- a/NineChess/src/ninechessai_ab.cpp +++ b/NineChess/src/ninechessai_ab.cpp @@ -81,6 +81,7 @@ void NineChessAi_ab::buildChildren(Node *node) // 列出所有合法的下一招 switch (chessTemp.context.action) { + // 对于选子和落子动作 case NineChess::ACTION_CHOOSE: case NineChess::ACTION_PLACE: // 对于摆子阶段 @@ -111,37 +112,43 @@ void NineChessAi_ab::buildChildren(Node *node) (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[oldPos][j]; + // 对于棋盘上还有3个子以上,或不允许飞子的情况,要求必须在招法表中 + for (int moveDirection = NineChess::MOVE_DIRECTION_CLOCKWISE; moveDirection <= NineChess::MOVE_DIRECTION_OUTWARD; moveDirection++) { + // 对于原有位置,遍历四个方向的招法,如果棋盘上为空位就加到结点列表中 + newPos = chessTemp.moveTable[oldPos][moveDirection]; if (newPos && !chessTemp.board_[newPos]) { int move = (oldPos << 8) + newPos; addNode(node, 0, move); } } } else { - for (int j = NineChess::POS_BEGIN; j < NineChess::POS_END; j++) { - if (!chessTemp.board_[j]) { - addNode(node, 0, (oldPos << 8) + j); + // 对于棋盘上还有不到3个字,但允许飞子的情况,不要求在招法表中,是空位就行 + for (newPos = NineChess::POS_BEGIN; newPos < NineChess::POS_END; newPos++) { + if (!chessTemp.board_[newPos]) { + int move = (oldPos << 8) + newPos; + addNode(node, 0, move); } } } } } break; - - case NineChess::ACTION_CAPTURE: - // 全成三的情况 + + // 对于吃子动作 + case NineChess::ACTION_CAPTURE: if (chessTemp.isAllInMills(opponent)) { - for (int i = NineChess::POS_BEGIN; i < NineChess::POS_END; i++) { - if (chessTemp.board_[i] & opponent) { - addNode(node, 0, -i); + // 全成三的情况 + for (int pos = NineChess::POS_BEGIN; pos < NineChess::POS_END; pos++) { + if (chessTemp.board_[pos] & opponent) { + addNode(node, 0, -pos); } } - } else if (!chessTemp.isAllInMills(opponent)) { - for (int i = NineChess::POS_BEGIN; i < NineChess::POS_END; i++) { - if (chessTemp.board_[i] & opponent) { - if (!chessTemp.isInMills(i)) { - addNode(node, 0, -i); + } else { + // 不是全成三的情况 + for (int pos = NineChess::POS_BEGIN; pos < NineChess::POS_END; pos++) { + if (chessTemp.board_[pos] & opponent) { + if (!chessTemp.isInMills(pos)) { + addNode(node, 0, -pos); } } }