MillGameAi_ab -> AIAlgorithm

This commit is contained in:
CalciteM Team 2019-09-15 19:16:31 +08:00
parent 551bff5860
commit 3cc120e8fc
9 changed files with 39 additions and 39 deletions

View File

@ -21,7 +21,7 @@
#include "evaluate.h" #include "evaluate.h"
value_t Evaluation::getValue(Game &dummyGame, Position *position, MillGameAi_ab::Node *node) value_t Evaluation::getValue(Game &dummyGame, Position *position, AIAlgorithm::Node *node)
{ {
// 初始评估值为0对先手有利则增大对后手有利则减小 // 初始评估值为0对先手有利则增大对后手有利则减小
value_t value = VALUE_ZERO; value_t value = VALUE_ZERO;

View File

@ -34,7 +34,7 @@ public:
Evaluation &operator=(const Evaluation &) = delete; Evaluation &operator=(const Evaluation &) = delete;
static value_t getValue(Game &dummyGame, Position *Position, MillGameAi_ab::Node *node); static value_t getValue(Game &dummyGame, Position *Position, AIAlgorithm::Node *node);
// 评估子力 // 评估子力
#ifdef EVALUATE_ENABLE #ifdef EVALUATE_ENABLE

View File

@ -25,8 +25,8 @@
#include "player.h" #include "player.h"
#include "misc.h" #include "misc.h"
void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame, void MoveList::generateLegalMoves(AIAlgorithm &ai, Game &dummyGame,
MillGameAi_ab::Node *node, MillGameAi_ab::Node *rootNode, AIAlgorithm::Node *node, AIAlgorithm::Node *rootNode,
move_t bestMove) move_t bestMove)
{ {
const int MOVE_PRIORITY_TABLE_SIZE = Board::N_RINGS * Board::N_SEATS; const int MOVE_PRIORITY_TABLE_SIZE = Board::N_RINGS * Board::N_SEATS;
@ -82,11 +82,11 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame,
} }
if (dummyGame.position.phase != PHASE_NOTSTARTED || node != rootNode) { if (dummyGame.position.phase != PHASE_NOTSTARTED || node != rootNode) {
ai_ab.addNode(node, VALUE_ZERO, (move_t)location, bestMove, dummyGame.position.turn); ai.addNode(node, VALUE_ZERO, (move_t)location, bestMove, dummyGame.position.turn);
} else { } else {
// 若为先手,则抢占星位 // 若为先手,则抢占星位
if (Board::isStarLocation(location)) { if (Board::isStarLocation(location)) {
ai_ab.addNode(node, VALUE_INFINITE, (move_t)location, bestMove, dummyGame.position.turn); ai.addNode(node, VALUE_INFINITE, (move_t)location, bestMove, dummyGame.position.turn);
} }
} }
} }
@ -113,7 +113,7 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame,
newLocation = moveTable[oldLocation][direction]; newLocation = moveTable[oldLocation][direction];
if (newLocation && !dummyGame.boardLocations[newLocation]) { if (newLocation && !dummyGame.boardLocations[newLocation]) {
move_t move = move_t((oldLocation << 8) + newLocation); move_t move = move_t((oldLocation << 8) + newLocation);
ai_ab.addNode(node, VALUE_ZERO, move, bestMove, dummyGame.position.turn); // (12%) ai.addNode(node, VALUE_ZERO, move, bestMove, dummyGame.position.turn); // (12%)
} }
} }
} else { } else {
@ -121,7 +121,7 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame,
for (newLocation = Board::LOCATION_BEGIN; newLocation < Board::LOCATION_END; newLocation++) { for (newLocation = Board::LOCATION_BEGIN; newLocation < Board::LOCATION_END; newLocation++) {
if (!dummyGame.boardLocations[newLocation]) { if (!dummyGame.boardLocations[newLocation]) {
move_t move = move_t((oldLocation << 8) + newLocation); move_t move = move_t((oldLocation << 8) + newLocation);
ai_ab.addNode(node, VALUE_ZERO, move, bestMove, dummyGame.position.turn); ai.addNode(node, VALUE_ZERO, move, bestMove, dummyGame.position.turn);
} }
} }
} }
@ -136,7 +136,7 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame,
for (int i = MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) { for (int i = MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) {
location = movePriorityTable[i]; location = movePriorityTable[i];
if (dummyGame.boardLocations[location] & opponent) { if (dummyGame.boardLocations[location] & opponent) {
ai_ab.addNode(node, VALUE_ZERO, (move_t)-location, bestMove, dummyGame.position.turn); ai.addNode(node, VALUE_ZERO, (move_t)-location, bestMove, dummyGame.position.turn);
} }
} }
break; break;
@ -147,7 +147,7 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame,
location = movePriorityTable[i]; location = movePriorityTable[i];
if (dummyGame.boardLocations[location] & opponent) { if (dummyGame.boardLocations[location] & opponent) {
if (dummyGame.getRule()->allowRemoveMill || !dummyGame.position.board.inHowManyMills(location)) { if (dummyGame.getRule()->allowRemoveMill || !dummyGame.position.board.inHowManyMills(location)) {
ai_ab.addNode(node, VALUE_ZERO, (move_t)-location, bestMove, dummyGame.position.turn); ai.addNode(node, VALUE_ZERO, (move_t)-location, bestMove, dummyGame.position.turn);
} }
} }
} }

