MillGameAi_ab -> AIAlgorithm
This commit is contained in:
parent
551bff5860
commit
3cc120e8fc
|
@ -21,7 +21,7 @@
|
|||
|
||||
#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,对先手有利则增大,对后手有利则减小
|
||||
value_t value = VALUE_ZERO;
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
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
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#include "player.h"
|
||||
#include "misc.h"
|
||||
|
||||
void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame,
|
||||
MillGameAi_ab::Node *node, MillGameAi_ab::Node *rootNode,
|
||||
void MoveList::generateLegalMoves(AIAlgorithm &ai, Game &dummyGame,
|
||||
AIAlgorithm::Node *node, AIAlgorithm::Node *rootNode,
|
||||
move_t bestMove)
|
||||
{
|
||||
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) {
|
||||
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 {
|
||||
// 若为先手,则抢占星位
|
||||
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];
|
||||
if (newLocation && !dummyGame.boardLocations[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 {
|
||||
|
@ -121,7 +121,7 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame,
|
|||
for (newLocation = Board::LOCATION_BEGIN; newLocation < Board::LOCATION_END; newLocation++) {
|
||||
if (!dummyGame.boardLocations[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--) {
|
||||
location = movePriorityTable[i];
|
||||
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;
|
||||
|
@ -147,7 +147,7 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame,
|
|||
location = movePriorityTable[i];
|
||||
if (dummyGame.boardLocations[location] & opponent) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ public:
|
|||
MoveList &operator=(const MoveList &) = delete;
|
||||
|
||||
// 生成所有合法的着法并建立子节点
|
||||
static void generateLegalMoves(MillGameAi_ab &ai_ab, Game &dummyGame,
|
||||
MillGameAi_ab::Node *node, MillGameAi_ab::Node *rootNode,
|
||||
static void generateLegalMoves(AIAlgorithm &ai, Game &dummyGame,
|
||||
AIAlgorithm::Node *node, AIAlgorithm::Node *rootNode,
|
||||
move_t bestMove);
|
||||
|
||||
// 生成着法表
|
||||
|
|
|
@ -42,18 +42,18 @@ vector<hash_t> openingBook;
|
|||
// 用于检测重复局面 (Position)
|
||||
vector<hash_t> history;
|
||||
|
||||
MillGameAi_ab::MillGameAi_ab()
|
||||
AIAlgorithm::AIAlgorithm()
|
||||
{
|
||||
buildRoot();
|
||||
}
|
||||
|
||||
MillGameAi_ab::~MillGameAi_ab()
|
||||
AIAlgorithm::~AIAlgorithm()
|
||||
{
|
||||
deleteTree(rootNode);
|
||||
rootNode = nullptr;
|
||||
}
|
||||
|
||||
depth_t MillGameAi_ab::changeDepth(depth_t originalDepth)
|
||||
depth_t AIAlgorithm::changeDepth(depth_t originalDepth)
|
||||
{
|
||||
depth_t newDepth = originalDepth;
|
||||
|
||||
|
@ -95,12 +95,12 @@ depth_t MillGameAi_ab::changeDepth(depth_t originalDepth)
|
|||
return newDepth;
|
||||
}
|
||||
|
||||
void MillGameAi_ab::buildRoot()
|
||||
void AIAlgorithm::buildRoot()
|
||||
{
|
||||
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,
|
||||
value_t value,
|
||||
move_t move,
|
||||
|
@ -192,7 +192,7 @@ struct MillGameAi_ab::Node *MillGameAi_ab::addNode(
|
|||
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
|
||||
if (first->value < second->value) {
|
||||
|
@ -210,7 +210,7 @@ bool MillGameAi_ab::nodeLess(const Node *first, const Node *second)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool MillGameAi_ab::nodeGreater(const Node *first, const Node *second)
|
||||
bool AIAlgorithm::nodeGreater(const Node *first, const Node *second)
|
||||
{
|
||||
#ifdef SORT_CONSIDER_PRUNED
|
||||
if (first->value > second->value) {
|
||||
|
@ -228,7 +228,7 @@ bool MillGameAi_ab::nodeGreater(const Node *first, const Node *second)
|
|||
#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);
|
||||
}
|
||||
|
||||
void MillGameAi_ab::deleteTree(Node *node)
|
||||
void AIAlgorithm::deleteTree(Node *node)
|
||||
{
|
||||
// 递归删除节点树
|
||||
if (node == nullptr) {
|
||||
|
@ -257,7 +257,7 @@ void MillGameAi_ab::deleteTree(Node *node)
|
|||
#endif
|
||||
}
|
||||
|
||||
void MillGameAi_ab::setGame(const Game &game)
|
||||
void AIAlgorithm::setGame(const Game &game)
|
||||
{
|
||||
// 如果规则改变,重建hashmap
|
||||
if (strcmp(this->game_.currentRule.name, game.currentRule.name) != 0) {
|
||||
|
@ -297,7 +297,7 @@ void MillGameAi_ab::setGame(const Game &game)
|
|||
#endif
|
||||
}
|
||||
|
||||
int MillGameAi_ab::alphaBetaPruning(depth_t depth)
|
||||
int AIAlgorithm::alphaBetaPruning(depth_t depth)
|
||||
{
|
||||
value_t value = VALUE_ZERO;
|
||||
|
||||
|
@ -378,7 +378,7 @@ int MillGameAi_ab::alphaBetaPruning(depth_t depth)
|
|||
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;
|
||||
|
@ -634,7 +634,7 @@ value_t MillGameAi_ab::alphaBetaPruning(depth_t depth, value_t alpha, value_t be
|
|||
return node->value;
|
||||
}
|
||||
|
||||
const char* MillGameAi_ab::bestMove()
|
||||
const char* AIAlgorithm::bestMove()
|
||||
{
|
||||
vector<Node*> bestMoves;
|
||||
size_t bestMovesSize = 0;
|
||||
|
@ -717,7 +717,7 @@ const char* MillGameAi_ab::bestMove()
|
|||
return move2string(bestMoves[0]->move);
|
||||
}
|
||||
|
||||
const char *MillGameAi_ab::move2string(move_t move)
|
||||
const char *AIAlgorithm::move2string(move_t move)
|
||||
{
|
||||
int r, s;
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ using namespace CTSL;
|
|||
// 另外,AI类是MillGame类的友元类,可以访问其私有变量
|
||||
// 尽量不要使用MillGame的操作函数,因为有参数安全性检测和不必要的赋值,影响效率
|
||||
|
||||
class MillGameAi_ab
|
||||
class AIAlgorithm
|
||||
{
|
||||
public:
|
||||
// 定义一个节点结构体
|
||||
|
@ -94,8 +94,8 @@ public:
|
|||
#endif
|
||||
|
||||
public:
|
||||
MillGameAi_ab();
|
||||
~MillGameAi_ab();
|
||||
AIAlgorithm();
|
||||
~AIAlgorithm();
|
||||
|
||||
void setGame(const Game &game);
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ void AiThread::setAi(const Game &game)
|
|||
mutex.lock();
|
||||
|
||||
this->game_ = &game;
|
||||
ai_ab.setGame(*(this->game_));
|
||||
ai.setGame(*(this->game_));
|
||||
|
||||
#ifdef TRANSPOSITION_TABLE_ENABLE
|
||||
// 新下一盘前清除哈希表 (注意可能同时存在每步之前清除)
|
||||
|
@ -82,7 +82,7 @@ void AiThread::setAi(const Game &game, depth_t depth, int time)
|
|||
{
|
||||
mutex.lock();
|
||||
this->game_ = &game;
|
||||
ai_ab.setGame(game);
|
||||
ai.setGame(game);
|
||||
aiDepth = depth;
|
||||
aiTime = time;
|
||||
mutex.unlock();
|
||||
|
@ -116,17 +116,17 @@ void AiThread::run()
|
|||
continue;
|
||||
}
|
||||
|
||||
ai_ab.setGame(*game_);
|
||||
ai.setGame(*game_);
|
||||
emit calcStarted();
|
||||
mutex.unlock();
|
||||
|
||||
if (ai_ab.alphaBetaPruning(aiDepth) == 3) {
|
||||
if (ai.alphaBetaPruning(aiDepth) == 3) {
|
||||
// 三次重复局面和
|
||||
loggerDebug("Draw\n\n");
|
||||
strCommand = "draw";
|
||||
QTimer::singleShot(EMIT_COMMAND_DELAY, this, &AiThread::emitCommand);
|
||||
} else {
|
||||
strCommand = ai_ab.bestMove();
|
||||
strCommand = ai.bestMove();
|
||||
if (strCommand && strcmp(strCommand, "error!") != 0) {
|
||||
loggerDebug("Computer: %s\n\n", strCommand);
|
||||
QTimer::singleShot(EMIT_COMMAND_DELAY, this, &AiThread::emitCommand);
|
||||
|
@ -153,7 +153,7 @@ void AiThread::act()
|
|||
|
||||
mutex.lock();
|
||||
waiting_ = false;
|
||||
ai_ab.quit();
|
||||
ai.quit();
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ void AiThread::stop()
|
|||
requestInterruption();
|
||||
mutex.lock();
|
||||
waiting_ = false;
|
||||
ai_ab.quit();
|
||||
ai.quit();
|
||||
pauseCondition.wakeAll();
|
||||
mutex.unlock();
|
||||
}
|
||||
|
|
|
@ -112,8 +112,8 @@ private:
|
|||
// 主线程棋对象的引用
|
||||
const Game *game_;
|
||||
|
||||
// Alpha-Beta剪枝算法类
|
||||
MillGameAi_ab ai_ab;
|
||||
// AI 算法类
|
||||
AIAlgorithm ai;
|
||||
|
||||
// AI的层数
|
||||
depth_t aiDepth;
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
class Game
|
||||
{
|
||||
// AI友元类
|
||||
friend class MillGameAi_ab;
|
||||
friend class AIAlgorithm;
|
||||
|
||||
public:
|
||||
// 赢盘数
|
||||
|
|
Loading…
Reference in New Issue