test: 新增测试模块用于本地对战
使用共享内存实现,效率比 socket 高。 打开 TEST_MODE 宏才能生效。
This commit is contained in:
parent
be8b1d4baa
commit
3182eff1ad
|
@ -30,6 +30,8 @@
|
|||
|
||||
//#define TRAINING_MODE
|
||||
|
||||
//#define TEST_MODE
|
||||
|
||||
//#define DEBUG_MODE
|
||||
//#define DEBUG_MODE_A
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ INCLUDEPATH += include
|
|||
INCLUDEPATH += src/base
|
||||
INCLUDEPATH += src/ai
|
||||
INCLUDEPATH += src/game
|
||||
INCLUDEPATH += src/test
|
||||
INCLUDEPATH += src/ui/qt
|
||||
|
||||
SOURCES += \
|
||||
|
@ -39,6 +40,7 @@ SOURCES += \
|
|||
src/main.cpp \
|
||||
src/base/aithread.cpp \
|
||||
src/ai/search.cpp \
|
||||
src/test/test.cpp \
|
||||
src/ui/qt/gamewindow.cpp \
|
||||
src/ui/qt/pieceitem.cpp \
|
||||
src/ui/qt/server.cpp \
|
||||
|
@ -75,6 +77,7 @@ HEADERS += \
|
|||
src/game/position.h \
|
||||
src/game/rule.h \
|
||||
src/game/types.h \
|
||||
src/test/test.h \
|
||||
src/ui/qt/client.h \
|
||||
src/ui/qt/gamecontroller.h \
|
||||
src/ui/qt/gamescene.h \
|
||||
|
|
|
@ -106,10 +106,10 @@
|
|||
<IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IgnoreImportLibrary>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\base;$(ProjectDir)\include;$(ProjectDir)\src\ai;$(ProjectDir)\src\game;$(ProjectDir)\src\ui\qt;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(ProjectDir)\src\base;$(ProjectDir)\include;$(ProjectDir)\src\ai;$(ProjectDir)\src\game;$(ProjectDir)\src\ui\qt;$(ProjectDir)\src\test;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>$(ProjectDir)\src\ui\qt;$(ProjectDir)\src\game;$(ProjectDir)\src\ai;$(ProjectDir)\src\base;$(ProjectDir)\include;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(ProjectDir)\src\ui\qt;$(ProjectDir)\src\game;$(ProjectDir)\src\ai;$(ProjectDir)\src\base;$(ProjectDir)\include;$(ProjectDir)\src\test;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
|
@ -466,6 +466,7 @@
|
|||
<ClInclude Include="src\game\position.h" />
|
||||
<ClInclude Include="src\game\rule.h" />
|
||||
<ClInclude Include="src\game\types.h" />
|
||||
<QtMoc Include="src\test\test.h" />
|
||||
<ClInclude Include="src\ui\qt\boarditem.h" />
|
||||
<QtMoc Include="src\ui\qt\client.h" />
|
||||
<QtMoc Include="src\ui\qt\gamecontroller.h" />
|
||||
|
@ -717,6 +718,7 @@
|
|||
<ClCompile Include="src\game\position.cpp" />
|
||||
<ClCompile Include="src\game\rule.cpp" />
|
||||
<ClCompile Include="src\main.cpp" />
|
||||
<ClCompile Include="src\test\test.cpp" />
|
||||
<ClCompile Include="src\ui\qt\boarditem.cpp" />
|
||||
<ClCompile Include="src\ui\qt\client.cpp" />
|
||||
<ClCompile Include="src\ui\qt\gamecontroller.cpp" />
|
||||
|
|
|
@ -52,6 +52,9 @@
|
|||
<Filter Include="base">
|
||||
<UniqueIdentifier>{c5349658-6cbb-4076-8529-29de7092f9d8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="test">
|
||||
<UniqueIdentifier>{944f132b-1dc6-4222-a345-79e3d2c821e7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h">
|
||||
|
@ -294,6 +297,9 @@
|
|||
<QtMoc Include="src\base\aithread.h">
|
||||
<Filter>base</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="src\test\test.h">
|
||||
<Filter>test</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\main.cpp">
|
||||
|
@ -374,6 +380,9 @@
|
|||
<ClCompile Include="src\base\thread.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\test\test.cpp">
|
||||
<Filter>test</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="millgame.rc">
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "search.h"
|
||||
#include "server.h"
|
||||
#include "client.h"
|
||||
#include "test.h"
|
||||
|
||||
class AiThread : public QThread
|
||||
{
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
Sanmill, a mill game playing engine derived from NineChess 1.5
|
||||
Copyright (C) 2015-2018 liuweilhy (NineChess author)
|
||||
Copyright (C) 2019 Calcitem <calcitem@outlook.com>
|
||||
|
||||
Sanmill is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Sanmill is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef TEST_MODE
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QUuid>
|
||||
#include <QDataStream>
|
||||
#include <QString>
|
||||
#include <QThread>
|
||||
#include <random>
|
||||
|
||||
#include "test.h"
|
||||
|
||||
Test::Test()
|
||||
{
|
||||
sharedMemory.setKey("MillGameSharedMemory");
|
||||
|
||||
if (sharedMemory.attach()) {
|
||||
loggerDebug("Attached shared memory segment.\n");
|
||||
} else {
|
||||
if (sharedMemory.create(SHARED_MEMORY_SIZE)) {
|
||||
loggerDebug("Created shared memory segment.\n");
|
||||
} else {
|
||||
loggerDebug("Unable to create shared memory segment.\n");
|
||||
}
|
||||
}
|
||||
|
||||
to = (char *)sharedMemory.data();
|
||||
|
||||
uuid = createUuidString();
|
||||
uuidSize = uuid.size();
|
||||
|
||||
assert(uuidSize == 38);
|
||||
}
|
||||
|
||||
Test::~Test()
|
||||
{
|
||||
detach();
|
||||
}
|
||||
|
||||
void Test::writeToMemory(const QString &cmdline)
|
||||
{
|
||||
if (cmdline == readStr) {
|
||||
return;
|
||||
}
|
||||
|
||||
char from[128] = { 0 };
|
||||
strcpy(from, cmdline.toStdString().c_str());
|
||||
|
||||
while (true) {
|
||||
sharedMemory.lock();
|
||||
|
||||
if (to[0] != 0) {
|
||||
sharedMemory.unlock();
|
||||
QThread::msleep(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(to, 0, SHARED_MEMORY_SIZE);
|
||||
memcpy(to, uuid.toStdString().c_str(), uuidSize);
|
||||
memcpy(to + uuidSize, from, strlen(from));
|
||||
sharedMemory.unlock();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Test::readFromMemory()
|
||||
{
|
||||
sharedMemory.lock();
|
||||
QString str = to;
|
||||
sharedMemory.unlock();
|
||||
|
||||
if (str.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(str.mid(0, uuidSize) == uuid)) {
|
||||
str = str.mid(uuidSize);
|
||||
if (str.size()) {
|
||||
sharedMemory.lock();
|
||||
memset(to, 0, SHARED_MEMORY_SIZE);
|
||||
sharedMemory.unlock();
|
||||
readStr = str;
|
||||
emit command(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Test::detach()
|
||||
{
|
||||
if (sharedMemory.isAttached()) {
|
||||
sharedMemory.detach();
|
||||
}
|
||||
}
|
||||
|
||||
QString Test::createUuidString()
|
||||
{
|
||||
return QUuid::createUuid().toString();
|
||||
}
|
||||
|
||||
#endif // TEST_MODE
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
Sanmill, a mill game playing engine derived from NineChess 1.5
|
||||
Copyright (C) 2015-2018 liuweilhy (NineChess author)
|
||||
Copyright (C) 2019 Calcitem <calcitem@outlook.com>
|
||||
|
||||
Sanmill is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Sanmill is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TEST_H
|
||||
#define TEST_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef TEST_MODE
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedMemory>
|
||||
#include <QString>
|
||||
#include <QBuffer>
|
||||
|
||||
class Test : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Test();
|
||||
~Test();
|
||||
|
||||
signals:
|
||||
void command(const QString &cmd, bool update = true);
|
||||
|
||||
public slots:
|
||||
void writeToMemory(const QString &str);
|
||||
void readFromMemory();
|
||||
|
||||
private:
|
||||
void detach();
|
||||
QString createUuidString();
|
||||
|
||||
private:
|
||||
const int SHARED_MEMORY_SIZE = 4096;
|
||||
QSharedMemory sharedMemory;
|
||||
QString uuid;
|
||||
int uuidSize;
|
||||
char *to { nullptr };
|
||||
QString readStr;
|
||||
};
|
||||
|
||||
#endif // TEST_MODE
|
||||
#endif // TEST_H
|
|
@ -76,12 +76,25 @@ GameController::GameController(
|
|||
|
||||
gameReset();
|
||||
|
||||
#ifdef TEST_MODE
|
||||
gameTest = new Test();
|
||||
|
||||
readMemoryTimer = new QTimer(this);
|
||||
connect(readMemoryTimer, SIGNAL(timeout()), this, SLOT(onTimeOut()));
|
||||
readMemoryTimer->start(100);
|
||||
#endif // TEST_MODE
|
||||
|
||||
// 关联AI和控制器的着法命令行
|
||||
connect(aiThread[BLACK], SIGNAL(command(const QString &, bool)),
|
||||
this, SLOT(command(const QString &, bool)));
|
||||
connect(aiThread[WHITE], SIGNAL(command(const QString &, bool)),
|
||||
this, SLOT(command(const QString &, bool)));
|
||||
|
||||
#ifdef TEST_MODE
|
||||
connect(this->gameTest, SIGNAL(command(const QString &, bool)),
|
||||
this, SLOT(command(const QString &, bool)));
|
||||
#endif
|
||||
|
||||
#ifndef TRAINING_MODE
|
||||
// 关联AI和网络类的着法命令行
|
||||
connect(aiThread[BLACK]->getClient(), SIGNAL(command(const QString &, bool)),
|
||||
|
@ -110,6 +123,13 @@ GameController::~GameController()
|
|||
#endif /* ENDGAME_LEARNING */
|
||||
}
|
||||
|
||||
#ifdef TEST_MODE
|
||||
void GameController::onTimeOut()
|
||||
{
|
||||
gameTest->readFromMemory();
|
||||
}
|
||||
#endif // TEST_MODE
|
||||
|
||||
const map<int, QStringList> GameController::getActions()
|
||||
{
|
||||
// 主窗口更新菜单栏
|
||||
|
@ -926,12 +946,16 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef TEST_MODE
|
||||
gameTest->writeToMemory(cmd);
|
||||
#endif // TEST_MODE
|
||||
|
||||
#ifndef TRAINING_MODE
|
||||
// 网络: 将着法放到服务器的发送列表中
|
||||
if (isAiPlayer[BLACK]) {
|
||||
aiThread[BLACK]->getServer()->setAction(cmd);
|
||||
} else if (isAiPlayer[WHITE]) {
|
||||
aiThread[BLACK]->getServer()->setAction(cmd); // 注意: 同样是AI1
|
||||
aiThread[BLACK]->getServer()->setAction(cmd); // 注意: 同样是 aiThread[BLACK]
|
||||
}
|
||||
#endif // TRAINING_MODE
|
||||
|
||||
|
|
|
@ -274,6 +274,11 @@ public slots:
|
|||
// 显示网络配置窗口
|
||||
void showNetworkWindow();
|
||||
|
||||
#ifdef TEST_MODE
|
||||
// 定时器超时
|
||||
void onTimeOut();
|
||||
#endif // TEST_MODE
|
||||
|
||||
protected:
|
||||
//bool eventFilter(QObject * watched, QEvent * event);
|
||||
// 定时器
|
||||
|
@ -286,6 +291,11 @@ private:
|
|||
// 棋对象的数据模型(临时)
|
||||
Game tempGame;
|
||||
|
||||
#ifdef TEST_MODE
|
||||
// 测试
|
||||
Test *gameTest;
|
||||
#endif // TEST_MODE
|
||||
|
||||
private:
|
||||
// 2个AI的线程
|
||||
AiThread *aiThread[COLOR_COUNT];
|
||||
|
@ -365,6 +375,9 @@ private:
|
|||
|
||||
// 棋谱字符串列表模型
|
||||
QStringListModel manualListModel;
|
||||
|
||||
// 读取共享内存的定时器
|
||||
QTimer *readMemoryTimer;
|
||||
};
|
||||
|
||||
#endif // GAMECONTROLLER_H
|
||||
|
|
Loading…
Reference in New Issue