View File

@ -34,8 +34,8 @@ public:
MoveList &operator=(const MoveList &) = delete; MoveList &operator=(const MoveList &) = delete;
// 生成所有合法的着法并建立子节点 // 生成所有合法的着法并建立子节点
static void generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame, static void generateLegalMoves(AIAlgorithm &ai, Game &dummyGame,
MillGameAi_ab::Node *node, MillGameAi_ab::Node *rootNode, AIAlgorithm::Node *node, AIAlgorithm::Node *rootNode,
move_t bestMove); move_t bestMove);
// 生成着法表 // 生成着法表

View File

@ -42,18 +42,18 @@ vector<hash_t> openingBook;
// 用于检测重复局面 (Position) // 用于检测重复局面 (Position)
vector<hash_t> history; vector<hash_t> history;
MillGameAi_ab::MillGameAi_ab() AIAlgorithm::AIAlgorithm()
{ {
buildRoot(); buildRoot();
} }
MillGameAi_ab::~MillGameAi_ab() AIAlgorithm::~AIAlgorithm()
{ {
deleteTree(rootNode); deleteTree(rootNode);
rootNode = nullptr; rootNode = nullptr;
} }
depth_t MillGameAi_ab::changeDepth(depth_t originalDepth) depth_t AIAlgorithm::changeDepth(depth_t originalDepth)
{ {
depth_t newDepth = originalDepth; depth_t newDepth = originalDepth;
@ -95,12 +95,12 @@ depth_t MillGameAi_ab::changeDepth(depth_t originalDepth)
return newDepth; return newDepth;
} }
void MillGameAi_ab::buildRoot() void AIAlgorithm::buildRoot()
{ {
rootNode = addNode(nullptr, VALUE_ZERO, MOVE_NONE, MOVE_NONE, PLAYER_NOBODY); rootNode = addNode(nullptr, VALUE_ZERO, MOVE_NONE, MOVE_NONE, PLAYER_NOBODY);
} }
struct MillGameAi_ab::Node *MillGameAi_ab::addNode( struct AIAlgorithm::Node *AIAlgorithm::addNode(
Node *parent, Node *parent,
value_t value, value_t value,
move_t move, move_t move,
@ -192,7 +192,7 @@ struct MillGameAi_ab::Node *MillGameAi_ab::addNode(
return newNode; return newNode;
} }
bool MillGameAi_ab::nodeLess(const Node *first, const Node *second) bool AIAlgorithm::nodeLess(const Node *first, const Node *second)
{ {
#ifdef SORT_CONSIDER_PRUNED #ifdef SORT_CONSIDER_PRUNED
if (first->value < second->value) { if (first->value < second->value) {
@ -210,7 +210,7 @@ bool MillGameAi_ab::nodeLess(const Node *first, const Node *second)
#endif #endif
} }
bool MillGameAi_ab::nodeGreater(const Node *first, const Node *second) bool AIAlgorithm::nodeGreater(const Node *first, const Node *second)
{ {
#ifdef SORT_CONSIDER_PRUNED #ifdef SORT_CONSIDER_PRUNED
if (first->value > second->value) { if (first->value > second->value) {
@ -228,7 +228,7 @@ bool MillGameAi_ab::nodeGreater(const Node *first, const Node *second)
#endif #endif
} }
void MillGameAi_ab::sortLegalMoves(Node *node) void AIAlgorithm::sortLegalMoves(Node *node)
{ {
// 这个函数对效率的影响很大,排序好的话,剪枝较早,节省时间,但不能在此函数耗费太多时间 // 这个函数对效率的影响很大,排序好的话,剪枝较早,节省时间,但不能在此函数耗费太多时间
@ -237,7 +237,7 @@ void MillGameAi_ab::sortLegalMoves(Node *node)
std::stable_sort(node->children.begin(), node->children.end(), cmp); std::stable_sort(node->children.begin(), node->children.end(), cmp);
} }
void MillGameAi_ab::deleteTree(Node *node) void AIAlgorithm::deleteTree(Node *node)
{ {
// 递归删除节点树 // 递归删除节点树
if (node == nullptr) { if (node == nullptr) {
@ -257,7 +257,7 @@ void MillGameAi_ab::deleteTree(Node *node)
#endif #endif
} }
void MillGameAi_ab::setGame(const Game &game) void AIAlgorithm::setGame(const Game &game)
{ {
// 如果规则改变重建hashmap // 如果规则改变重建hashmap
if (strcmp(this->game_.currentRule.name, game.currentRule.name) != 0) { if (strcmp(this->game_.currentRule.name, game.currentRule.name) != 0) {
@ -297,7 +297,7 @@ void MillGameAi_ab::setGame(const Game &game)
#endif #endif
} }
int MillGameAi_ab::alphaBetaPruning(depth_t depth) int AIAlgorithm::alphaBetaPruning(depth_t depth)
{ {
value_t value = VALUE_ZERO; value_t value = VALUE_ZERO;
@ -378,7 +378,7 @@ int MillGameAi_ab::alphaBetaPruning(depth_t depth)
return 0; return 0;
} }
value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t alpha, value_t beta, Node *node) value_t AIAlgorithm::alphaBetaPruning(depth_t depth, value_t alpha, value_t beta, Node *node)
{ {
// 评价值 // 评价值
value_t value; value_t value;
@ -634,7 +634,7 @@ value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t alpha, value_t be
return node->value; return node->value;
} }
const char* MillGameAi_ab::bestMove() const char* AIAlgorithm::bestMove()
{ {
vector<Node*> bestMoves; vector<Node*> bestMoves;
size_t bestMovesSize = 0; size_t bestMovesSize = 0;
@ -717,7 +717,7 @@ const char* MillGameAi_ab::bestMove()
return move2string(bestMoves[0]->move); return move2string(bestMoves[0]->move);
} }
const char *MillGameAi_ab::move2string(move_t move) const char *AIAlgorithm::move2string(move_t move)
{ {
int r, s; int r, s;

View File

@ -50,7 +50,7 @@ using namespace CTSL;
// 另外AI类是MillGame类的友元类可以访问其私有变量 // 另外AI类是MillGame类的友元类可以访问其私有变量
// 尽量不要使用MillGame的操作函数因为有参数安全性检测和不必要的赋值影响效率 // 尽量不要使用MillGame的操作函数因为有参数安全性检测和不必要的赋值影响效率
class MillGameAi_ab class AIAlgorithm
{ {
public: public:
// 定义一个节点结构体 // 定义一个节点结构体
@ -94,8 +94,8 @@ public:
#endif #endif
public: public:
MillGameAi_ab(); AIAlgorithm();
~MillGameAi_ab(); ~AIAlgorithm();
void setGame(const Game &game); void setGame(const Game &game);

View File

@ -66,7 +66,7 @@ void AiThread::setAi(const Game &game)
mutex.lock(); mutex.lock();
this->game_ = &game; this->game_ = &game;
ai_ab.setGame(*(this->game_)); ai.setGame(*(this->game_));
#ifdef TRANSPOSITION_TABLE_ENABLE #ifdef TRANSPOSITION_TABLE_ENABLE
// 新下一盘前清除哈希表 (注意可能同时存在每步之前清除) // 新下一盘前清除哈希表 (注意可能同时存在每步之前清除)
@ -82,7 +82,7 @@ void AiThread::setAi(const Game &game, depth_t depth, int time)
{ {
mutex.lock(); mutex.lock();
this->game_ = &game; this->game_ = &game;
ai_ab.setGame(game); ai.setGame(game);
aiDepth = depth; aiDepth = depth;
aiTime = time; aiTime = time;
mutex.unlock(); mutex.unlock();
@ -116,17 +116,17 @@ void AiThread::run()
continue; continue;
} }
ai_ab.setGame(*game_); ai.setGame(*game_);
emit calcStarted(); emit calcStarted();
mutex.unlock(); mutex.unlock();
if (ai_ab.alphaBetaPruning(aiDepth) == 3) { if (ai.alphaBetaPruning(aiDepth) == 3) {
// 三次重复局面和 // 三次重复局面和
loggerDebug("Draw\n\n"); loggerDebug("Draw\n\n");
strCommand = "draw"; strCommand = "draw";
QTimer::singleShot(EMIT_COMMAND_DELAY, this, &AiThread::emitCommand); QTimer::singleShot(EMIT_COMMAND_DELAY, this, &AiThread::emitCommand);
} else { } else {
strCommand = ai_ab.bestMove(); strCommand = ai.bestMove();
if (strCommand && strcmp(strCommand, "error!") != 0) { if (strCommand && strcmp(strCommand, "error!") != 0) {
loggerDebug("Computer: %s\n\n", strCommand); loggerDebug("Computer: %s\n\n", strCommand);
QTimer::singleShot(EMIT_COMMAND_DELAY, this, &AiThread::emitCommand); QTimer::singleShot(EMIT_COMMAND_DELAY, this, &AiThread::emitCommand);
@ -153,7 +153,7 @@ void AiThread::act()
mutex.lock(); mutex.lock();
waiting_ = false; waiting_ = false;
ai_ab.quit(); ai.quit();
mutex.unlock(); mutex.unlock();
} }
@ -181,7 +181,7 @@ void AiThread::stop()
requestInterruption(); requestInterruption();
mutex.lock(); mutex.lock();
waiting_ = false; waiting_ = false;
ai_ab.quit(); ai.quit();
pauseCondition.wakeAll(); pauseCondition.wakeAll();
mutex.unlock(); mutex.unlock();
} }

View File

@ -112,8 +112,8 @@ private:
// 主线程棋对象的引用 // 主线程棋对象的引用
const Game *game_; const Game *game_;
// Alpha-Beta剪枝算法类 // AI 算法类
MillGameAi_ab ai_ab; AIAlgorithm ai;
// AI的层数 // AI的层数
depth_t aiDepth; depth_t aiDepth;

View File

@ -77,7 +77,7 @@ public:
class Game class Game
{ {
// AI友元类 // AI友元类
friend class MillGameAi_ab; friend class AIAlgorithm;
public: public:
// 赢盘数 // 赢盘数