添加AI设置——深度和定时器功能
This commit is contained in:
parent
df2b4f8f7a
commit
435a82ac5e
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.6.1, 2018-12-02T12:38:12. -->
|
||||
<!-- Written by QtCreator 4.6.1, 2018-12-15T21:55:22. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
|
|
@ -2,9 +2,17 @@
|
|||
#include "aithread.h"
|
||||
|
||||
AiThread::AiThread(int id, QObject *parent) : QThread(parent),
|
||||
waiting_(false)
|
||||
waiting_(false),
|
||||
aiDepth(7),
|
||||
aiTime(8)
|
||||
{
|
||||
this->id = id;
|
||||
// 连接定时器启动,减去118毫秒的返回时间
|
||||
connect(this, &AiThread::calcStarted, this, [=]() {timer.start(aiTime * 1000 - 118); }, Qt::QueuedConnection);
|
||||
// 连接定时器停止
|
||||
connect(this, &AiThread::calcFinished, this, [=]() {timer.stop(); }, Qt::QueuedConnection);
|
||||
// 连接定时器处理函数
|
||||
connect(&timer, &QTimer::timeout, this, &AiThread::act, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
AiThread::~AiThread()
|
||||
|
@ -18,14 +26,24 @@ void AiThread::setAi(const NineChess &chess)
|
|||
{
|
||||
mutex.lock();
|
||||
this->chess = &chess;
|
||||
ai_ab.setChess(*(this->chess));
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void AiThread::setAi(const NineChess &chess, int depth, int time)
|
||||
{
|
||||
mutex.lock();
|
||||
this->chess = &chess;
|
||||
ai_ab.setChess(chess);
|
||||
aiDepth = depth;
|
||||
aiTime = time;
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void AiThread::run()
|
||||
{
|
||||
|
||||
// 测试用数据
|
||||
int iTemp = 0;
|
||||
// int iTemp = 0;
|
||||
// 设一个标识,1号线程只管玩家1,2号线程只管玩家2
|
||||
int i = 0;
|
||||
|
||||
|
@ -45,28 +63,40 @@ void AiThread::run()
|
|||
mutex.unlock();
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
ai_ab.setChess(*chess);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
ai_ab.alphaBetaPruning(6);
|
||||
ai_ab.setChess(*chess);
|
||||
emit calcStarted();
|
||||
mutex.unlock();
|
||||
|
||||
ai_ab.alphaBetaPruning(aiDepth);
|
||||
const char * str = ai_ab.bestMove();
|
||||
qDebug() << str;
|
||||
if (strcmp(str, "error!"))
|
||||
emit command(str);
|
||||
qDebug() << "Thread" << id << "run" << ++iTemp << "times";
|
||||
// qDebug() << "Thread" << id << "run" << ++iTemp << "times";
|
||||
emit calcFinished();
|
||||
|
||||
// 执行完毕后继续判断
|
||||
mutex.lock();
|
||||
if (!isInterruptionRequested()) {
|
||||
mutex.lock();
|
||||
pauseCondition.wait(&mutex);
|
||||
mutex.unlock();
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
qDebug() << "Thread" << id << "quit";
|
||||
}
|
||||
|
||||
void AiThread::act()
|
||||
{
|
||||
if (isFinished() || !isRunning())
|
||||
return;
|
||||
|
||||
mutex.lock();
|
||||
waiting_ = false;
|
||||
ai_ab.quit();
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void AiThread::pause()
|
||||
{
|
||||
mutex.lock();
|
||||
|
@ -87,11 +117,12 @@ void AiThread::stop()
|
|||
if (isFinished() || !isRunning())
|
||||
return;
|
||||
|
||||
if(!isInterruptionRequested())
|
||||
if (!isInterruptionRequested()) {
|
||||
requestInterruption();
|
||||
mutex.lock();
|
||||
waiting_ = false;
|
||||
ai_ab.quit();
|
||||
pauseCondition.wakeAll();
|
||||
mutex.unlock();
|
||||
mutex.lock();
|
||||
waiting_ = false;
|
||||
ai_ab.quit();
|
||||
pauseCondition.wakeAll();
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include <QTimer>
|
||||
#include "ninechess.h"
|
||||
#include "ninechessai_ab.h"
|
||||
|
||||
|
@ -18,14 +19,29 @@ public:
|
|||
signals:
|
||||
// 招法信号
|
||||
void command(const QString &cmdline, bool update = true);
|
||||
// 开始计算的信号
|
||||
void calcStarted();
|
||||
// 计算结束的信号
|
||||
void calcFinished();
|
||||
|
||||
protected:
|
||||
void run() override;
|
||||
|
||||
public:
|
||||
// AI设置
|
||||
void setAi(const NineChess &chess);
|
||||
void setAi(const NineChess &chess, int depth, int time);
|
||||
// 深度和限时
|
||||
void getDepthTime(int &depth, int &time) { depth = aiDepth; time = aiTime; }
|
||||
|
||||
public slots:
|
||||
void setAi(const NineChess &);
|
||||
// 强制出招,不退出线程
|
||||
void act();
|
||||
// 线程暂停
|
||||
void pause();
|
||||
// 线程继续
|
||||
void resume();
|
||||
// 退出线程
|
||||
void stop();
|
||||
|
||||
private:
|
||||
|
@ -42,6 +58,12 @@ private:
|
|||
const NineChess *chess;
|
||||
// Alpha-Beta剪枝算法类
|
||||
NineChessAi_ab ai_ab;
|
||||
// AI的层数
|
||||
int aiDepth;
|
||||
// AI的限时
|
||||
int aiTime;
|
||||
// 定时器
|
||||
QTimer timer;
|
||||
};
|
||||
|
||||
#endif // AITHREAD_H
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QSound>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
|
@ -247,6 +248,34 @@ void GameController::setEngine2(bool arg)
|
|||
}
|
||||
}
|
||||
|
||||
void GameController::setAiDepthTime(int depth1, int time1, int depth2, int time2)
|
||||
{
|
||||
if (isEngine1) {
|
||||
ai1.stop();
|
||||
ai1.wait();
|
||||
}
|
||||
if (isEngine2) {
|
||||
ai2.stop();
|
||||
ai2.wait();
|
||||
}
|
||||
|
||||
ai1.setAi(chess, depth1, time1);
|
||||
ai2.setAi(chess, depth2, time2);
|
||||
|
||||
if (isEngine1) {
|
||||
ai1.start();
|
||||
}
|
||||
if (isEngine2) {
|
||||
ai2.start();
|
||||
}
|
||||
}
|
||||
|
||||
void GameController::getAiDepthTime(int &depth1, int &time1, int &depth2, int &time2)
|
||||
{
|
||||
ai1.getDepthTime(depth1, time1);
|
||||
ai2.getDepthTime(depth2, time2);
|
||||
}
|
||||
|
||||
void GameController::setAnimation(bool arg)
|
||||
{
|
||||
hasAnimation = arg;
|
||||
|
@ -295,12 +324,12 @@ void GameController::flip()
|
|||
else
|
||||
phaseChange(currentRow, true);
|
||||
|
||||
ai1.setAi(chess);
|
||||
ai2.setAi(chess);
|
||||
if (isEngine1) {
|
||||
ai1.setAi(chess);
|
||||
ai1.start();
|
||||
}
|
||||
if (isEngine2) {
|
||||
ai2.setAi(chess);
|
||||
ai2.start();
|
||||
}
|
||||
}
|
||||
|
@ -331,12 +360,12 @@ void GameController::mirror()
|
|||
else
|
||||
phaseChange(currentRow, true);
|
||||
|
||||
ai1.setAi(chess);
|
||||
ai2.setAi(chess);
|
||||
if (isEngine1) {
|
||||
ai1.setAi(chess);
|
||||
ai1.start();
|
||||
}
|
||||
if (isEngine2) {
|
||||
ai2.setAi(chess);
|
||||
ai2.start();
|
||||
}
|
||||
}
|
||||
|
@ -366,12 +395,12 @@ void GameController::turnRight()
|
|||
else
|
||||
phaseChange(currentRow, true);
|
||||
|
||||
ai1.setAi(chess);
|
||||
ai2.setAi(chess);
|
||||
if (isEngine1) {
|
||||
ai1.setAi(chess);
|
||||
ai1.start();
|
||||
}
|
||||
if (isEngine2) {
|
||||
ai2.setAi(chess);
|
||||
ai2.start();
|
||||
}
|
||||
}
|
||||
|
@ -398,12 +427,12 @@ void GameController::turnLeft()
|
|||
// 刷新显示
|
||||
updateScence();
|
||||
|
||||
ai1.setAi(chess);
|
||||
ai2.setAi(chess);
|
||||
if (isEngine1) {
|
||||
ai1.setAi(chess);
|
||||
ai1.start();
|
||||
}
|
||||
if (isEngine2) {
|
||||
ai2.setAi(chess);
|
||||
ai2.start();
|
||||
}
|
||||
}
|
||||
|
@ -597,16 +626,18 @@ bool GameController::actionPiece(QPointF pos)
|
|||
// 如果还未决出胜负
|
||||
if (chess.whoWin() == NineChess::NOBODY) {
|
||||
if (chess.whosTurn() == NineChess::PLAYER1) {
|
||||
if (isEngine1)
|
||||
if (isEngine1) {
|
||||
ai1.resume();
|
||||
}
|
||||
if (isEngine2)
|
||||
ai2.pause();
|
||||
}
|
||||
else {
|
||||
if (isEngine1)
|
||||
ai1.pause();
|
||||
if (isEngine2)
|
||||
if (isEngine2) {
|
||||
ai2.resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果已经决出胜负
|
||||
|
@ -727,16 +758,18 @@ bool GameController::command(const QString &cmd, bool update /*= true*/)
|
|||
// 如果还未决出胜负
|
||||
if (chess.whoWin() == NineChess::NOBODY) {
|
||||
if (chess.whosTurn() == NineChess::PLAYER1) {
|
||||
if (isEngine1)
|
||||
if (isEngine1) {
|
||||
ai1.resume();
|
||||
}
|
||||
if (isEngine2)
|
||||
ai2.pause();
|
||||
}
|
||||
else {
|
||||
if (isEngine1)
|
||||
ai1.pause();
|
||||
if (isEngine2)
|
||||
if (isEngine2) {
|
||||
ai2.resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果已经决出胜负
|
||||
|
|
|
@ -35,8 +35,9 @@ public:
|
|||
bool isAnimation() { return hasAnimation; }
|
||||
void setDurationTime(int i) { durationTime = i; }
|
||||
int getDurationTime() { return durationTime; }
|
||||
// 棋谱字符串列表模型
|
||||
QStringListModel manualListModel;
|
||||
QStringListModel *getManualListModel() { return &manualListModel; }
|
||||
void setAiDepthTime(int depth1, int time1, int depth2, int time2);
|
||||
void getAiDepthTime(int &depth1, int &time1, int &depth2, int &time2);
|
||||
|
||||
signals:
|
||||
// 玩家1(先手)用时改变的信号
|
||||
|
@ -138,7 +139,8 @@ private:
|
|||
int time2;
|
||||
// 用于主窗口状态栏显示的字符串
|
||||
QString message;
|
||||
|
||||
// 棋谱字符串列表模型
|
||||
QStringListModel manualListModel;
|
||||
};
|
||||
|
||||
#endif // GAMECONTROLLER_H
|
||||
|
|
|
@ -41,6 +41,9 @@ protected slots:
|
|||
}
|
||||
|
||||
void rowsInserted(const QModelIndex &parent, int start, int end) {
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(start)
|
||||
Q_UNUSED(end)
|
||||
newEmptyRow = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -154,6 +154,7 @@ const NineChess & NineChess::operator=(const NineChess &chess)
|
|||
memcpy(cmdline, chess.cmdline, sizeof(cmdline));
|
||||
cmdlist = chess.cmdlist;
|
||||
tip = chess.tip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1593,6 +1594,7 @@ void NineChess::mirror(bool cmdChange /*= true*/)
|
|||
{
|
||||
char ch;
|
||||
int i, j;
|
||||
|
||||
for (i = 1; i <= RING; i++) {
|
||||
for (j = 1; j < SEAT / 2; j++) {
|
||||
ch = board[i*SEAT + j];
|
||||
|
@ -1601,7 +1603,8 @@ void NineChess::mirror(bool cmdChange /*= true*/)
|
|||
}
|
||||
}
|
||||
|
||||
int16_t p1, p2, p3;
|
||||
uint64_t p1, p2, p3;
|
||||
|
||||
if (move_ < 0) {
|
||||
i = (-move_) / SEAT;
|
||||
j = (-move_) % SEAT;
|
||||
|
@ -1611,15 +1614,16 @@ void NineChess::mirror(bool cmdChange /*= true*/)
|
|||
else {
|
||||
p1 = move_ >> 8;
|
||||
p2 = move_ & 0x00ff;
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
i = (int)p1 / SEAT;
|
||||
j = (int)p1 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p1 = i * SEAT + j;
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
|
||||
i = (int)p2 / SEAT;
|
||||
j = (int)p2 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p2 = i * SEAT + j;
|
||||
move_ = (p1 << 8) | p2;
|
||||
move_ = (int16_t)((p1 << 8) | p2);
|
||||
}
|
||||
|
||||
if (currentPos != 0) {
|
||||
|
@ -1633,20 +1637,20 @@ void NineChess::mirror(bool cmdChange /*= true*/)
|
|||
for (auto mill = data.millList.begin(); mill != data.millList.end(); mill++) {
|
||||
p1 = (*mill & 0x000000ff00000000) >> 32;
|
||||
p2 = (*mill & 0x0000000000ff0000) >> 16;
|
||||
p2 = (*mill & 0x00000000000000ff);
|
||||
p3 = (*mill & 0x00000000000000ff);
|
||||
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
i = (int)p1 / SEAT;
|
||||
j = (int)p1 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p1 = i * SEAT + j;
|
||||
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
i = (int)p2 / SEAT;
|
||||
j = (int)p2 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p2 = i * SEAT + j;
|
||||
|
||||
i = p3 / SEAT;
|
||||
j = p3 % SEAT;
|
||||
i = (int)p3 / SEAT;
|
||||
j = (int)p3 % SEAT;
|
||||
j = (SEAT - j) % SEAT;
|
||||
p3 = i * SEAT + j;
|
||||
|
||||
|
@ -1660,7 +1664,6 @@ void NineChess::mirror(bool cmdChange /*= true*/)
|
|||
int c1, p1, c2, p2;
|
||||
int args = 0;
|
||||
int mm = 0, ss = 0, mss = 0;
|
||||
long tm = -1;
|
||||
|
||||
args = sscanf(cmdline, "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
|
||||
if (args >= 4) {
|
||||
|
@ -1714,13 +1717,14 @@ void NineChess::turn(bool cmdChange /*= true*/)
|
|||
{
|
||||
char ch;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < SEAT; i++) {
|
||||
ch = board[SEAT + i];
|
||||
board[SEAT + i] = board[SEAT*RING + i];
|
||||
board[SEAT*RING + i] = ch;
|
||||
}
|
||||
|
||||
int16_t p1, p2, p3;
|
||||
uint64_t p1, p2, p3;
|
||||
|
||||
if (move_ < 0) {
|
||||
i = (-move_) / SEAT;
|
||||
|
@ -1734,21 +1738,21 @@ void NineChess::turn(bool cmdChange /*= true*/)
|
|||
else {
|
||||
p1 = move_ >> 8;
|
||||
p2 = move_ & 0x00ff;
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
i = (int)p1 / SEAT;
|
||||
j = (int)p1 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p1 = i * SEAT + j;
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
i = (int)p2 / SEAT;
|
||||
j = (int)p2 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p2 = i * SEAT + j;
|
||||
move_ = (p1 << 8) | p2;
|
||||
move_ = (int16_t)((p1 << 8) | p2);
|
||||
}
|
||||
|
||||
if (currentPos != 0) {
|
||||
|
@ -1765,26 +1769,26 @@ void NineChess::turn(bool cmdChange /*= true*/)
|
|||
for (auto mill = data.millList.begin(); mill != data.millList.end(); mill++) {
|
||||
p1 = (*mill & 0x000000ff00000000) >> 32;
|
||||
p2 = (*mill & 0x0000000000ff0000) >> 16;
|
||||
p2 = (*mill & 0x00000000000000ff);
|
||||
p3 = (*mill & 0x00000000000000ff);
|
||||
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
i = (int)p1 / SEAT;
|
||||
j = (int)p1 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p1 = i * SEAT + j;
|
||||
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
i = (int)p2 / SEAT;
|
||||
j = (int)p2 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
i = 1;
|
||||
p2 = i * SEAT + j;
|
||||
|
||||
i = p3 / SEAT;
|
||||
j = p3 % SEAT;
|
||||
i = (int)p3 / SEAT;
|
||||
j = (int)p3 % SEAT;
|
||||
if (i == 1)
|
||||
i = RING;
|
||||
else if (i == RING)
|
||||
|
@ -1801,7 +1805,6 @@ void NineChess::turn(bool cmdChange /*= true*/)
|
|||
int c1, p1, c2, p2;
|
||||
int args = 0;
|
||||
int mm = 0, ss = 0, mss = 0;
|
||||
long tm = -1;
|
||||
|
||||
args = sscanf(cmdline, "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
|
||||
if (args >= 4) {
|
||||
|
@ -1889,6 +1892,7 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
|
|||
|
||||
char ch1, ch2;
|
||||
int i, j;
|
||||
|
||||
if (degrees == 2) {
|
||||
for (i = 1; i <= RING; i++) {
|
||||
ch1 = board[i*SEAT];
|
||||
|
@ -1923,7 +1927,7 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
|
|||
else
|
||||
return;
|
||||
|
||||
int16_t p1, p2, p3;
|
||||
uint64_t p1, p2, p3;
|
||||
|
||||
if (move_ < 0) {
|
||||
i = (-move_) / SEAT;
|
||||
|
@ -1934,15 +1938,15 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
|
|||
else {
|
||||
p1 = move_ >> 8;
|
||||
p2 = move_ & 0x00ff;
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
i = (int)p1 / SEAT;
|
||||
j = (int)p1 % SEAT;
|
||||
j = (j + SEAT - degrees) % SEAT;
|
||||
p1 = i * SEAT + j;
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
i = (int)p2 / SEAT;
|
||||
j = (int)p2 % SEAT;
|
||||
j = (j + SEAT - degrees) % SEAT;
|
||||
p2 = i * SEAT + j;
|
||||
move_ = (p1 << 8) | p2;
|
||||
move_ = (int16_t)((p1 << 8) | p2);
|
||||
}
|
||||
|
||||
if (currentPos != 0) {
|
||||
|
@ -1956,20 +1960,20 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
|
|||
for (auto mill = data.millList.begin(); mill != data.millList.end(); mill++) {
|
||||
p1 = (*mill & 0x000000ff00000000) >> 32;
|
||||
p2 = (*mill & 0x0000000000ff0000) >> 16;
|
||||
p2 = (*mill & 0x00000000000000ff);
|
||||
p3 = (*mill & 0x00000000000000ff);
|
||||
|
||||
i = p1 / SEAT;
|
||||
j = p1 % SEAT;
|
||||
i = (int)p1 / SEAT;
|
||||
j = (int)p1 % SEAT;
|
||||
j = (j + SEAT - degrees) % SEAT;
|
||||
p1 = i * SEAT + j;
|
||||
|
||||
i = p2 / SEAT;
|
||||
j = p2 % SEAT;
|
||||
i = (int)p2 / SEAT;
|
||||
j = (int)p2 % SEAT;
|
||||
j = (j + SEAT - degrees) % SEAT;
|
||||
p2 = i * SEAT + j;
|
||||
|
||||
i = p3 / SEAT;
|
||||
j = p3 % SEAT;
|
||||
i = (int)p3 / SEAT;
|
||||
j = (int)p3 % SEAT;
|
||||
j = (j + SEAT - degrees) % SEAT;
|
||||
p3 = i * SEAT + j;
|
||||
|
||||
|
@ -1983,7 +1987,6 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
|
|||
int c1, p1, c2, p2;
|
||||
int args = 0;
|
||||
int mm = 0, ss = 0, mss = 0;
|
||||
long tm = -1;
|
||||
|
||||
args = sscanf(cmdline, "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
|
||||
if (args >= 4) {
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
|
||||
NineChessAi_ab::NineChessAi_ab():
|
||||
rootNode(nullptr),
|
||||
requiredQuit(false),
|
||||
depth(3) // 默认3层深度
|
||||
requiredQuit(false)
|
||||
{
|
||||
rootNode = new Node;
|
||||
rootNode->value = 0;
|
||||
|
@ -345,21 +344,6 @@ const char *NineChessAi_ab::move2string(int16_t move)
|
|||
return cmdline;
|
||||
}
|
||||
|
||||
void NineChessAi_ab::reverse(const NineChess *node1, NineChess *node2, int i)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NineChessAi_ab::turn(const NineChess *node1, NineChess *node2, int i)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NineChessAi_ab::rotate(const NineChess *node1, NineChess *node2, int i)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool NineChessAi_ab::isInHash(const Node *node)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -42,7 +42,6 @@ public:
|
|||
~NineChessAi_ab();
|
||||
|
||||
void setChess(const NineChess &chess);
|
||||
void setDepth(int depth) { this->depth = depth; }
|
||||
void quit() { requiredQuit = true; }
|
||||
// Alpha-Beta剪枝算法
|
||||
int alphaBetaPruning(int depth);
|
||||
|
@ -63,13 +62,6 @@ protected:
|
|||
// 返回招法的命令行
|
||||
const char *move2string(int16_t move);
|
||||
|
||||
// 局面逆序
|
||||
void reverse(const NineChess *node1, NineChess *node2, int i);
|
||||
// 局面层次翻转
|
||||
void turn(const NineChess *node1, NineChess *node2, int i);
|
||||
// 局面旋转
|
||||
void rotate(const NineChess *node1, NineChess *node2, int i);
|
||||
|
||||
// 判断是否在哈希表中
|
||||
bool isInHash(const Node *node);
|
||||
|
||||
|
@ -92,7 +84,7 @@ private:
|
|||
// 标识,用于跳出剪枝算法,立即返回
|
||||
bool requiredQuit;
|
||||
// 剪枝算法的层深
|
||||
int depth;
|
||||
// int depth;
|
||||
// 定义极大值,等于32位有符号整形数字的最大值
|
||||
static const int infinity = INT32_MAX;
|
||||
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFormLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QSpinBox>
|
||||
#include <QLabel>
|
||||
#include <QHelpEvent>
|
||||
#include <QToolTip>
|
||||
|
@ -53,7 +57,6 @@ NineChessWindow::NineChessWindow(QWidget *parent)
|
|||
ui.gameView->setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
// 因功能限制,使部分功能不可用,将来再添加
|
||||
ui.actionEngine_E->setDisabled(true);
|
||||
ui.actionInternet_I->setDisabled(true);
|
||||
ui.actionSetting_O->setDisabled(true);
|
||||
|
||||
|
@ -194,7 +197,7 @@ void NineChessWindow::initialize()
|
|||
ruleInfo();
|
||||
|
||||
// 关联列表视图和字符串列表模型
|
||||
ui.listView->setModel(&(game->manualListModel));
|
||||
ui.listView->setModel(game->getManualListModel());
|
||||
// 因为QListView的rowsInserted在setModel之后才能启动,
|
||||
// 第一次需手动初始化选中listView第一项
|
||||
//qDebug() << ui.listView->model();
|
||||
|
@ -563,6 +566,7 @@ void NineChessWindow::on_actionRowChange()
|
|||
|
||||
void NineChessWindow::onAutoRunTimeOut(QPrivateSignal signal)
|
||||
{
|
||||
Q_UNUSED(signal)
|
||||
int rows = ui.listView->model()->rowCount();
|
||||
int currentRow = ui.listView->currentIndex().row();
|
||||
|
||||
|
@ -645,7 +649,99 @@ void NineChessWindow::on_actionInternet_I_triggered()
|
|||
|
||||
void NineChessWindow::on_actionEngine_E_triggered()
|
||||
{
|
||||
// 空着,有时间再做
|
||||
// 定义新对话框
|
||||
QDialog *dialog = new QDialog(this);
|
||||
dialog->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
dialog->setObjectName(QStringLiteral("Dialog"));
|
||||
dialog->setWindowTitle(tr("AI设置"));
|
||||
dialog->resize(256, 188);
|
||||
dialog->setModal(true);
|
||||
|
||||
// 生成各个控件
|
||||
QVBoxLayout *vLayout = new QVBoxLayout(dialog);
|
||||
QGroupBox *groupBox1 = new QGroupBox(dialog);
|
||||
QGroupBox *groupBox2 = new QGroupBox(dialog);
|
||||
|
||||
QHBoxLayout *hLayout1 = new QHBoxLayout;
|
||||
QLabel *label_depth1 = new QLabel(dialog);
|
||||
QSpinBox *spinBox_depth1 = new QSpinBox(dialog);
|
||||
QLabel *label_time1 = new QLabel(dialog);
|
||||
QSpinBox *spinBox_time1 = new QSpinBox(dialog);
|
||||
|
||||
QHBoxLayout *hLayout2 = new QHBoxLayout;
|
||||
QLabel *label_depth2 = new QLabel(dialog);
|
||||
QSpinBox *spinBox_depth2 = new QSpinBox(dialog);
|
||||
QLabel *label_time2 = new QLabel(dialog);
|
||||
QSpinBox *spinBox_time2 = new QSpinBox(dialog);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog);
|
||||
|
||||
// 设置各个控件数据
|
||||
groupBox1->setTitle(tr("玩家1 AI设置"));
|
||||
label_depth1->setText(tr("深度"));
|
||||
spinBox_depth1->setMinimum(1);
|
||||
spinBox_depth1->setMaximum(10);
|
||||
label_time1->setText(tr("限时"));
|
||||
spinBox_time1->setMinimum(1);
|
||||
spinBox_time1->setMaximum(30);
|
||||
|
||||
groupBox2->setTitle(tr("玩家2 AI设置"));
|
||||
label_depth2->setText(tr("深度"));
|
||||
spinBox_depth2->setMinimum(1);
|
||||
spinBox_depth2->setMaximum(10);
|
||||
label_time2->setText(tr("限时"));
|
||||
spinBox_time2->setMinimum(1);
|
||||
spinBox_time2->setMaximum(30);
|
||||
|
||||
buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
|
||||
buttonBox->setCenterButtons(true);
|
||||
buttonBox->button(QDialogButtonBox::Ok)->setText(tr("确定"));
|
||||
buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("取消"));
|
||||
|
||||
// 布局控件
|
||||
vLayout->addWidget(groupBox1);
|
||||
vLayout->addWidget(groupBox2);
|
||||
vLayout->addWidget(buttonBox);
|
||||
groupBox1->setLayout(hLayout1);
|
||||
groupBox2->setLayout(hLayout2);
|
||||
hLayout1->addWidget(label_depth1);
|
||||
hLayout1->addWidget(spinBox_depth1);
|
||||
hLayout1->addWidget(label_time1);
|
||||
hLayout1->addWidget(spinBox_time1);
|
||||
hLayout2->addWidget(label_depth2);
|
||||
hLayout2->addWidget(spinBox_depth2);
|
||||
hLayout2->addWidget(label_time2);
|
||||
hLayout2->addWidget(spinBox_time2);
|
||||
|
||||
// 关联信号和槽函数
|
||||
connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
|
||||
connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
|
||||
|
||||
// 目前数据
|
||||
int depth1, depth2, time1, time2;
|
||||
game->getAiDepthTime(depth1, time1, depth2, time2);
|
||||
spinBox_depth1->setValue(depth1);
|
||||
spinBox_depth2->setValue(depth2);
|
||||
spinBox_time1->setValue(time1);
|
||||
spinBox_time2->setValue(time2);
|
||||
|
||||
// 新设数据
|
||||
if (dialog->exec() == QDialog::Accepted) {
|
||||
int depth1_new, depth2_new, time1_new, time2_new;
|
||||
depth1_new = spinBox_depth1->value();
|
||||
depth2_new = spinBox_depth2->value();
|
||||
time1_new = spinBox_time1->value();
|
||||
time2_new = spinBox_time2->value();
|
||||
|
||||
if (depth1 != depth1_new || depth2 != depth2_new || time1 != time1_new || time2 != time2_new) {
|
||||
// 重置AI
|
||||
game->setAiDepthTime(depth1_new, time1_new, depth2_new, time2_new);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除对话框,子控件会一并删除
|
||||
dialog->disconnect();
|
||||
delete dialog;
|
||||
}
|
||||
|
||||
void NineChessWindow::on_actionViewHelp_V_triggered()
|
||||
|
|
Loading…
Reference in New Issue