parent
39d0e34f9f
commit
a526dbff2c
|
@ -32,6 +32,7 @@
|
||||||
#include "endgame.h"
|
#include "endgame.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "option.h"
|
#include "option.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
#define SORT_NAME nodep
|
#define SORT_NAME nodep
|
||||||
#define SORT_TYPE AIAlgorithm::Node*
|
#define SORT_TYPE AIAlgorithm::Node*
|
||||||
|
@ -314,8 +315,22 @@ void AIAlgorithm::sortMoves(Node *node)
|
||||||
|
|
||||||
gSideToMove = tempGame.position.sideToMove; // TODO: 暂时用全局变量
|
gSideToMove = tempGame.position.sideToMove; // TODO: 暂时用全局变量
|
||||||
|
|
||||||
// 此处选用排序算法
|
// 此处选用排序算法, 各算法耗时统计如下:
|
||||||
|
/*
|
||||||
|
* sqrt_sort_sort_ins: 100% (4272)
|
||||||
|
* bubble_sort: 115% (4920)
|
||||||
|
* binary_insertion_sort: 122% (5209)
|
||||||
|
* merge_sort: 131% (5612)
|
||||||
|
* grail_lazy_stable_sort: 175% (7471)
|
||||||
|
* tim_sort: 185% (7885)
|
||||||
|
* selection_sort: 202% (8642)
|
||||||
|
* rec_stable_sort: 226% (9646)
|
||||||
|
* sqrt_sort: 275% (11729)
|
||||||
|
*/
|
||||||
|
auto timeStart = now();
|
||||||
NODE_PTR_SORT_FUN(sqrt_sort_sort_ins)(node->children, node->childrenSize);
|
NODE_PTR_SORT_FUN(sqrt_sort_sort_ins)(node->children, node->childrenSize);
|
||||||
|
auto timeEnd = now();
|
||||||
|
sortTime += (timeEnd - timeStart);
|
||||||
|
|
||||||
#ifdef DEBUG_SORT
|
#ifdef DEBUG_SORT
|
||||||
if (tempGame.position.sideToMove == PLAYER_BLACK) {
|
if (tempGame.position.sideToMove == PLAYER_BLACK) {
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "endgame.h"
|
#include "endgame.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "memmgr.h"
|
#include "memmgr.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace CTSL;
|
using namespace CTSL;
|
||||||
|
@ -98,6 +99,9 @@ public:
|
||||||
|
|
||||||
MemoryManager memmgr;
|
MemoryManager memmgr;
|
||||||
|
|
||||||
|
// 排序算法耗时 (ms)
|
||||||
|
TimePoint sortTime { 0 };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AIAlgorithm();
|
AIAlgorithm();
|
||||||
~AIAlgorithm();
|
~AIAlgorithm();
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#ifndef MISC_H
|
#ifndef MISC_H
|
||||||
#define MISC_H
|
#define MISC_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
using TimePoint = std::chrono::milliseconds::rep; // A value in milliseconds
|
using TimePoint = std::chrono::milliseconds::rep; // A value in milliseconds
|
||||||
|
|
||||||
static_assert(sizeof(TimePoint) == sizeof(int64_t), "TimePoint should be 64 bits");
|
static_assert(sizeof(TimePoint) == sizeof(int64_t), "TimePoint should be 64 bits");
|
||||||
|
|
|
@ -116,9 +116,12 @@ private:
|
||||||
// 主线程棋对象的引用
|
// 主线程棋对象的引用
|
||||||
const Game *game;
|
const Game *game;
|
||||||
|
|
||||||
|
public: // TODO: Change to private
|
||||||
// AI 算法类
|
// AI 算法类
|
||||||
AIAlgorithm ai;
|
AIAlgorithm ai;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
// AI的层数
|
// AI的层数
|
||||||
depth_t depth;
|
depth_t depth;
|
||||||
|
|
||||||
|
|
|
@ -61,19 +61,19 @@ GameController::GameController(GameScene & scene, QObject * parent) :
|
||||||
isAiPlayer[1] = false,
|
isAiPlayer[1] = false,
|
||||||
isAiPlayer[2] = false,
|
isAiPlayer[2] = false,
|
||||||
|
|
||||||
ai[1] = new AiThread(1);
|
aiThread[1] = new AiThread(1);
|
||||||
ai[2] = new AiThread(2);
|
aiThread[2] = new AiThread(2);
|
||||||
|
|
||||||
gameReset();
|
gameReset();
|
||||||
|
|
||||||
// 关联AI和控制器的着法命令行
|
// 关联AI和控制器的着法命令行
|
||||||
connect(ai[1], SIGNAL(command(const QString &, bool)),
|
connect(aiThread[1], SIGNAL(command(const QString &, bool)),
|
||||||
this, SLOT(command(const QString &, bool)));
|
this, SLOT(command(const QString &, bool)));
|
||||||
connect(ai[2], SIGNAL(command(const QString &, bool)),
|
connect(aiThread[2], SIGNAL(command(const QString &, bool)),
|
||||||
this, SLOT(command(const QString &, bool)));
|
this, SLOT(command(const QString &, bool)));
|
||||||
|
|
||||||
// 关联AI和网络类的着法命令行
|
// 关联AI和网络类的着法命令行
|
||||||
connect(ai[1]->getClient(), SIGNAL(command(const QString &, bool)),
|
connect(aiThread[1]->getClient(), SIGNAL(command(const QString &, bool)),
|
||||||
this, SLOT(command(const QString &, bool)));
|
this, SLOT(command(const QString &, bool)));
|
||||||
|
|
||||||
// 安装事件过滤器监视scene的各个事件,
|
// 安装事件过滤器监视scene的各个事件,
|
||||||
|
@ -88,13 +88,13 @@ GameController::~GameController()
|
||||||
killTimer(timeID);
|
killTimer(timeID);
|
||||||
|
|
||||||
// 停掉线程
|
// 停掉线程
|
||||||
ai[1]->stop();
|
aiThread[1]->stop();
|
||||||
ai[2]->stop();
|
aiThread[2]->stop();
|
||||||
ai[1]->wait();
|
aiThread[1]->wait();
|
||||||
ai[2]->wait();
|
aiThread[2]->wait();
|
||||||
|
|
||||||
delete ai[1];
|
delete aiThread[1];
|
||||||
delete ai[2];
|
delete aiThread[2];
|
||||||
|
|
||||||
#ifdef ENDGAME_LEARNING
|
#ifdef ENDGAME_LEARNING
|
||||||
if (options.getLearnEndgameEnabled()) {
|
if (options.getLearnEndgameEnabled()) {
|
||||||
|
@ -152,8 +152,8 @@ void GameController::gameReset()
|
||||||
|
|
||||||
// 停掉线程
|
// 停掉线程
|
||||||
if (!options.getAutoRestart()) {
|
if (!options.getAutoRestart()) {
|
||||||
ai[1]->stop();
|
aiThread[1]->stop();
|
||||||
ai[2]->stop();
|
aiThread[2]->stop();
|
||||||
isAiPlayer[1] = false;
|
isAiPlayer[1] = false;
|
||||||
isAiPlayer[2] = false;
|
isAiPlayer[2] = false;
|
||||||
}
|
}
|
||||||
|
@ -290,13 +290,13 @@ void GameController::setEngine(int id, bool arg)
|
||||||
isAiPlayer[id] = arg;
|
isAiPlayer[id] = arg;
|
||||||
|
|
||||||
if (arg) {
|
if (arg) {
|
||||||
ai[id]->setAi(game);
|
aiThread[id]->setAi(game);
|
||||||
if (ai[id]->isRunning())
|
if (aiThread[id]->isRunning())
|
||||||
ai[id]->resume();
|
aiThread[id]->resume();
|
||||||
else
|
else
|
||||||
ai[id]->start();
|
aiThread[id]->start();
|
||||||
} else {
|
} else {
|
||||||
ai[id]->stop();
|
aiThread[id]->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,32 +313,32 @@ void GameController::setEngine2(bool arg)
|
||||||
void GameController::setAiDepthTime(depth_t depth1, int time1, depth_t depth2, int time2)
|
void GameController::setAiDepthTime(depth_t depth1, int time1, depth_t depth2, int time2)
|
||||||
{
|
{
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->stop();
|
aiThread[1]->stop();
|
||||||
ai[1]->wait();
|
aiThread[1]->wait();
|
||||||
}
|
}
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->stop();
|
aiThread[2]->stop();
|
||||||
ai[2]->wait();
|
aiThread[2]->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
ai[1]->setAi(game, depth1, time1);
|
aiThread[1]->setAi(game, depth1, time1);
|
||||||
ai[2]->setAi(game, depth2, time2);
|
aiThread[2]->setAi(game, depth2, time2);
|
||||||
|
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->start();
|
aiThread[1]->start();
|
||||||
}
|
}
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->start();
|
aiThread[2]->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameController::getAiDepthTime(depth_t &depth1, int &time1, depth_t &depth2, int &time2)
|
void GameController::getAiDepthTime(depth_t &depth1, int &time1, depth_t &depth2, int &time2)
|
||||||
{
|
{
|
||||||
depth1 = ai[1]->getDepth();
|
depth1 = aiThread[1]->getDepth();
|
||||||
time1 = ai[1]->getTimeLimit();
|
time1 = aiThread[1]->getTimeLimit();
|
||||||
|
|
||||||
depth2 = ai[2]->getDepth();
|
depth2 = aiThread[2]->getDepth();
|
||||||
time2 = ai[2]->getTimeLimit();
|
time2 = aiThread[2]->getTimeLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameController::setAnimation(bool arg)
|
void GameController::setAnimation(bool arg)
|
||||||
|
@ -394,12 +394,12 @@ void GameController::setLearnEndgame(bool enabled)
|
||||||
void GameController::flip()
|
void GameController::flip()
|
||||||
{
|
{
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->stop();
|
aiThread[1]->stop();
|
||||||
ai[1]->wait();
|
aiThread[1]->wait();
|
||||||
}
|
}
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->stop();
|
aiThread[2]->stop();
|
||||||
ai[2]->wait();
|
aiThread[2]->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
game.position.board.mirror(game.cmdlist, game.cmdline, game.move, game.currentSquare);
|
game.position.board.mirror(game.cmdlist, game.cmdline, game.move, game.currentSquare);
|
||||||
|
@ -418,15 +418,15 @@ void GameController::flip()
|
||||||
else
|
else
|
||||||
phaseChange(currentRow, true);
|
phaseChange(currentRow, true);
|
||||||
|
|
||||||
ai[1]->setAi(game);
|
aiThread[1]->setAi(game);
|
||||||
ai[2]->setAi(game);
|
aiThread[2]->setAi(game);
|
||||||
|
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->start();
|
aiThread[1]->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->start();
|
aiThread[2]->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,12 +434,12 @@ void GameController::flip()
|
||||||
void GameController::mirror()
|
void GameController::mirror()
|
||||||
{
|
{
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->stop();
|
aiThread[1]->stop();
|
||||||
ai[1]->wait();
|
aiThread[1]->wait();
|
||||||
}
|
}
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->stop();
|
aiThread[2]->stop();
|
||||||
ai[2]->wait();
|
aiThread[2]->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
game.position.board.mirror(game.cmdlist, game.cmdline, game.move, game.currentSquare);
|
game.position.board.mirror(game.cmdlist, game.cmdline, game.move, game.currentSquare);
|
||||||
|
@ -460,15 +460,15 @@ void GameController::mirror()
|
||||||
else
|
else
|
||||||
phaseChange(currentRow, true);
|
phaseChange(currentRow, true);
|
||||||
|
|
||||||
ai[1]->setAi(game);
|
aiThread[1]->setAi(game);
|
||||||
ai[2]->setAi(game);
|
aiThread[2]->setAi(game);
|
||||||
|
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->start();
|
aiThread[1]->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->start();
|
aiThread[2]->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,12 +476,12 @@ void GameController::mirror()
|
||||||
void GameController::turnRight()
|
void GameController::turnRight()
|
||||||
{
|
{
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->stop();
|
aiThread[1]->stop();
|
||||||
ai[1]->wait();
|
aiThread[1]->wait();
|
||||||
}
|
}
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->stop();
|
aiThread[2]->stop();
|
||||||
ai[2]->wait();
|
aiThread[2]->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
game.position.board.rotate(-90, game.cmdlist, game.cmdline, game.move, game.currentSquare);
|
game.position.board.rotate(-90, game.cmdlist, game.cmdline, game.move, game.currentSquare);
|
||||||
|
@ -500,15 +500,15 @@ void GameController::turnRight()
|
||||||
else
|
else
|
||||||
phaseChange(currentRow, true);
|
phaseChange(currentRow, true);
|
||||||
|
|
||||||
ai[1]->setAi(game);
|
aiThread[1]->setAi(game);
|
||||||
ai[2]->setAi(game);
|
aiThread[2]->setAi(game);
|
||||||
|
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->start();
|
aiThread[1]->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->start();
|
aiThread[2]->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,12 +516,12 @@ void GameController::turnRight()
|
||||||
void GameController::turnLeft()
|
void GameController::turnLeft()
|
||||||
{
|
{
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->stop();
|
aiThread[1]->stop();
|
||||||
ai[1]->wait();
|
aiThread[1]->wait();
|
||||||
}
|
}
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->stop();
|
aiThread[2]->stop();
|
||||||
ai[2]->wait();
|
aiThread[2]->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
game.position.board.rotate(90, game.cmdlist, game.cmdline, game.move, game.currentSquare);
|
game.position.board.rotate(90, game.cmdlist, game.cmdline, game.move, game.currentSquare);
|
||||||
|
@ -536,13 +536,13 @@ void GameController::turnLeft()
|
||||||
// 刷新显示
|
// 刷新显示
|
||||||
updateScence();
|
updateScence();
|
||||||
|
|
||||||
ai[1]->setAi(game);
|
aiThread[1]->setAi(game);
|
||||||
ai[2]->setAi(game);
|
aiThread[2]->setAi(game);
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->start();
|
aiThread[1]->start();
|
||||||
}
|
}
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->start();
|
aiThread[2]->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,22 +755,22 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
if (game.whoWin() == PLAYER_NOBODY) {
|
if (game.whoWin() == PLAYER_NOBODY) {
|
||||||
if (game.position.sideToMove == PLAYER_BLACK) {
|
if (game.position.sideToMove == PLAYER_BLACK) {
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->resume();
|
aiThread[1]->resume();
|
||||||
}
|
}
|
||||||
if (isAiPlayer[2])
|
if (isAiPlayer[2])
|
||||||
ai[2]->pause();
|
aiThread[2]->pause();
|
||||||
} else {
|
} else {
|
||||||
if (isAiPlayer[1])
|
if (isAiPlayer[1])
|
||||||
ai[1]->pause();
|
aiThread[1]->pause();
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->resume();
|
aiThread[2]->resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果已经决出胜负
|
// 如果已经决出胜负
|
||||||
else {
|
else {
|
||||||
ai[1]->stop();
|
aiThread[1]->stop();
|
||||||
ai[2]->stop();
|
aiThread[2]->stop();
|
||||||
|
|
||||||
// 弹框
|
// 弹框
|
||||||
//message = QString::fromStdString(game.getTips());
|
//message = QString::fromStdString(game.getTips());
|
||||||
|
@ -816,10 +816,10 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
|
||||||
Q_UNUSED(hasSound)
|
Q_UNUSED(hasSound)
|
||||||
|
|
||||||
// 防止接收滞后结束的线程发送的指令
|
// 防止接收滞后结束的线程发送的指令
|
||||||
if (sender() == ai[1] && !isAiPlayer[1])
|
if (sender() == aiThread[1] && !isAiPlayer[1])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (sender() == ai[2] && !isAiPlayer[2])
|
if (sender() == aiThread[2] && !isAiPlayer[2])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// 声音
|
// 声音
|
||||||
|
@ -895,22 +895,27 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
|
||||||
if (game.whoWin() == PLAYER_NOBODY) {
|
if (game.whoWin() == PLAYER_NOBODY) {
|
||||||
if (game.position.sideToMove == PLAYER_BLACK) {
|
if (game.position.sideToMove == PLAYER_BLACK) {
|
||||||
if (isAiPlayer[1]) {
|
if (isAiPlayer[1]) {
|
||||||
ai[1]->resume();
|
aiThread[1]->resume();
|
||||||
}
|
}
|
||||||
if (isAiPlayer[2])
|
if (isAiPlayer[2])
|
||||||
ai[2]->pause();
|
aiThread[2]->pause();
|
||||||
} else {
|
} else {
|
||||||
if (isAiPlayer[1])
|
if (isAiPlayer[1])
|
||||||
ai[1]->pause();
|
aiThread[1]->pause();
|
||||||
if (isAiPlayer[2]) {
|
if (isAiPlayer[2]) {
|
||||||
ai[2]->resume();
|
aiThread[2]->resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果已经决出胜负
|
// 如果已经决出胜负
|
||||||
else {
|
else {
|
||||||
ai[1]->stop();
|
aiThread[1]->stop();
|
||||||
ai[2]->stop();
|
aiThread[2]->stop();
|
||||||
|
|
||||||
|
loggerDebug("Sort Time: %ld + %ld = %ldms\n",
|
||||||
|
aiThread[1]->ai.sortTime, aiThread[2]->ai.sortTime,
|
||||||
|
(aiThread[1]->ai.sortTime + aiThread[2]->ai.sortTime));
|
||||||
|
aiThread[1]->ai.sortTime = aiThread[2]->ai.sortTime = 0;
|
||||||
|
|
||||||
if (options.getAutoRestart()) {
|
if (options.getAutoRestart()) {
|
||||||
gameReset();
|
gameReset();
|
||||||
|
@ -935,9 +940,9 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
|
||||||
// 网络: 将着法放到服务器的发送列表中
|
// 网络: 将着法放到服务器的发送列表中
|
||||||
if (isAiPlayer[1])
|
if (isAiPlayer[1])
|
||||||
{
|
{
|
||||||
ai[1]->getServer()->setAction(cmd);
|
aiThread[1]->getServer()->setAction(cmd);
|
||||||
} else if (isAiPlayer[2]) {
|
} else if (isAiPlayer[2]) {
|
||||||
ai[1]->getServer()->setAction(cmd); // 注意: 同样是AI1
|
aiThread[1]->getServer()->setAction(cmd); // 注意: 同样是AI1
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1116,6 +1121,6 @@ bool GameController::updateScence(Game &g)
|
||||||
|
|
||||||
void GameController::showNetworkWindow()
|
void GameController::showNetworkWindow()
|
||||||
{
|
{
|
||||||
ai[1]->getServer()->show();
|
aiThread[1]->getServer()->show();
|
||||||
ai[1]->getClient()->show();
|
aiThread[1]->getClient()->show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,7 +202,7 @@ private:
|
||||||
Game tempGame;
|
Game tempGame;
|
||||||
|
|
||||||
// 2个AI的线程
|
// 2个AI的线程
|
||||||
AiThread *ai[3];
|
AiThread *aiThread[3];
|
||||||
|
|
||||||
// 棋局的场景类
|
// 棋局的场景类
|
||||||
GameScene &scene;
|
GameScene &scene;
|
||||||
|
|
Loading…
Reference in New Issue