重构NineChess模型,做了数据分离,评估用的数据大小从304字节减小为88字节。

This commit is contained in:
liuweilhy 2018-12-02 01:03:54 +08:00
parent 2e9a690df3
commit a99577d089
9 changed files with 648 additions and 505 deletions

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.6.1, 2018-11-30T23:59:04. -->
<!-- Written by QtCreator 4.7.2, 2018-12-01T00:15:14. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{fba36f69-c7a3-4c3f-91d4-7c71ad79549c}</value>
<value type="QByteArray">{9a8c5f9d-1814-40d9-ab01-983c45f229c5}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
@ -54,19 +54,22 @@
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
<valuemap type="QVariantMap">
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.11.0 MSVC2017 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.11.0 MSVC2017 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5110.win64_msvc2017_64_kit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.9.7 GCC 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.9.7 GCC 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.597.gcc_64_kit</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:/My program/QT/NineChess/build-ninechess-Desktop_Qt_5_11_0_MSVC2017_64bit-Debug</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/sniper/Work/My program/QT/NineChess/build-ninechess-Desktop_Qt_5_9_7_GCC_64bit-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@ -84,7 +87,10 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
@ -100,7 +106,10 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
@ -120,7 +129,7 @@
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:/My program/QT/NineChess/build-ninechess-Desktop_Qt_5_11_0_MSVC2017_64bit-Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/sniper/Work/My program/QT/NineChess/build-ninechess-Desktop_Qt_5_9_7_GCC_64bit-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@ -138,7 +147,10 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
@ -154,7 +166,10 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
@ -174,7 +189,7 @@
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:/My program/QT/NineChess/build-ninechess-Desktop_Qt_5_11_0_MSVC2017_64bit-Profile</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/sniper/Work/My program/QT/NineChess/build-ninechess-Desktop_Qt_5_9_7_GCC_64bit-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@ -192,7 +207,10 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
@ -208,7 +226,10 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
@ -236,7 +257,7 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署设置</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
@ -286,13 +307,12 @@
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">ninechess</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:E:/My program/QT/NineChess/NineChess/ninechess.pro</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/media/sniper/Work/My program/QT/NineChess/NineChess/ninechess.pro</value>
<value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">ninechess.pro</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">E:/My program/QT/NineChess/build-ninechess-Desktop_Qt_5_11_0_MSVC2017_64bit-Debug</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/media/sniper/Work/My program/QT/NineChess/build-ninechess-Desktop_Qt_5_9_7_GCC_64bit-Debug</value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>

View File

@ -8,13 +8,19 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}.Debug|x64.ActiveCfg = Debug|x64
{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}.Debug|x64.Build.0 = Debug|x64
{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}.Debug|x86.ActiveCfg = Debug|Win32
{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}.Debug|x86.Build.0 = Debug|Win32
{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}.Release|x64.ActiveCfg = Release|x64
{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}.Release|x64.Build.0 = Release|x64
{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}.Release|x86.ActiveCfg = Release|Win32
{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -23,10 +23,6 @@
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
<Extensions>qrc;*</Extensions>
@ -41,85 +37,76 @@
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Distribution Files">
<UniqueIdentifier>{B83CAF91-C7BF-462F-B76C-EA11631F866C}</UniqueIdentifier>
<Extensions>*</Extensions>
<ParseFiles>false</ParseFiles>
</Filter>
<Filter Include="Text Files">
<UniqueIdentifier>{d3810898-e5d4-49ce-92da-beddffba0697}</UniqueIdentifier>
</Filter>
<Filter Include="Project Files">
<UniqueIdentifier>{16c52ca8-0391-4ad2-919c-4a865ad87e98}</UniqueIdentifier>
</Filter>
<Filter Include="View">
<UniqueIdentifier>{afa4cc20-6ea3-4aee-8211-eca831a215d8}</UniqueIdentifier>
</Filter>
<Filter Include="Control">
<UniqueIdentifier>{2dce63cc-311c-4d88-a5a4-7fdc289f99c6}</UniqueIdentifier>
</Filter>
<Filter Include="Model">
<UniqueIdentifier>{bc588bf0-770b-4800-89b5-64e97e98b22a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\boarditem.cpp">
<Filter>Source Files</Filter>
<ClCompile Include="src\aithread.cpp">
<Filter>Control</Filter>
</ClCompile>
<ClCompile Include="src\gamecontroller.cpp">
<Filter>Source Files</Filter>
<Filter>Control</Filter>
</ClCompile>
<ClCompile Include="src\boarditem.cpp">
<Filter>View</Filter>
</ClCompile>
<ClCompile Include="src\gamescene.cpp">
<Filter>Source Files</Filter>
<Filter>View</Filter>
</ClCompile>
<ClCompile Include="src\gameview.cpp">
<Filter>Source Files</Filter>
<Filter>View</Filter>
</ClCompile>
<ClCompile Include="src\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ninechess.cpp">
<Filter>Source Files</Filter>
<Filter>View</Filter>
</ClCompile>
<ClCompile Include="src\ninechesswindow.cpp">
<Filter>Source Files</Filter>
<Filter>View</Filter>
</ClCompile>
<ClCompile Include="src\pieceitem.cpp">
<Filter>Source Files</Filter>
<Filter>View</Filter>
</ClCompile>
<ClCompile Include="src\aithread.cpp">
<Filter>Source Files</Filter>
<ClCompile Include="src\ninechess.cpp">
<Filter>Model</Filter>
</ClCompile>
<ClCompile Include="src\ninechessai_ab.cpp">
<Filter>Source Files</Filter>
<Filter>Model</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="src\gamecontroller.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="src\gamescene.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="src\gameview.h">
<Filter>Header Files</Filter>
</QtMoc>
<ClInclude Include="src\graphicsconst.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ninechess.h">
<Filter>Header Files</Filter>
</ClInclude>
<QtMoc Include="src\ninechesswindow.h">
<Filter>Header Files</Filter>
</QtMoc>
<ClInclude Include="resource.h">
<Filter>Generated Files</Filter>
</ClInclude>
<QtMoc Include="src\pieceitem.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="src\aithread.h">
<Filter>Header Files</Filter>
<Filter>Control</Filter>
</QtMoc>
<QtMoc Include="src\manuallistview.h">
<Filter>Header Files</Filter>
<QtMoc Include="src\gamecontroller.h">
<Filter>Control</Filter>
</QtMoc>
<QtMoc Include="src\gamescene.h">
<Filter>View</Filter>
</QtMoc>
<ClInclude Include="src\graphicsconst.h">
<Filter>View</Filter>
</ClInclude>
<ClInclude Include="src\ninechess.h">
<Filter>Model</Filter>
</ClInclude>
<ClInclude Include="src\ninechessai_ab.h">
<Filter>Model</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
@ -269,10 +256,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\boarditem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ninechessai_ab.h">
<Filter>Header Files</Filter>
<Filter>View</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -285,4 +269,18 @@
<Filter>Project Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="src\gameview.h">
<Filter>View</Filter>
</QtMoc>
<QtMoc Include="src\manuallistview.h">
<Filter>View</Filter>
</QtMoc>
<QtMoc Include="src\pieceitem.h">
<Filter>View</Filter>
</QtMoc>
<QtMoc Include="src\ninechesswindow.h">
<Filter>View</Filter>
</QtMoc>
</ItemGroup>
</Project>

View File

@ -71,7 +71,6 @@ const QMap<int, QStringList> GameController::getActions()
return actions;
}
void GameController::gameStart()
{
chess.start();
@ -100,11 +99,17 @@ void GameController::gameReset()
// 重新绘制棋盘
scene.setDiagonal(chess.getRule()->hasObliqueLine);
// 绘制所有棋子放在起始位置分成2组写后面好区分
// 绘制所有棋子,放在起始位置
// 0: 先手第1子 1后手第1子
// 2先手嫡2子 3后手第2子
// ......
PieceItem::Models md;
PieceItem *newP;
for (int i = 0; i < chess.getRule()->numOfChess; i++)
{
PieceItem::Models md = isInverted ? PieceItem::whitePiece : PieceItem::blackPiece;
PieceItem *newP = new PieceItem;
// 先手的棋子
md = isInverted ? PieceItem::whitePiece : PieceItem::blackPiece;
newP = new PieceItem;
newP->setModel(md);
newP->setPos(scene.pos_p1);
newP->setNum(i + 1);
@ -113,20 +118,19 @@ void GameController::gameReset()
newP->setShowNum(true);
pieceList.append(newP);
scene.addItem(newP);
}
for (int i = 0; i < chess.getRule()->numOfChess; i++)
{
PieceItem::Models md = isInverted ? PieceItem::blackPiece : PieceItem::whitePiece;
PieceItem *newP = new PieceItem;
newP->setModel(md);
newP->setPos(scene.pos_p2);
newP->setNum(i + 1);
// 如果重复三连不可用,则显示棋子序号,九连棋专用玩法
if (!(chess.getRule()->canRepeated))
newP->setShowNum(true);
pieceList.append(newP);
scene.addItem(newP);
}
// 后手的棋子
md = isInverted ? PieceItem::blackPiece : PieceItem::whitePiece;
newP = new PieceItem;
newP->setModel(md);
newP->setPos(scene.pos_p2);
newP->setNum(i + 1);
// 如果重复三连不可用,则显示棋子序号,九连棋专用玩法
if (!(chess.getRule()->canRepeated))
newP->setShowNum(true);
pieceList.append(newP);
scene.addItem(newP);
}
// 读取规则限时要求
timeLimit = chess.getRule()->maxTime;
@ -218,7 +222,8 @@ void GameController::setEngine1(bool arg)
void GameController::setEngine2(bool arg)
{
isEngine2 = arg;
qDebug() << "size of NineChess::ChessData" << sizeof(NineChess::ChessData);
qDebug() << "size of NineChess: " << sizeof(chess);
}
void GameController::setAnimation(bool arg)
@ -243,10 +248,10 @@ void GameController::playSound(const QString &soundPath)
}
}
bool GameController::eventFilter(QObject * watched, QEvent * event)
{
return QObject::eventFilter(watched, event);
}
//bool GameController::eventFilter(QObject * watched, QEvent * event)
//{
// return QObject::eventFilter(watched, event);
//}
void GameController::timerEvent(QTimerEvent *event)
{
@ -348,7 +353,7 @@ bool GameController::phaseChange(int row)
qDebug() << mlist.at(i);
chessTemp.command(mlist.at(i).toStdString().c_str());
}
// 下面这步关键,让悔棋者承担时间损失
// 下面这步关键,让悔棋者承担时间损失
chessTemp.setStartTimeb(chess.getStartTimeb());
// 刷新棋局场景
updateScence(chessTemp);
@ -583,12 +588,12 @@ bool GameController::updateScence()
bool GameController::updateScence(NineChess &chess)
{
const char *board = chess.getBoard();
QPointF pos;
// chess类中的棋子代码
int key;
// 棋子总数
int n = chess.getRule()->numOfChess * 2;
const char *board = chess.getBoard();
QPointF pos;
// chess类中的棋子代码
int key;
// 棋子总数
int n = chess.getRule()->numOfChess * 2;
// 动画组
QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup;
@ -596,92 +601,100 @@ bool GameController::updateScence(NineChess &chess)
// 棋子就位
PieceItem *piece = nullptr;
for (int i = 0; i < n; i++)
{
piece = pieceList.at(i);
// 将pieceList的下标转换为chess的棋子代号
key = (i >= n/2) ? (i + 0x21 -n/2) : (i + 0x11);
int j;
// 放置棋盘上的棋子
for (j = NineChess::SEAT; j < (NineChess::SEAT)*(NineChess::RING + 1); j++)
{
if (board[j] == key)
{
pos = scene.cp2pos(j / NineChess::SEAT, j % NineChess::SEAT + 1);
if (piece->pos() != pos) {
{
piece = pieceList.at(i);
// 将pieceList的下标转换为chess的棋子代号
key = (i % 2) ? (i/2 + 0x21) : (i/2 + 0x11);
int j;
// 遍历棋盘,查找并放置棋盘上的棋子
for (j = NineChess::SEAT; j < (NineChess::SEAT)*(NineChess::RING + 1); j++)
{
if (board[j] == key)
{
pos = scene.cp2pos(j / NineChess::SEAT, j % NineChess::SEAT + 1);
if (piece->pos() != pos) {
// 让移动的棋子位于顶层
piece->setZValue(1);
// 棋子移动动画
QPropertyAnimation *animation = new QPropertyAnimation(piece, "pos");
animation->setDuration(durationTime);
animation->setStartValue(piece->pos());
animation->setEndValue(pos);
animation->setEasingCurve(QEasingCurve::InOutQuad);
animationGroup->addAnimation(animation);
}
break;
}
}
animation->setDuration(durationTime);
animation->setStartValue(piece->pos());
animation->setEndValue(pos);
animation->setEasingCurve(QEasingCurve::InOutQuad);
animationGroup->addAnimation(animation);
}
else
{
// 让静止的棋子位于底层
piece->setZValue(0);
}
break;
}
}
// 放置棋盘外的棋子
if (j == (NineChess::SEAT)*(NineChess::RING + 1))
{
// 判断是被吃掉的子,还是未安放的子
if (key & 0x10) {
pos = (key - 0x11 < n / 2 - chess.getPlayer1_InHand()) ? scene.pos_p2_g : scene.pos_p1;
}
else
pos = (key - 0x21 < n / 2 - chess.getPlayer2_InHand()) ? scene.pos_p1_g : scene.pos_p2;
// 如果没有找到,放置棋盘外的棋子
if (j == (NineChess::SEAT)*(NineChess::RING + 1))
{
// 判断是被吃掉的子,还是未安放的子
if (key & 0x10) {
pos = (key - 0x11 < n / 2 - chess.getPlayer1_InHand()) ? scene.pos_p2_g : scene.pos_p1;
}
else
pos = (key - 0x21 < n / 2 - chess.getPlayer2_InHand()) ? scene.pos_p1_g : scene.pos_p2;
if (piece->pos() != pos) {
if (piece->pos() != pos) {
QPropertyAnimation *animation = new QPropertyAnimation(piece, "pos");
animation->setDuration(durationTime);
animation->setStartValue(piece->pos());
animation->setEndValue(pos);
animation->setEasingCurve(QEasingCurve::InOutQuad);
animationGroup->addAnimation(animation);
animation->setEasingCurve(QEasingCurve::InOutQuad);
animationGroup->addAnimation(animation);
}
}
piece->setSelected(false);
}
piece->setSelected(false);
}
// 添加开局禁子点
if (chess.getRule()->hasForbidden && chess.getPhase() == NineChess::GAME_OPENING)
{
for (int j = NineChess::SEAT; j < (NineChess::SEAT)*(NineChess::RING + 1); j++)
{
if (board[j] == 0x0F)
{
pos = scene.cp2pos(j / NineChess::SEAT, j % NineChess::SEAT + 1);
if (n < pieceList.size())
{
pieceList.at(n++)->setPos(pos);
}
else
{
PieceItem *newP = new PieceItem;
newP->setDeleted();
newP->setPos(pos);
pieceList.append(newP);
n++;
scene.addItem(newP);
}
}
}
}
// 添加开局禁子点
if (chess.getRule()->hasForbidden && chess.getPhase() == NineChess::GAME_OPENING)
{
for (int j = NineChess::SEAT; j < (NineChess::SEAT)*(NineChess::RING + 1); j++)
{
if (board[j] == 0x0F)
{
pos = scene.cp2pos(j / NineChess::SEAT, j % NineChess::SEAT + 1);
if (n < pieceList.size())
{
pieceList.at(n++)->setPos(pos);
}
else
{
PieceItem *newP = new PieceItem;
newP->setDeleted();
newP->setPos(pos);
pieceList.append(newP);
n++;
scene.addItem(newP);
}
}
}
}
// 中局清除禁子点
if (chess.getRule()->hasForbidden && chess.getPhase() != NineChess::GAME_OPENING)
{
while (n < pieceList.size())
{
delete pieceList.at(n);
pieceList.removeAt(n);
}
}
// 中局清除禁子点
if (chess.getRule()->hasForbidden && chess.getPhase() != NineChess::GAME_OPENING)
{
while (n < pieceList.size())
{
delete pieceList.at(n);
pieceList.removeAt(n);
}
}
// 选中当前棋子
// 选中当前棋子
int ipos = chess.getCurrentPos();
if (ipos) {
key = board[chess.getCurrentPos()];
currentPiece = pieceList.at(key & 0x10 ? key - 0x11 : key - 0x21 + n/2);
currentPiece->setSelected(true);
key = board[chess.getCurrentPos()];
currentPiece = pieceList.at(key & 0x10 ? (key - 0x11)*2 : (key - 0x21)*2 + 1);
currentPiece->setSelected(true);
}
animationGroup->start(QAbstractAnimation::DeleteWhenStopped);

View File

@ -80,7 +80,7 @@ public slots:
bool updateScence(NineChess &chess);
protected:
bool eventFilter(QObject * watched, QEvent * event);
//bool eventFilter(QObject * watched, QEvent * event);
// 定时器
void timerEvent(QTimerEvent * event);
// 选子

View File

@ -105,15 +105,57 @@ const char NineChess::inBoard[(RING + 2)*SEAT] = {
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'
};
// 招法表
char NineChess::moveTable[(RING + 2)*SEAT][4] = { 0 };
// 成三表
char NineChess::millTable[(RING + 2)*SEAT][3][2] = { 0 };
NineChess::NineChess()
{
// 单独提出board免得每次都写data.board;
board = data.board;
// 默认选择第0号规则即“成三棋”
setData(&RULES[0]);
}
NineChess::NineChess(const NineChess &chess)
{
rule = chess.rule;
data = chess.data;
board = data.board;
currentPos = chess.currentPos;
winner = chess.winner;
startTimeb = chess.startTimeb;
currentTimeb = chess.currentTimeb;
player1_MS = chess.player1_MS;
player2_MS = chess.player2_MS;
move_ = chess.move_;
memcpy(cmdline, chess.cmdline, sizeof(cmdline));
cmdlist = chess.cmdlist;
tip = chess.tip;
}
const NineChess & NineChess::operator=(const NineChess &chess)
{
if (this == &chess)
return *this;
rule = chess.rule;
data = chess.data;
board = data.board;
currentPos = chess.currentPos;
winner = chess.winner;
startTimeb = chess.startTimeb;
currentTimeb = chess.currentTimeb;
player1_MS = chess.player1_MS;
player2_MS = chess.player2_MS;
move_ = chess.move_;
memcpy(cmdline, chess.cmdline, sizeof(cmdline));
cmdlist = chess.cmdlist;
tip = chess.tip;
}
NineChess::~NineChess()
{
}
@ -129,45 +171,85 @@ bool NineChess::setData(const struct Rule *rule, int s, int t, int step, int fla
this->rule = *rule;
this->rule.maxSteps = s;
this->rule.maxTime = t;
// 设置步数
this->step = step;
// 设置状态
// 设置棋局数据
{
// 设置步数
data.step = step;
// 局面阶段标识
if (flags & GAME_NOTSTARTED)
data.phase = GAME_NOTSTARTED;
else if (flags & GAME_OPENING)
data.phase = GAME_OPENING;
else if (flags & GAME_MID)
data.phase = GAME_MID;
else if (flags & GAME_OVER)
data.phase = GAME_OVER;
else
return false;
// 轮流状态标识
if (flags & PLAYER1)
data.turn = PLAYER1;
else if (flags & PLAYER2)
data.turn = PLAYER2;
else
return false;
// 动作状态标识
if (flags & ACTION_CHOOSE)
data.action = ACTION_CHOOSE;
else if (flags & ACTION_PLACE)
data.action = ACTION_PLACE;
else if (flags & ACTION_REMOVE)
data.action = ACTION_REMOVE;
else
return false;
// 当前棋局3×8
if (boardsource == nullptr)
memset(data.board, 0, sizeof(data.board));
else
memcpy(data.board, boardsource, sizeof(data.board));
// 计算盘面子数
data.player1_Remain = data.player2_Remain = 0;
for (int i = 1; i < RING + 2; i++)
{
for (int j = 0; j < SEAT; j++)
{
if (data.board[i*SEAT + j] & '\x10')
data.player1_Remain++;
else if (data.board[i*SEAT + j] & '\x20') {
data.player2_Remain++;
}
}
}
// 设置玩家盘面剩余子数和未放置子数
if (data.player1_Remain > rule->numOfChess || data.player2_Remain > rule->numOfChess)
return false;
if (p1_InHand < 0 || p2_InHand < 0)
return false;
data.player1_InHand = rule->numOfChess - data.player1_Remain;
data.player2_InHand = rule->numOfChess - data.player2_Remain;
data.player1_InHand = p1_InHand < data.player1_InHand ? p1_InHand : data.player1_InHand;
data.player2_InHand = p2_InHand < data.player2_InHand ? p2_InHand : data.player2_InHand;
// 设置去子状态时的剩余尚待去除子数
if (flags & ACTION_REMOVE) {
if (num_NeedRemove >= 0 && num_NeedRemove < 3)
data.num_NeedRemove = num_NeedRemove;
}
else
data.num_NeedRemove = 0;
// 清空成三记录
data.millList.clear();
}
// 局面阶段标识
if (flags & GAME_NOTSTARTED)
phase = GAME_NOTSTARTED;
else if (flags & GAME_OPENING)
phase = GAME_OPENING;
else if (flags & GAME_MID)
phase = GAME_MID;
else if (flags & GAME_OVER)
phase = GAME_OVER;
else
return false;
// 轮流状态标识
if (flags & PLAYER1)
turn = PLAYER1;
else if (flags & PLAYER2)
turn = PLAYER2;
else
return false;
// 动作状态标识
if (flags & ACTION_CHOOSE)
action = ACTION_CHOOSE;
else if (flags & ACTION_PLACE)
action = ACTION_PLACE;
else if (flags & ACTION_REMOVE)
action = ACTION_REMOVE;
else
return false;
// 胜负标识
winner = NOBODY;
// 当前棋局3×8
if (boardsource == nullptr)
memset(this->board, 0, sizeof(this->board));
else
memcpy(this->board, boardsource, sizeof(this->board));
// 生成招法表
for (int i = 1; i <= RING; i++)
{
@ -197,6 +279,7 @@ bool NineChess::setData(const struct Rule *rule, int s, int t, int step, int fla
//}
}
}
// 生成成三表
for (int j = 0; j < SEAT; j++)
{
@ -256,40 +339,6 @@ bool NineChess::setData(const struct Rule *rule, int s, int t, int step, int fla
}
}
// 计算盘面子数
player1_Remain = player2_Remain = 0;
for (int i = 1; i < RING + 2; i++)
{
for (int j = 0; j < SEAT; j++)
{
if (board[i*SEAT + j] & '\x10')
player1_Remain++;
else if (board[i*SEAT + j] & '\x20') {
player2_Remain++;
}
}
}
// 设置玩家盘面剩余子数和未放置子数
if (player1_Remain > rule->numOfChess || player2_Remain > rule->numOfChess)
return false;
if (p1_InHand < 0 || p2_InHand < 0)
return false;
player1_InHand = rule->numOfChess - player1_Remain;
player2_InHand = rule->numOfChess - player2_Remain;
player1_InHand = p1_InHand < player1_InHand ? p1_InHand : player1_InHand;
player2_InHand = p2_InHand < player2_InHand ? p2_InHand : player2_InHand;
// 设置去子状态时的剩余尚待去除子数
if (flags & ACTION_REMOVE) {
if (num_NeedRemove >= 0 && num_NeedRemove < 3)
this->num_NeedRemove = num_NeedRemove;
}
else
this->num_NeedRemove = 0;
// 清空成三记录
millList.clear();
// 不选中棋子
currentPos = 0;
@ -318,39 +367,32 @@ bool NineChess::setData(const struct Rule *rule, int s, int t, int step, int fla
//return true;
}
void NineChess::getData(struct Rule &rule, int &step, int &chess, const char *&board,
void NineChess::getData(struct Rule &rule, int &step, int &flags, const char *&board,
int &p1_InHand, int &p2_InHand, int &num_NeedRemove)
{
rule = this->rule;
step = this->step;
chess = phase | turn | action | winner;
board = this->board;
p1_InHand = player1_InHand;
p2_InHand = player2_InHand;
num_NeedRemove = this->num_NeedRemove;
}
const char * NineChess::getBoard()
{
return board;
step = data.step;
flags = data.phase | data.turn | data.action;
board = board;
p1_InHand = data.player1_InHand;
p2_InHand = data.player2_InHand;
num_NeedRemove = data.num_NeedRemove;
}
bool NineChess::reset()
{
if (phase == GAME_NOTSTARTED && player1_MS == player2_MS == 0)
if (data.phase == GAME_NOTSTARTED && player1_MS == player2_MS == 0)
return true;
// 步数归零
step = 0;
data.step = 0;
// 局面阶段标识
phase = GAME_NOTSTARTED;
data.phase = GAME_NOTSTARTED;
// 轮流状态标识
turn = PLAYER1;
data.turn = PLAYER1;
// 动作状态标识
action = ACTION_PLACE;
data.action = ACTION_PLACE;
// 胜负标识
winner = NOBODY;
@ -359,16 +401,16 @@ bool NineChess::reset()
memset(board, 0, sizeof(board));
// 盘面子数归零
player1_Remain = player2_Remain = 0;
data.player1_Remain = data.player2_Remain = 0;
// 设置玩家盘面剩余子数和未放置子数
player1_InHand = player2_InHand = rule.numOfChess;
data.player1_InHand = data.player2_InHand = rule.numOfChess;
// 设置去子状态时的剩余尚待去除子数
num_NeedRemove = 0;
data.num_NeedRemove = 0;
// 清空成三记录
millList.clear();
data.millList.clear();
// 不选中棋子
currentPos = 0;
@ -400,25 +442,82 @@ bool NineChess::reset()
bool NineChess::start()
{
switch (data.phase)
{
// 如果游戏已经开始则返回false
if (phase == GAME_OPENING || phase == GAME_MID)
case GAME_OPENING:
case GAME_MID:
return false;
// 如果游戏结束,则重置游戏,进入未开始状态
if (phase == GAME_OVER)
reset();
case GAME_OVER:
reset(); // 这里不要break;
// 如果游戏处于未开始状态
if (phase == GAME_NOTSTARTED) {
phase = GAME_OPENING;
case GAME_NOTSTARTED:
// 启动计时器
ftime(&startTimeb);
// 进入开局状态
data.phase = GAME_OPENING;
return true;
default:
return false;
}
}
bool NineChess::getPieceCP(const Players &player, const int &number, int &c, int &p)
{
char piece;
if (player == PLAYER1)
piece = 0x10;
else if (player == PLAYER2)
piece = 0x20;
else
return false;
if (number > 0 && number <= rule.numOfChess)
piece &= number;
else
return false;
for (int i = SEAT; i < SEAT*(RING + 1); i++) {
if (board[i] == piece) {
pos2cp(i, c, p);
return true;
}
}
// 其它情况
return false;
}
// 获取当前棋子
bool NineChess::getCurrentPiece(Players &player, int &number)
{
if (!inBoard[currentPos])
return false;
if (board[currentPos] & 0x10) {
player = PLAYER1;
number = board[currentPos] - 0x10;
}
else if (board[currentPos] & 0x20) {
player = PLAYER2;
number = board[currentPos] - 0x20;
}
else
return false;
return true;
}
bool NineChess::pos2cp(const int pos, int &c, int &p)
{
if (pos < SEAT || pos >= SEAT * (RING + 1))
return false;
c = pos / SEAT;
p = pos % SEAT + 1;
return true;
}
int NineChess::cp2pos(int c, int p)
{
if (c < 1 || c > RING || p < 1 || p > SEAT)
@ -429,14 +528,14 @@ int NineChess::cp2pos(int c, int p)
bool NineChess::place(int c, int p, long time_p /* = -1*/)
{
// 如果局面为“结局”返回false
if (phase == GAME_OVER)
if (data.phase == GAME_OVER)
return false;
// 如果局面为“未开局”,则开具
if (phase == GAME_NOTSTARTED)
if (data.phase == GAME_NOTSTARTED)
start();
// 如非“落子”状态返回false
if (action != ACTION_PLACE)
if (data.action != ACTION_PLACE)
return false;
// 如果落子位置在棋盘外、已有子点或禁点返回false
int pos = cp2pos(c, p);
@ -448,28 +547,28 @@ bool NineChess::place(int c, int p, long time_p /* = -1*/)
// 对于开局落子
char piece = '\x00';
int n = 0;
if (phase == GAME_OPENING) {
if (data.phase == GAME_OPENING) {
// 先手下
if (turn == PLAYER1)
if (data.turn == PLAYER1)
{
piece = '\x11' + rule.numOfChess - player1_InHand;
board[pos] = piece;
player1_InHand--;
player1_Remain++;
piece = '\x11' + rule.numOfChess - data.player1_InHand;
data.player1_InHand--;
data.player1_Remain++;
}
// 后手下
else
{
piece = '\x21' + rule.numOfChess - player2_InHand;
board[pos] = piece;
player2_InHand--;
player2_Remain++;
piece = '\x21' + rule.numOfChess - data.player2_InHand;
data.player2_InHand--;
data.player2_Remain++;
}
board[pos] = piece;
move_ = pos;
player_ms = update(time_p);
sprintf(cmdline, "(%1u,%1u) %02u:%02u.%03u", c, p, player_ms / 60000, player_ms / 1000, player_ms % 1000);
cmdlist.push_back(string(cmdline));
currentPos = pos;
step++;
data.step++;
// 如果决出胜负
if (win()) {
setTip();
@ -480,20 +579,21 @@ bool NineChess::place(int c, int p, long time_p /* = -1*/)
// 开局阶段未成三
if (n == 0) {
// 如果双方都无未放置的棋子
if (player1_InHand == 0 && player2_InHand == 0) {
if (data.player1_InHand == 0 && data.player2_InHand == 0) {
// 进入中局阶段
phase = GAME_MID;
data.phase = GAME_MID;
// 进入选子状态
action = ACTION_CHOOSE;
data.action = ACTION_CHOOSE;
// 清除禁点
cleanForbidden();
// 设置轮到谁走
if (rule.isDefensiveMoveFirst) {
turn = PLAYER2;
data.turn = PLAYER2;
}
else {
turn = PLAYER1;
data.turn = PLAYER1;
}
// 再决胜负
if (win()) {
setTip();
@ -509,19 +609,19 @@ bool NineChess::place(int c, int p, long time_p /* = -1*/)
// 如果成三
else {
// 设置去子数目
num_NeedRemove = rule.removeMore ? n : 1;
data.num_NeedRemove = rule.removeMore ? n : 1;
// 进入去子状态
action = ACTION_REMOVE;
data.action = ACTION_REMOVE;
}
setTip();
return true;
}
// 对于中局落子
else if (phase == GAME_MID) {
else if (data.phase == GAME_MID) {
// 如果落子不合法
if ((turn == PLAYER1 && (player1_Remain > rule.numAtLest || !rule.canFly)) ||
(turn == PLAYER2 && (player2_Remain > rule.numAtLest || !rule.canFly))) {
if ((data.turn == PLAYER1 && (data.player1_Remain > rule.numAtLest || !rule.canFly)) ||
(data.turn == PLAYER2 && (data.player2_Remain > rule.numAtLest || !rule.canFly))) {
int i;
for (i = 0; i < 4; i++) {
if (pos == moveTable[currentPos][i])
@ -532,6 +632,7 @@ bool NineChess::place(int c, int p, long time_p /* = -1*/)
return false;
}
// 移子
move_ = currentPos << 8 + pos;
player_ms = update(time_p);
sprintf(cmdline, "(%1u,%1u)->(%1u,%1u) %02u:%02u.%03u", currentPos / SEAT, currentPos % SEAT + 1,
c, p, player_ms / 60000, player_ms / 1000, player_ms % 1000);
@ -539,13 +640,13 @@ bool NineChess::place(int c, int p, long time_p /* = -1*/)
board[pos] = board[currentPos];
board[currentPos] = '\x00';
currentPos = pos;
step++;
data.step++;
n = addMills(currentPos);
// 中局阶段未成三
if (n == 0) {
// 进入选子状态
action = ACTION_CHOOSE;
data.action = ACTION_CHOOSE;
// 设置轮到谁走
changeTurn();
// 如果决出胜负
@ -557,9 +658,9 @@ bool NineChess::place(int c, int p, long time_p /* = -1*/)
// 中局阶段成三
else {
// 设置去子数目
num_NeedRemove = rule.removeMore ? n : 1;
data.num_NeedRemove = rule.removeMore ? n : 1;
// 进入去子状态
action = ACTION_REMOVE;
data.action = ACTION_REMOVE;
setTip();
}
setTip();
@ -572,20 +673,20 @@ bool NineChess::place(int c, int p, long time_p /* = -1*/)
bool NineChess::remove(int c, int p, long time_p /* = -1*/)
{
// 如果局面为"未开局"或“结局”返回false
if (phase == GAME_NOTSTARTED || phase == GAME_OVER)
if (data.phase == GAME_NOTSTARTED || data.phase == GAME_OVER)
return false;
// 如非“去子”状态返回false
if (action != ACTION_REMOVE)
if (data.action != ACTION_REMOVE)
return false;
// 如果去子完成返回false
if (num_NeedRemove <= 0)
if (data.num_NeedRemove <= 0)
return false;
// 时间的临时变量
long player_ms = -1;
int pos = cp2pos(c, p);
// 对手
enum Player opponent = PLAYER2;
if (turn == PLAYER2)
enum Players opponent = PLAYER2;
if (data.turn == PLAYER2)
opponent = PLAYER1;
// 判断去子不是对手棋
if (getWhosPiece(c, p) != opponent)
@ -597,20 +698,21 @@ bool NineChess::remove(int c, int p, long time_p /* = -1*/)
}
// 去子(设置禁点)
if (rule.hasForbidden && phase == GAME_OPENING)
if (rule.hasForbidden && data.phase == GAME_OPENING)
board[pos] = '\x0f';
else // 去子
board[pos] = '\x00';
if (turn == PLAYER1)
player2_Remain--;
else if (turn == PLAYER2)
player1_Remain--;
if (data.turn == PLAYER1)
data.player2_Remain--;
else if (data.turn == PLAYER2)
data.player1_Remain--;
move_ = -pos;
player_ms = update(time_p);
sprintf(cmdline, "-(%1u,%1u) %02u:%02u.%03u", c, p, player_ms / 60000, player_ms / 1000, player_ms % 1000);
cmdlist.push_back(string(cmdline));
currentPos = 0;
num_NeedRemove--;
step++;
data.num_NeedRemove--;
data.step++;
// 去子完成
// 如果决出胜负
@ -619,28 +721,28 @@ bool NineChess::remove(int c, int p, long time_p /* = -1*/)
return true;
}
// 还有其余的子要去吗
if (num_NeedRemove > 0) {
if (data.num_NeedRemove > 0) {
// 继续去子
return true;
}
// 所有去子都完成了
else {
// 开局阶段
if (phase == GAME_OPENING) {
if (data.phase == GAME_OPENING) {
// 如果双方都无未放置的棋子
if (player1_InHand == 0 && player2_InHand == 0) {
if (data.player1_InHand == 0 && data.player2_InHand == 0) {
// 进入中局阶段
phase = GAME_MID;
data.phase = GAME_MID;
// 进入选子状态
action = ACTION_CHOOSE;
data.action = ACTION_CHOOSE;
// 清除禁点
cleanForbidden();
// 设置轮到谁走
if (rule.isDefensiveMoveFirst) {
turn = PLAYER2;
data.turn = PLAYER2;
}
else {
turn = PLAYER1;
data.turn = PLAYER1;
}
// 再决胜负
if (win()) {
@ -651,7 +753,7 @@ bool NineChess::remove(int c, int p, long time_p /* = -1*/)
// 如果双方还有子
else {
// 进入落子状态
action = ACTION_PLACE;
data.action = ACTION_PLACE;
// 设置轮到谁走
changeTurn();
// 如果决出胜负
@ -664,7 +766,7 @@ bool NineChess::remove(int c, int p, long time_p /* = -1*/)
// 中局阶段
else {
// 进入选子状态
action = ACTION_CHOOSE;
data.action = ACTION_CHOOSE;
// 设置轮到谁走
changeTurn();
// 如果决出胜负
@ -681,17 +783,17 @@ bool NineChess::remove(int c, int p, long time_p /* = -1*/)
bool NineChess::choose(int c, int p)
{
// 如果局面不是"中局”返回false
if (phase != GAME_MID)
if (data.phase != GAME_MID)
return false;
// 如非“选子”或“落子”状态返回false
if (action != ACTION_CHOOSE && action != ACTION_PLACE)
if (data.action != ACTION_CHOOSE && data.action != ACTION_PLACE)
return false;
int pos = cp2pos(c, p);
// 根据先后手,判断可选子
char t ='\0';
if (turn == PLAYER1)
if (data.turn == PLAYER1)
t = '\x10';
else if (turn == PLAYER2)
else if (data.turn == PLAYER2)
t = '\x20';
// 判断选子是否可选
if (board[pos] & t) {
@ -702,19 +804,19 @@ bool NineChess::choose(int c, int p)
// 选子
currentPos = pos;
// 选子完成,进入落子状态
action = ACTION_PLACE;
data.action = ACTION_PLACE;
return true;
}
return false;
}
bool NineChess::giveup(Player loser)
bool NineChess::giveup(Players loser)
{
if (phase == GAME_MID || phase == GAME_OPENING)
if (data.phase == GAME_MID || data.phase == GAME_OPENING)
{
if (loser == PLAYER1)
{
phase = GAME_OVER;
data.phase = GAME_OVER;
winner = PLAYER2;
tip = "玩家1投子认负恭喜玩家2获胜";
sprintf(cmdline, "Player1 give up!");
@ -723,7 +825,7 @@ bool NineChess::giveup(Player loser)
}
else if (loser == PLAYER2)
{
phase = GAME_OVER;
data.phase = GAME_OVER;
winner = PLAYER1;
tip = "玩家2投子认负恭喜玩家1获胜";
sprintf(cmdline, "Player2 give up!");
@ -784,7 +886,7 @@ bool NineChess::command(const char *cmd)
}
// 认输
args = sscanf(cmd, "Player%1u give up!", &t);
args = sscanf(cmd, "Players%1u give up!", &t);
if (args == 1) {
if (t == 1) {
return giveup(PLAYER1);
@ -801,11 +903,11 @@ bool NineChess::command(const char *cmd)
inline long NineChess::update(long time_p /*= -1*/)
{
long ret = -1;
long *player_ms = (turn == PLAYER1 ? &player1_MS : &player2_MS);
long playerNext_ms = (turn == PLAYER1 ? player2_MS : player1_MS);
long *player_ms = (data.turn == PLAYER1 ? &player1_MS : &player2_MS);
long playerNext_ms = (data.turn == PLAYER1 ? player2_MS : player1_MS);
// 根据局面调整计时器
switch (phase)
switch (data.phase)
{
case NineChess::GAME_OPENING:
case NineChess::GAME_MID:
@ -847,9 +949,9 @@ inline long NineChess::update(long time_p /*= -1*/)
// 是否分出胜负
bool NineChess::win()
{
if (phase == GAME_OVER)
if (data.phase == GAME_OVER)
return true;
if (phase == GAME_NOTSTARTED)
if (data.phase == GAME_NOTSTARTED)
return false;
// 如果有时间限定
@ -859,7 +961,7 @@ bool NineChess::win()
if (player1_MS > rule.maxTime * 60000) {
player1_MS = rule.maxTime * 60000;
winner = PLAYER2;
phase = GAME_OVER;
data.phase = GAME_OVER;
tip = "玩家1超时恭喜玩家2获胜";
sprintf(cmdline, "Time over. Player2 win!");
cmdlist.push_back(string(cmdline));
@ -869,7 +971,7 @@ bool NineChess::win()
else if (player2_MS > rule.maxTime * 60000) {
player2_MS = rule.maxTime * 60000;
winner = PLAYER1;
phase = GAME_OVER;
data.phase = GAME_OVER;
tip = "玩家2超时恭喜玩家1获胜";
sprintf(cmdline, "Time over. Player1 win!");
cmdlist.push_back(string(cmdline));
@ -879,9 +981,9 @@ bool NineChess::win()
// 如果有步数限定
if (rule.maxSteps > 0) {
if (step > rule.maxSteps) {
if (data.step > rule.maxSteps) {
winner = DRAW;
phase = GAME_OVER;
data.phase = GAME_OVER;
sprintf(cmdline, "Steps over. In draw!");
cmdlist.push_back(string(cmdline));
return true;
@ -889,26 +991,26 @@ bool NineChess::win()
}
// 如果玩家1子数小于赛点则玩家2获胜
if (player1_Remain + player1_InHand < rule.numAtLest) {
if (data.player1_Remain + data.player1_InHand < rule.numAtLest) {
winner = PLAYER2;
phase = GAME_OVER;
data.phase = GAME_OVER;
sprintf(cmdline, "Player2 win!");
cmdlist.push_back(string(cmdline));
return true;
}
// 如果玩家2子数小于赛点则玩家1获胜
else if (player2_Remain + player2_InHand < rule.numAtLest) {
else if (data.player2_Remain + data.player2_InHand < rule.numAtLest) {
winner = PLAYER1;
phase = GAME_OVER;
data.phase = GAME_OVER;
sprintf(cmdline, "Player1 win!");
cmdlist.push_back(string(cmdline));
return true;
}
// 如果摆满了,根据规则判断胜负
else if (player1_Remain + player2_Remain >= SEAT * RING) {
else if (data.player1_Remain + data.player2_Remain >= SEAT * RING) {
if (rule.isFullLose) {
winner = PLAYER2;
phase = GAME_OVER;
data.phase = GAME_OVER;
sprintf(cmdline, "Player2 win!");
cmdlist.push_back(string(cmdline));
return true;
@ -916,21 +1018,21 @@ bool NineChess::win()
else
{
winner = DRAW;
phase = GAME_OVER;
data.phase = GAME_OVER;
sprintf(cmdline, "Full. In draw!");
cmdlist.push_back(string(cmdline));
return true;
}
}
// 如果中局被“闷”
else if (phase == GAME_MID && action == ACTION_CHOOSE && isAllSurrounded(turn)) {
else if (data.phase == GAME_MID && data.action == ACTION_CHOOSE && isAllSurrounded(data.turn)) {
// 规则要求被“闷”判负,则对手获胜
if (rule.isNoWayLose) {
if (turn == PLAYER1)
if (data.turn == PLAYER1)
{
tip = "玩家1无子可走恭喜玩家2获胜";
winner = PLAYER2;
phase = GAME_OVER;
data.phase = GAME_OVER;
sprintf(cmdline, "Player1 no way to go. Player2 win!");
cmdlist.push_back(string(cmdline));
return true;
@ -939,7 +1041,7 @@ bool NineChess::win()
{
tip = "玩家2无子可走恭喜玩家1获胜";
winner = PLAYER1;
phase = GAME_OVER;
data.phase = GAME_OVER;
sprintf(cmdline, "Player2 no way to go. Player1 win!");
cmdlist.push_back(string(cmdline));
return true;
@ -1019,15 +1121,15 @@ int NineChess::addMills(int pos)
// 迭代器
list<long long>::iterator itor;
// 遍历
for (itor = millList.begin(); itor != millList.end(); itor++)
for (itor = data.millList.begin(); itor != data.millList.end(); itor++)
{
if (mill == *itor)
break;
}
// 如果没找到历史项
if (itor == millList.end()) {
if (itor == data.millList.end()) {
n++;
millList.push_back(mill);
data.millList.push_back(mill);
}
}
}
@ -1035,7 +1137,7 @@ int NineChess::addMills(int pos)
return n;
}
bool NineChess::isAllInMills(enum Player player)
bool NineChess::isAllInMills(enum Players player)
{
char ch = '\x00';
if (player == PLAYER1)
@ -1044,7 +1146,6 @@ bool NineChess::isAllInMills(enum Player player)
ch = '\x20';
else
return true;
for (int i = 1; i <= RING; i++)
for (int j = 0; j < SEAT; j++) {
if (board[i*SEAT + j] & ch) {
@ -1060,8 +1161,8 @@ bool NineChess::isAllInMills(enum Player player)
bool NineChess::isSurrounded(int pos)
{
// 判断pos处的棋子是否被“闷”
if ((turn == PLAYER1 && (player1_Remain > rule.numAtLest || !rule.canFly)) ||
(turn == PLAYER2 && (player2_Remain > rule.numAtLest || !rule.canFly)))
if ((data.turn == PLAYER1 && (data.player1_Remain > rule.numAtLest || !rule.canFly)) ||
(data.turn == PLAYER2 && (data.player2_Remain > rule.numAtLest || !rule.canFly)))
{
int i, movePos;
for (i = 0; i < 4; i++) {
@ -1078,7 +1179,7 @@ bool NineChess::isSurrounded(int pos)
}
// 判断玩家的棋子是否全部被围
bool NineChess::isAllSurrounded(enum Player ply)
bool NineChess::isAllSurrounded(enum Players ply)
{
char t = '\x30';
if (ply == PLAYER1)
@ -1086,11 +1187,11 @@ bool NineChess::isAllSurrounded(enum Player ply)
else if (ply == PLAYER2)
t &= '\x20';
// 如果摆满
if (player1_Remain + player2_Remain >= SEAT * RING)
if (data.player1_Remain + data.player2_Remain >= SEAT * RING)
return true;
// 判断是否可以飞子
if ((turn == PLAYER1 && (player1_Remain <= rule.numAtLest && rule.canFly)) ||
(turn == PLAYER2 && (player2_Remain <= rule.numAtLest && rule.canFly)))
if ((data.turn == PLAYER1 && (data.player1_Remain <= rule.numAtLest && rule.canFly)) ||
(data.turn == PLAYER2 && (data.player2_Remain <= rule.numAtLest && rule.canFly)))
{
return false;
}
@ -1121,52 +1222,53 @@ void NineChess::cleanForbidden()
}
}
enum NineChess::Player NineChess::changeTurn()
enum NineChess::Players NineChess::changeTurn()
{
// 设置轮到谁走
return turn = (turn == PLAYER1) ? PLAYER2 : PLAYER1;
data.turn = (data.turn == PLAYER1) ? PLAYER2 : PLAYER1;
return data.turn;
}
void NineChess::setTip()
{
switch (phase)
switch (data.phase)
{
case NineChess::GAME_NOTSTARTED:
tip = "轮到玩家1落子剩余" + std::to_string(player1_InHand) + "";
tip = "轮到玩家1落子剩余" + std::to_string(data.player1_InHand) + "";
break;
case NineChess::GAME_OPENING:
if (action == ACTION_PLACE) {
if (turn == PLAYER1) {
tip = "轮到玩家1落子剩余" + std::to_string(player1_InHand) + "";
if (data.action == ACTION_PLACE) {
if (data.turn == PLAYER1) {
tip = "轮到玩家1落子剩余" + std::to_string(data.player1_InHand) + "";
}
else if (turn == PLAYER2) {
tip = "轮到玩家2落子剩余" + std::to_string(player2_InHand) + "";
else if (data.turn == PLAYER2) {
tip = "轮到玩家2落子剩余" + std::to_string(data.player2_InHand) + "";
}
}
else if (action == ACTION_REMOVE) {
if (turn == PLAYER1) {
tip = "轮到玩家1去子需去" + std::to_string(num_NeedRemove) + "";
else if (data.action == ACTION_REMOVE) {
if (data.turn == PLAYER1) {
tip = "轮到玩家1去子需去" + std::to_string(data.num_NeedRemove) + "";
}
else if (turn == PLAYER2) {
tip = "轮到玩家2去子需去" + std::to_string(num_NeedRemove) + "";
else if (data.turn == PLAYER2) {
tip = "轮到玩家2去子需去" + std::to_string(data.num_NeedRemove) + "";
}
}
break;
case NineChess::GAME_MID:
if (action == ACTION_PLACE || action == ACTION_CHOOSE) {
if (turn == PLAYER1) {
if (data.action == ACTION_PLACE || data.action == ACTION_CHOOSE) {
if (data.turn == PLAYER1) {
tip = "轮到玩家1选子移动";
}
else if (turn == PLAYER2) {
else if (data.turn == PLAYER2) {
tip = "轮到玩家2选子移动";
}
}
else if (action == ACTION_REMOVE) {
if (turn == PLAYER1) {
tip = "轮到玩家1去子需去" + std::to_string(num_NeedRemove) + "";
else if (data.action == ACTION_REMOVE) {
if (data.turn == PLAYER1) {
tip = "轮到玩家1去子需去" + std::to_string(data.num_NeedRemove) + "";
}
else if (turn == PLAYER2) {
tip = "轮到玩家2去子需去" + std::to_string(num_NeedRemove) + "";
else if (data.turn == PLAYER2) {
tip = "轮到玩家2去子需去" + std::to_string(data.num_NeedRemove) + "";
}
}
break;
@ -1191,7 +1293,7 @@ void NineChess::setTip()
}
}
enum NineChess::Player NineChess::getWhosPiece(int c, int p)
enum NineChess::Players NineChess::getWhosPiece(int c, int p)
{
int pos = cp2pos(c, p);
if (board[pos] & '\x10')
@ -1201,13 +1303,6 @@ enum NineChess::Player NineChess::getWhosPiece(int c, int p)
return NOBODY;
}
int NineChess::getPieceNum(int c, int p)
{
int pos = cp2pos(c, p);
int n = 0x0f & board[pos];
return n;
}
void NineChess::getPlayer_TimeMS(int &p1_ms, int &p2_ms)
{
update();

View File

@ -21,6 +21,14 @@ using std::list;
class NineChess
{
public:
// 5个静态成员常量
// 3圈禁止修改
static const int RING = 3;
// 8位禁止修改
static const int SEAT = 8;
// 预定义的规则数目
static const int RULENUM = 4;
// 嵌套的规则结构体
struct Rule
{
@ -53,39 +61,80 @@ public:
// 包干最长时间超出判负为0则不计时
int maxTime;
};
// 预定义的规则
static const struct Rule RULES[RULENUM];
// 局面阶段标识
enum Phases {
GAME_NOTSTARTED = 0x00000001, // 未开局
GAME_OPENING = 0x00000002, // 开局(摆棋)
GAME_MID = 0x00000004, // 中局(走棋)
GAME_OVER = 0x00000008 // 结局
GAME_NOTSTARTED = 0x0001, // 未开局
GAME_OPENING = 0x0002, // 开局(摆棋)
GAME_MID = 0x0004, // 中局(走棋)
GAME_OVER = 0x0008 // 结局
};
// 玩家标识,轮流状态,胜负标识
enum Player {
PLAYER1 = 0x00000010, // 玩家1
PLAYER2 = 0x00000020, // 玩家2
DRAW = 0x00000040, // 双方和棋
NOBODY = 0x00000080 // 胜负未分
enum Players {
PLAYER1 = 0x0010, // 玩家1
PLAYER2 = 0x0020, // 玩家2
DRAW = 0x0040, // 双方和棋
NOBODY = 0x0080 // 胜负未分
};
// 动作状态标识
enum Actions {
ACTION_CHOOSE = 0x00000100, // 选子
ACTION_PLACE = 0x00000200, // 落子
ACTION_REMOVE = 0x00000400 // 提子
ACTION_CHOOSE = 0x0100, // 选子
ACTION_PLACE = 0x0200, // 落子
ACTION_REMOVE = 0x0400 // 提子
};
// 5个静态成员常量
// 3圈禁止修改
static const int RING = 3;
// 8位禁止修改
static const int SEAT = 8;
// 预定义的规则数目
static const int RULENUM = 4;
// 预定义的规则
static const struct Rule RULES[RULENUM];
// 棋局结构体,包含当前棋盘数据
// 单独分离出来供AI判断局面用生成置换表时使用
struct ChessData {
// 棋局抽象为一个5×8的char数组上下两行留空
/* 0x00代表无棋子
0x0F
0x110x1C112
0x210x2c112
(board[i] & 0x10)
(board[i] & 0x20) */
char board[(NineChess::RING + 2)*NineChess::SEAT];
// 当前步数
int step;
// 局面阶段标识
enum NineChess::Phases phase;
// 轮流状态标识
enum NineChess::Players turn;
// 动作状态标识
enum NineChess::Actions action;
// 玩家1剩余未放置子数
char player1_InHand;
// 玩家2剩余未放置子数
char player2_InHand;
// 玩家1盘面剩余子数
char player1_Remain;
// 玩家1盘面剩余子数
char player2_Remain;
// 尚待去除的子数
char num_NeedRemove;
/* 本打算用如下的结构体来表示“三连”
struct Mill {
char piece1; // “三连”中最小的棋子
char pos1; // 最小棋子的位置
char piece2; // 次小的棋子
char pos2; // 次小棋子的位置
char piece3; // 最大的棋子
char pos3; // 最大棋子的位置
};
64
0x 00 00 00 00 00 00 00 00
unused unused piece1 pos1 piece2 pos2 piece3 pos3
*/
// “三连列表”
list <long long> millList;
};
private:
// 空棋盘点位,用于判断一个棋子位置是否在棋盘上
@ -100,20 +149,19 @@ private:
static char millTable[(RING + 2)*SEAT][3][2];
public:
NineChess();
explicit NineChess();
virtual ~NineChess();
/* 拷贝构造函数
NineChess类没有指针类型的成员变量list内的值也是深拷贝
*/
//explicit NineChess(const NineChess &);
// 拷贝构造函数
explicit NineChess(const NineChess &);
// 运算符重载
const NineChess & operator=(const NineChess &);
// 设置棋局状态和棋盘数据,用于初始化
bool setData(const struct Rule *rule,
int s = 0, // 限制步数
int t = 0, // 限制时间
int step = 0, // 默认起始步数为0
int flags = GAME_NOTSTARTED | PLAYER1 | ACTION_PLACE | NOBODY, // 默认状态
int flags = GAME_NOTSTARTED | PLAYER1 | ACTION_PLACE, // 默认状态
const char *boardsource = nullptr, // 默认空棋盘
int p1_InHand = 12, // 玩家1剩余未放置子数
int p2_InHand = 12, // 玩家2剩余未放置子数
@ -122,30 +170,32 @@ public:
// 获取棋局状态和棋盘数据
void getData(struct Rule &rule, int &step, int &flags, const char *&boardsource, int &p1_InHand, int &p2_InHand, int &num_NeedRemove);
// 获取棋盘数据
const char *getBoard();
// 获取当前规则
const struct Rule *getRule() { return &rule; }
// 获取当前点
// 获取棋盘数据
const char *getBoard() { return data.board; }
// 获取棋子位置(c, p)
bool getPieceCP(const Players &player, const int &number, int &c, int &p);
// 获取当前棋子
bool getCurrentPiece(Players &player, int &number);
// 获取当前棋子位置点
int getCurrentPos() { return currentPos; }
// 获取当前步数
int getStep() { return step; }
int getStep() { return data.step; }
// 获取局面阶段标识
enum Phases getPhase() { return phase; }
enum Phases getPhase() { return data.phase; }
// 获取轮流状态标识
enum Player whosTurn() { return turn; }
enum Players whosTurn() { return data.turn; }
// 获取动作状态标识
enum Actions getAction() { return action; }
enum Actions getAction() { return data.action; }
// 判断胜负
enum Player whoWin() { return winner; }
enum Players whoWin() { return winner; }
// 玩家1和玩家2的用时
void getPlayer_TimeMS(int &p1_ms, int &p2_ms);
// 获取棋局的字符提示
const string getTip() { return tip; }
// 获取位置点棋子的归属人
enum Player getWhosPiece(int c, int p);
// 获取位置点棋子的序号
int getPieceNum(int c, int p);
enum Players getWhosPiece(int c, int p);
// 获取当前招法
const char *getCmdLine() { return cmdline; }
// 获得棋谱
@ -156,15 +206,15 @@ public:
void setStartTimeb(timeb stimeb) { startTimeb = stimeb; }
// 玩家1剩余未放置子数
int getPlayer1_InHand() { return player1_InHand; }
int getPlayer1_InHand() { return data.player1_InHand; }
// 玩家2剩余未放置子数
int getPlayer2_InHand() { return player2_InHand; }
int getPlayer2_InHand() { return data.player2_InHand; }
// 玩家1盘面剩余子数
int getPlayer1_Remain() { return player1_Remain; }
int getPlayer1_Remain() { return data.player1_Remain; }
// 玩家1盘面剩余子数
int getPlayer2_Remain() { return player2_Remain; }
int getPlayer2_Remain() { return data.player2_Remain; }
// 尚待去除的子数
int getNum_NeedRemove() { return num_NeedRemove; }
int getNum_NeedRemove() { return data.num_NeedRemove; }
// 游戏重置
bool reset();
@ -177,7 +227,7 @@ public:
// 去子在第c圈第p个位置为迎合日常c和p下标都从1开始
bool remove(int c, int p, long time_p = -1);
// 认输
bool giveup(Player loser);
bool giveup(Players loser);
// 命令行解析函数
bool command(const char *cmd);
@ -185,13 +235,15 @@ protected:
// 判断棋盘pos处的棋子处于几个“三连”中
int isInMills(int pos);
// 判断玩家的所有棋子是否都处于“三连”状态
bool isAllInMills(enum Player);
bool isAllInMills(enum Players);
// 判断玩家的棋子是否被围
bool isSurrounded(int pos);
// 判断玩家的棋子是否全部被围
bool isAllSurrounded(enum Player);
bool isAllSurrounded(enum Players);
// 三连加入列表
int addMills(int pos);
// 将棋盘下标形式转化为第c圈第p位c和p下标都从1开始
bool pos2cp(const int pos, int &c, int &p);
// 将第c圈第p位转化为棋盘下标形式c和p下标都从1开始
int cp2pos(int c, int p);
// 更新时间和状态,用内联函数以提高效率
@ -201,72 +253,21 @@ protected:
// 清除所有禁点
void cleanForbidden();
// 改变轮流
enum NineChess::Player changeTurn();
enum NineChess::Players changeTurn();
// 设置提示
void setTip();
private:
// 当前步数
int step;
// 局面阶段标识
enum Phases phase;
// 轮流状态标识
enum Player turn;
// 动作状态标识
enum Actions action;
// 赢家
enum Player winner;
// 玩家1剩余未放置子数
int player1_InHand;
// 玩家2剩余未放置子数
int player2_InHand;
// 玩家1盘面剩余子数
int player1_Remain;
// 玩家1盘面剩余子数
int player2_Remain;
// 尚待去除的子数
int num_NeedRemove;
/* 棋局抽象为一个5×8的char数组上下两行留空
* 0x00
* 0x0F
* 0x110x1C112
* 0x210x2c112
* (board[i] & 0x10)
* (board[i] & 0x20)
*/
char board[(NineChess::RING + 2)*NineChess::SEAT];
/* 本打算用如下的结构体来表示“三连”
struct Mill {
char piece1; // “三连”中最小的棋子
char pos1; // 最小棋子的位置
char piece2; // 次小的棋子
char pos2; // 次小棋子的位置
char piece3; // 最大的棋子
char pos3; // 最大棋子的位置
};
64
0x 00 00 00 00 00 00 00 00
unused unused piece1 pos1 piece2 pos2 piece3 pos3
*/
// “三连列表”
list <long long> millList;
/* 当前招法AI会用到如下表示
0x 00 00
pos1 pos2
0x00????
0x__??__为移动前的位置??
0xFF????
*/
short move_;
// 当前使用的规则
struct Rule rule;
// 棋局数据
struct ChessData data;
// 棋局数据中的棋盘数据,单独提出来
char *board;
// 选中的棋子在board中的位置
int currentPos;
char currentPos;
// 胜负标识
enum Players winner;
// 游戏起始时间
timeb startTimeb;
@ -277,11 +278,22 @@ private:
// 玩家2用时毫秒
long player2_MS;
/* 当前招法AI会用到如下表示
0x 00 00
pos1 pos2
0x00????
0x__??__为移动前的位置??
0xFF????
*/
short move_;
// 招法命令行用于棋谱的显示和解析
// 当前招法的命令行指令,即一招棋谱
char cmdline[32];
// 棋谱
list <string> cmdlist;
// 当前棋局的字符提示
string tip;
};

View File

@ -251,7 +251,6 @@ void NineChessWindow::actionRules_triggered()
ruleInfo();
}
void NineChessWindow::on_actionNew_N_triggered()
{
if (file.isOpen())
@ -521,7 +520,6 @@ void NineChessWindow::on_actionAutoRun_A_toggled(bool arg1)
ui.actionAutoRun_A->setChecked(false);
}
void NineChessWindow::on_actionLimited_T_triggered()
{
/* 其实本来可以用设计器做个ui然后从QDialog派生个自己的对话框

View File

@ -32,6 +32,7 @@ public:
enum Models getModel() { return model; }
void setModel(enum Models model) { this->model = model; }
int getNum() { return num; }
void setNum(int n) { num = n; }
bool isDeleted() { return deleted; }
void setDeleted(bool deleted = true)