2018/5/21清理项目(17MB),重新提交2018/5/19日版:

游戏可以正确运行,实现本机对战功能,其它功能待完善。
This commit is contained in:
liuweilhy 2018-05-21 23:43:19 +08:00
commit e66ef36927
80 changed files with 5016 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
################################################################################
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
################################################################################
/NineChess/debug
/NineChess/release
/NineChess/GeneratedFiles
/NineChess/x64
/NineChess/.vs
/.vs

8
History.txt Normal file
View File

@ -0,0 +1,8 @@
九连棋 NineChess
更新历史:
2018/5/19 V1.0
1. Qt5.10.1+MSVC2017重构
2. 游戏可以正确运行,实现本机对战功能,其它功能待完善。
2015/11/6 V0.1
1. 无算法只有界面的程序。

15
Licence.txt Normal file
View File

@ -0,0 +1,15 @@
本软件代码遵循LGPL协议其中
1. 对于Qt库遵循GPL协议。任何人都可以免费使用但必须保持其开源
2. 对于原作者自行开发的代码:
2.1 未经原作者书面授权,任何人不得修改、传播;
2.2 获得原作者书面授权免费使用者:
2.2.1 其修改版必须对原作者开源;
2.2.2 其修改版必须完整保留本Licence文件如需新增内容只能在原版Licence文件末尾追加
2.2.3 原作者对其修改版在保留修改者署名情况下,有修改、传播及无偿商业化使用的权利;
2.3 获得原作者书面授权收费使用者,按照双方书面协议执行。
本软件的可执行文件:
1. Qt库文件归Qt版权方所有
2. 原作者、代码免费使用者的可执行文件,任何人可以免费使用、传播,但不得反汇编、修改,不得商用及其它违法用途。
3. 获得原作者书面授权收费使用者,按照双方书面协议执行。
—— by liuweilhy 2018.05.21

BIN
NineChess/NineChess.rc Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
NineChess/ninechess.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

48
NineChess/ninechess.pro Normal file
View File

@ -0,0 +1,48 @@
#-------------------------------------------------
#
# Project created by QtCreator 2015-11-03T22:30:34
#
#-------------------------------------------------
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01
QT += core gui \
multimedia
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = NineChess
TEMPLATE = app
SOURCES += src\main.cpp \
src\ninechesswindow.cpp \
src\pieceitem.cpp \
src\gamecontroller.cpp \
src\boarditem.cpp \
src\gameview.cpp \
src\ninechess.cpp \
src\gamescene.cpp
HEADERS += \
src\ninechesswindow.h \
src\pieceitem.h \
src\gamecontroller.h \
src\graphicsconst.h \
src\boarditem.h \
src\gameview.h \
src\ninechess.h \
src\sizehintlistview.h \
src\gamescene.h
FORMS += \
ninechesswindow.ui
RESOURCES += \
ninechesswindow.qrc
DISTFILES += \
Readme.txt \
NineChess.rc \
History.txt
RC_FILE += NineChess.rc

View File

@ -0,0 +1,318 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.5.1, 2018-05-17T00:26:36. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{fba36f69-c7a3-4c3f-91d4-7c71ad79549c}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.10.1 MSVC2017 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.10.1 MSVC2017 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5101.win64_msvc2017_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/build-ninechess-Desktop_Qt_5_10_1_MSVC2017_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>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<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"/>
<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>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<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"/>
<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>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清理</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<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/build-ninechess-Desktop_Qt_5_10_1_MSVC2017_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>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<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"/>
<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>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<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"/>
<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>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清理</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<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/build-ninechess-Desktop_Qt_5_10_1_MSVC2017_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>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<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"/>
<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>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<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"/>
<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>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清理</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<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.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">ninechess</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">ninechess2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:E:/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/build-ninechess-Desktop_Qt_5_10_1_MSVC2017_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>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">18</value>
</data>
<data>
<variable>Version</variable>
<value type="int">18</value>
</data>
</qtcreator>

25
NineChess/ninechess.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27703.2000
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ninechess", "ninechess.vcxproj", "{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
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}.Release|x64.ActiveCfg = Release|x64
{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {401C61DF-0B94-45A9-96C1-9BD069796A84}
EndGlobalSection
EndGlobal

306
NineChess/ninechess.vcxproj Normal file
View File

@ -0,0 +1,306 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D6EBE2B6-17F9-30EA-AE68-9CD0BB526200}</ProjectGuid>
<RootNamespace>NineChess</RootNamespace>
<Keyword>Qt4VSv1.0</Keyword>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<PlatformToolset>v141</PlatformToolset>
<OutputDirectory>release\</OutputDirectory>
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
<CharacterSet>NotSet</CharacterSet>
<ConfigurationType>Application</ConfigurationType>
<IntermediateDirectory>release\</IntermediateDirectory>
<PrimaryOutput>NineChess</PrimaryOutput>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<PlatformToolset>v141</PlatformToolset>
<OutputDirectory>debug\</OutputDirectory>
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
<CharacterSet>NotSet</CharacterSet>
<ConfigurationType>Application</ConfigurationType>
<IntermediateDirectory>debug\</IntermediateDirectory>
<PrimaryOutput>NineChess</PrimaryOutput>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">
<QtMsBuild>$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target>
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
<Import Project="$(QtMsBuild)\qt.props" />
</ImportGroup>
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NineChess</TargetName>
<IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</IgnoreImportLibrary>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NineChess</TargetName>
<IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IgnoreImportLibrary>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(QTDIR)\include;$(QTDIR)\include\QtMultimedia;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtCore;release;\include;$(QTDIR)\mkspecs\win32-msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
<AssemblerListingLocation>release\</AssemblerListingLocation>
<BrowseInformation>false</BrowseInformation>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ExceptionHandling>Sync</ExceptionHandling>
<ObjectFileName>$(IntDir)</ObjectFileName>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;QT_MULTIMEDIA_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_CORE_LIB;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<WarningLevel>Level3</WarningLevel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>$(QTDIR)\lib\qtmain.lib;shell32.lib;$(QTDIR)\lib\Qt5Multimedia.lib;$(QTDIR)\lib\Qt5Widgets.lib;$(QTDIR)\lib\Qt5Gui.lib;$(QTDIR)\lib\Qt5Network.lib;$(QTDIR)\lib\Qt5Core.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(QTDIR)\lib;C:\utils\my_sql\my_sql\lib;C:\utils\postgresql\pgsql\lib;$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
<DataExecutionPrevention>true</DataExecutionPrevention>
<GenerateDebugInformation>false</GenerateDebugInformation>
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
<OutputFile>$(OutDir)\NineChess.exe</OutputFile>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<SubSystem>Windows</SubSystem>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Link>
<Midl>
<DefaultCharType>Unsigned</DefaultCharType>
<EnableErrorChecks>None</EnableErrorChecks>
<WarningLevel>0</WarningLevel>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;QT_MULTIMEDIA_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<QtMoc>
<QTDIR>$(QTDIR)</QTDIR>
<OutputFile>.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</OutputFile>
<Define>UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;QT_MULTIMEDIA_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_CORE_LIB</Define>
<CompilerFlavor>msvc</CompilerFlavor>
<Include>$(Configuration)/moc_predefs.h</Include>
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
<InputFile>%(FullPath)</InputFile>
<DynamicSource>output</DynamicSource>
<IncludePath>.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;$(QTDIR)\mkspecs/win32-msvc;.;$(QTDIR)\include;$(QTDIR)\include/QtMultimedia;$(QTDIR)\include/QtWidgets;$(QTDIR)\include/QtGui;$(QTDIR)\include/QtANGLE;$(QTDIR)\include/QtNetwork;$(QTDIR)\include/QtCore;D:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\ATLMFC\include;D:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\ucrt;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\shared;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\winrt;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\cppwinrt</IncludePath>
</QtMoc>
<QtRcc>
<InitFuncName>ninechesswindow</InitFuncName>
<OutputFile>.\GeneratedFiles\qrc_%(Filename).cpp</OutputFile>
<QTDIR>$(QTDIR)</QTDIR>
<Compression>default</Compression>
<InputFile>%(FullPath)</InputFile>
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
</QtRcc>
<QtUic>
<QTDIR>$(QTDIR)</QTDIR>
<InputFile>%(FullPath)</InputFile>
<OutputFile>.\GeneratedFiles\ui_%(Filename).h</OutputFile>
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
</QtUic>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalIncludeDirectories>.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(QTDIR)\include;$(QTDIR)\include\QtMultimedia;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtCore;debug;\include;$(QTDIR)\mkspecs\win32-msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
<AssemblerListingLocation>debug\</AssemblerListingLocation>
<BrowseInformation>false</BrowseInformation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ExceptionHandling>Sync</ExceptionHandling>
<ObjectFileName>$(IntDir)</ObjectFileName>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_MULTIMEDIA_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<WarningLevel>Level3</WarningLevel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>$(QTDIR)\lib\qtmaind.lib;shell32.lib;$(QTDIR)\lib\Qt5Multimediad.lib;$(QTDIR)\lib\Qt5Widgetsd.lib;$(QTDIR)\lib\Qt5Guid.lib;$(QTDIR)\lib\Qt5Networkd.lib;$(QTDIR)\lib\Qt5Cored.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(QTDIR)\lib;C:\utils\my_sql\my_sql\lib;C:\utils\postgresql\pgsql\lib;$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
<DataExecutionPrevention>true</DataExecutionPrevention>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<OutputFile>$(OutDir)\NineChess.exe</OutputFile>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<SubSystem>Windows</SubSystem>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Link>
<Midl>
<DefaultCharType>Unsigned</DefaultCharType>
<EnableErrorChecks>None</EnableErrorChecks>
<WarningLevel>0</WarningLevel>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_MULTIMEDIA_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<QtRcc>
<QTDIR>$(QTDIR)</QTDIR>
<Compression>default</Compression>
<InitFuncName>ninechesswindow</InitFuncName>
<OutputFile>.\GeneratedFiles\qrc_%(Filename).cpp</OutputFile>
<InputFile>%(FullPath)</InputFile>
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
</QtRcc>
<QtMoc>
<QTDIR>$(QTDIR)</QTDIR>
<OutputFile>.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</OutputFile>
<Define>UNICODE;_UNICODE;WIN32;WIN64;QT_MULTIMEDIA_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_CORE_LIB</Define>
<CompilerFlavor>msvc</CompilerFlavor>
<Include>$(Configuration)/moc_predefs.h</Include>
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
<InputFile>%(FullPath)</InputFile>
<DynamicSource>output</DynamicSource>
<IncludePath>.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;$(QTDIR)\mkspecs/win32-msvc;.;$(QTDIR)\include;$(QTDIR)\include/QtMultimedia;$(QTDIR)\include/QtWidgets;$(QTDIR)\include/QtGui;$(QTDIR)\include/QtANGLE;$(QTDIR)\include/QtNetwork;$(QTDIR)\include/QtCore;D:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\ATLMFC\include;D:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\ucrt;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\shared;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\winrt;D:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\cppwinrt</IncludePath>
</QtMoc>
<QtUic>
<QTDIR>$(QTDIR)</QTDIR>
<InputFile>%(FullPath)</InputFile>
<OutputFile>.\GeneratedFiles\ui_%(Filename).h</OutputFile>
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
</QtUic>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\boarditem.cpp" />
<ClCompile Include="src\gamecontroller.cpp" />
<ClCompile Include="src\gamescene.cpp" />
<ClCompile Include="src\gameview.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\ninechess.cpp" />
<ClCompile Include="src\ninechesswindow.cpp" />
<ClCompile Include="src\pieceitem.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\boarditem.h" />
<QtMoc Include="src\gamecontroller.h">
</QtMoc>
<QtMoc Include="src\gamescene.h">
</QtMoc>
<QtMoc Include="src\gameview.h">
</QtMoc>
<ClInclude Include="src\graphicsconst.h" />
<ClInclude Include="src\ninechess.h" />
<QtMoc Include="src\ninechesswindow.h">
</QtMoc>
<ClInclude Include="src\pieceitem.h" />
<ClInclude Include="src\sizehintlistview.h" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;debug\moc_predefs.h</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generate moc_predefs.h</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_predefs.h;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Include="release\moc_predefs.h.cbt">
<FileType>Document</FileType>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2&gt;NUL &gt;release\moc_predefs.h</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Generate moc_predefs.h</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\moc_predefs.h;%(Outputs)</Outputs>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</CustomBuild>
<ClInclude Include="ui_ninechesswindow.h" />
</ItemGroup>
<ItemGroup>
<QtUic Include="ninechesswindow.ui">
</QtUic>
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon\ActualSizeHS.png" />
<None Include="Resources\icon\Black.png" />
<None Include="Resources\icon\BreakpointHS.png" />
<None Include="Resources\icon\DocumentHS.png" />
<None Include="Resources\icon\EditInformationHS.png" />
<None Include="Resources\icon\EditTableHS.png" />
<None Include="Resources\icon\Error.png" />
<None Include="Resources\icon\First.png" />
<None Include="Resources\icon\FlipHorizontalHS.png" />
<None Include="Resources\icon\FlipVerticalHS.png" />
<None Include="Resources\icon\FullScreenHS.png" />
<None Include="Resources\icon\Help.png" />
<None Include="Resources\icon\HomeHS.png" />
<None Include="Resources\icon\Invert.png" />
<None Include="Resources\icon\Last.png" />
<None Include="Resources\icon\LeftHS.png" />
<None Include="Resources\icon\LegendHS.png" />
<None Include="Resources\icon\NewDocumentHS.png" />
<None Include="Resources\icon\Next.png" />
<None Include="Resources\icon\OpenHS.png" />
<None Include="Resources\icon\OptionsHS.png" />
<None Include="Resources\icon\Pause.png" />
<None Include="Resources\icon\Play.png" />
<None Include="Resources\icon\Previous.png" />
<None Include="Resources\icon\PrimaryKeyHS.png" />
<None Include="Resources\icon\Refresh.png" />
<None Include="Resources\icon\Request.png" />
<None Include="Resources\icon\RestartHS.png" />
<None Include="Resources\icon\RightHS.png" />
<None Include="Resources\icon\SaveHS.png" />
<None Include="Resources\icon\Web.png" />
<None Include="Resources\icon\White.png" />
<None Include="Resources\image\background.png" />
<None Include="Resources\image\black_piece.png" />
<None Include="Resources\image\board.png" />
<QtRcc Include="ninechesswindow.qrc">
</QtRcc>
<None Include="Resources\image\white_piece.png" />
</ItemGroup>
<ItemGroup>
<None Include="History.txt" />
<None Include="NineChess.rc" />
<None Include="Readme.txt" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="NineChess.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
</ImportGroup>
<ImportGroup Label="ExtensionTargets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties UicDir=".\GeneratedFiles" RccDir=".\GeneratedFiles" Qt5Version_x0020_x64="qt5.10.1" />
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@ -0,0 +1,267 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
<ParseFiles>false</ParseFiles>
</Filter>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
<ParseFiles>false</ParseFiles>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
<Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
<Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</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="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>
<ParseFiles>false</ParseFiles>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
<Extensions>qrc;*</Extensions>
<ParseFiles>false</ParseFiles>
</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="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="Distribution Files">
<UniqueIdentifier>{B83CAF91-C7BF-462F-B76C-EA11631F866C}</UniqueIdentifier>
<Extensions>*</Extensions>
<ParseFiles>false</ParseFiles>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\boarditem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\gamecontroller.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\gamescene.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\gameview.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ninechess.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ninechesswindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\pieceitem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\boarditem.h">
<Filter>Header Files</Filter>
</ClInclude>
<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="src\pieceitem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\sizehintlistview.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
<Filter>Generated Files</Filter>
</CustomBuild>
<CustomBuild Include="release\moc_predefs.h.cbt">
<Filter>Generated Files</Filter>
</CustomBuild>
<ClInclude Include="ui_ninechesswindow.h">
<Filter>Generated Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtUic Include="ninechesswindow.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon\ActualSizeHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Black.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\BreakpointHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\DocumentHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\EditInformationHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\EditTableHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Error.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\First.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\FlipHorizontalHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\FlipVerticalHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\FullScreenHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Help.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\HomeHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Invert.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Last.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\LeftHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\LegendHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\NewDocumentHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Next.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\OpenHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\OptionsHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Pause.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Play.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Previous.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\PrimaryKeyHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Refresh.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Request.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\RestartHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\RightHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\SaveHS.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\Web.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\icon\White.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\image\background.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\image\black_piece.png">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources\image\board.png">
<Filter>Resource Files</Filter>
</None>
<QtRcc Include="ninechesswindow.qrc">
<Filter>Resource Files</Filter>
</QtRcc>
<None Include="Resources\image\white_piece.png">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<None Include="History.txt">
<Filter>Distribution Files</Filter>
</None>
<None Include="NineChess.rc">
<Filter>Distribution Files</Filter>
</None>
<None Include="Readme.txt">
<Filter>Distribution Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="NineChess.rc" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<QTDIR>D:\Qt\Qt5.10.1\5.10.1\msvc2017_64\</QTDIR>
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<QTDIR>D:\Qt\Qt5.10.1\5.10.1\msvc2017_64\</QTDIR>
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,43 @@
<RCC>
<qresource prefix="/image">
<file>Resources/image/black_piece.png</file>
<file>Resources/image/board.png</file>
<file>Resources/image/white_piece.png</file>
<file>Resources/image/background.png</file>
</qresource>
<qresource prefix="/icon">
<file>Resources/icon/Black.png</file>
<file>Resources/icon/White.png</file>
<file>Resources/icon/ActualSizeHS.png</file>
<file>Resources/icon/BreakpointHS.png</file>
<file>Resources/icon/DocumentHS.png</file>
<file>Resources/icon/EditInformationHS.png</file>
<file>Resources/icon/EditTableHS.png</file>
<file>Resources/icon/Error.png</file>
<file>Resources/icon/First.png</file>
<file>Resources/icon/FlipHorizontalHS.png</file>
<file>Resources/icon/FlipVerticalHS.png</file>
<file>Resources/icon/FullScreenHS.png</file>
<file>Resources/icon/Help.png</file>
<file>Resources/icon/HomeHS.png</file>
<file>Resources/icon/Last.png</file>
<file>Resources/icon/LeftHS.png</file>
<file>Resources/icon/LegendHS.png</file>
<file>Resources/icon/NewDocumentHS.png</file>
<file>Resources/icon/Next.png</file>
<file>Resources/icon/OpenHS.png</file>
<file>Resources/icon/Pause.png</file>
<file>Resources/icon/Play.png</file>
<file>Resources/icon/Previous.png</file>
<file>Resources/icon/PrimaryKeyHS.png</file>
<file>Resources/icon/Refresh.png</file>
<file>Resources/icon/Request.png</file>
<file>Resources/icon/OptionsHS.png</file>
<file>Resources/icon/Web.png</file>
<file>Resources/icon/RestartHS.png</file>
<file>Resources/icon/Invert.png</file>
<file>Resources/icon/RightHS.png</file>
<file>Resources/icon/SaveHS.png</file>
</qresource>
<qresource prefix="/sound"/>
</RCC>

View File

@ -0,0 +1,916 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NineChessWindowClass</class>
<widget class="QMainWindow" name="NineChessWindowClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<height>490</height>
</rect>
</property>
<property name="windowTitle">
<string>九连棋</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<widget class="QWidget" name="centralWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>3</horstretch>
<verstretch>3</verstretch>
</sizepolicy>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="GameView" name="gameView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>10</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>240</width>
<height>240</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-image: url(:/image/Resources/image/background.png);</string>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>561</width>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menu_F">
<property name="title">
<string>文件(&amp;F)</string>
</property>
<addaction name="actionNew_N"/>
<addaction name="actionOpen_O"/>
<addaction name="actionSave_S"/>
<addaction name="actionSaveAs_A"/>
<addaction name="separator"/>
<addaction name="actionViewText_V"/>
<addaction name="separator"/>
<addaction name="actionExit_X"/>
</widget>
<widget class="QMenu" name="menu_C">
<property name="title">
<string>棋局(&amp;C)</string>
</property>
<addaction name="actionEdit_E"/>
<addaction name="separator"/>
<addaction name="actionFlip_F"/>
<addaction name="actionMirror_M"/>
<addaction name="actionTurnRight_R"/>
<addaction name="actionTurnLeftt_L"/>
<addaction name="actionInvert_I"/>
</widget>
<widget class="QMenu" name="menu_M">
<property name="title">
<string>招法(&amp;M)</string>
</property>
<addaction name="actionBegin_S"/>
<addaction name="actionPrevious_B"/>
<addaction name="actionNext_F"/>
<addaction name="actionEnd_E"/>
<addaction name="actionAutoRun_A"/>
<addaction name="separator"/>
<addaction name="actionResign_R"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menu_E">
<property name="title">
<string>引擎(&amp;E)</string>
</property>
<addaction name="actionEngine_E"/>
<addaction name="actionLocal_L"/>
<addaction name="actionInternet_I"/>
<addaction name="separator"/>
<addaction name="actionEngine1_T"/>
<addaction name="actionEngine2_R"/>
</widget>
<widget class="QMenu" name="menu_O">
<property name="title">
<string>选项(&amp;O)</string>
</property>
<addaction name="actionSetting_O"/>
<addaction name="separator"/>
<addaction name="actionToolBar_T"/>
<addaction name="actionDockBar_D"/>
<addaction name="actionMusic_M"/>
<addaction name="actionSound_S"/>
<addaction name="actionAnimation_A"/>
</widget>
<widget class="QMenu" name="menu_H">
<property name="title">
<string>帮助(&amp;H)</string>
</property>
<addaction name="actionViewHelp_V"/>
<addaction name="actionWeb_W"/>
<addaction name="actionAbout_A"/>
</widget>
<widget class="QMenu" name="menu_R">
<property name="title">
<string>规则(&amp;R)</string>
</property>
<addaction name="separator"/>
<addaction name="actionLimited_T"/>
</widget>
<addaction name="menu_F"/>
<addaction name="menu_C"/>
<addaction name="menu_M"/>
<addaction name="menu_R"/>
<addaction name="menu_E"/>
<addaction name="menu_O"/>
<addaction name="menu_H"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<property name="windowTitle">
<string>工具栏</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionNew_N"/>
<addaction name="actionOpen_O"/>
<addaction name="actionSave_S"/>
<addaction name="separator"/>
<addaction name="actionEdit_E"/>
<addaction name="separator"/>
<addaction name="actionBegin_S"/>
<addaction name="actionPrevious_B"/>
<addaction name="actionNext_F"/>
<addaction name="actionEnd_E"/>
<addaction name="actionAutoRun_A"/>
<addaction name="separator"/>
<addaction name="actionEngine1_T"/>
<addaction name="actionEngine2_R"/>
<addaction name="actionLocal_L"/>
<addaction name="actionInternet_I"/>
</widget>
<widget class="QDockWidget" name="dockWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">QLCDNumber {
color: lightgreen;
background-color: rgb(32, 32, 32);
}</string>
</property>
<property name="floating">
<bool>false</bool>
</property>
<property name="allowedAreas">
<set>Qt::AllDockWidgetAreas</set>
</property>
<property name="windowTitle">
<string>对战记录</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QSplitter" name="splitter">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>1</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QLabel" name="picLabel1">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="ninechesswindow.qrc">:/icon/Resources/icon/Black.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label1">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>微软雅黑</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>玩家1</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLCDNumber" name="lcdNumber_1">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="smallDecimalPoint">
<bool>false</bool>
</property>
<property name="digitCount">
<number>9</number>
</property>
<property name="segmentStyle">
<enum>QLCDNumber::Flat</enum>
</property>
<property name="value" stdset="0">
<double>0.000000000000000</double>
</property>
<property name="intValue" stdset="0">
<number>0</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>1</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QLabel" name="picLabel2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="ninechesswindow.qrc">:/icon/Resources/icon/White.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>微软雅黑</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>玩家2</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLCDNumber" name="lcdNumber_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="smallDecimalPoint">
<bool>false</bool>
</property>
<property name="digitCount">
<number>9</number>
</property>
<property name="segmentStyle">
<enum>QLCDNumber::Flat</enum>
</property>
<property name="value" stdset="0">
<double>0.000000000000000</double>
</property>
<property name="intValue" stdset="0">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="SizeHintListView" name="listView">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>微软雅黑</family>
</font>
</property>
<property name="styleSheet">
<string notr="true">QToolTip {
font: 9pt &quot;consolas&quot;;
color: black;
}</string>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionNew_N">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/DocumentHS.png</normaloff>:/icon/Resources/icon/DocumentHS.png</iconset>
</property>
<property name="text">
<string>新建(&amp;N)</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
</property>
</action>
<action name="actionOpen_O">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/OpenHS.png</normaloff>:/icon/Resources/icon/OpenHS.png</iconset>
</property>
<property name="text">
<string>打开(&amp;O)...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="actionSave_S">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/SaveHS.png</normaloff>:/icon/Resources/icon/SaveHS.png</iconset>
</property>
<property name="text">
<string>保存(&amp;S)</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="actionSaveAs_A">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/SaveHS.png</normaloff>:/icon/Resources/icon/SaveHS.png</iconset>
</property>
<property name="text">
<string>另存为(&amp;A)...</string>
</property>
</action>
<action name="actionViewText_V">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/EditInformationHS.png</normaloff>:/icon/Resources/icon/EditInformationHS.png</iconset>
</property>
<property name="text">
<string>查看文本棋谱(&amp;V)</string>
</property>
</action>
<action name="actionExit_X">
<property name="text">
<string>退出(&amp;X)</string>
</property>
</action>
<action name="actionEdit_E">
<property name="checkable">
<bool>true</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/EditTableHS.png</normaloff>:/icon/Resources/icon/EditTableHS.png</iconset>
</property>
<property name="text">
<string>编辑棋局(&amp;E)</string>
</property>
</action>
<action name="actionFlip_F">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/FlipVerticalHS.png</normaloff>:/icon/Resources/icon/FlipVerticalHS.png</iconset>
</property>
<property name="text">
<string>上下翻转(&amp;F)</string>
</property>
</action>
<action name="actionMirror_M">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/FlipHorizontalHS.png</normaloff>:/icon/Resources/icon/FlipHorizontalHS.png</iconset>
</property>
<property name="text">
<string>左右翻转(&amp;M)</string>
</property>
</action>
<action name="actionTurnRight_R">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/RightHS.png</normaloff>:/icon/Resources/icon/RightHS.png</iconset>
</property>
<property name="text">
<string>顺时针旋转90°(&amp;R)</string>
</property>
<property name="toolTip">
<string>顺时针旋转90°(R)</string>
</property>
</action>
<action name="actionTurnLeftt_L">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/LeftHS.png</normaloff>:/icon/Resources/icon/LeftHS.png</iconset>
</property>
<property name="text">
<string>逆时针旋转90°(&amp;L)</string>
</property>
<property name="toolTip">
<string>逆时针旋转90°(L)</string>
</property>
</action>
<action name="actionInvert_I">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/Invert.png</normaloff>:/icon/Resources/icon/Invert.png</iconset>
</property>
<property name="text">
<string>黑白反转(&amp;B)</string>
</property>
</action>
<action name="actionBegin_S">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/First.png</normaloff>:/icon/Resources/icon/First.png</iconset>
</property>
<property name="text">
<string>初始局面(&amp;S)</string>
</property>
<property name="toolTip">
<string>初始局面(S)</string>
</property>
<property name="shortcut">
<string>Ctrl+Up</string>
</property>
</action>
<action name="actionPrevious_B">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/Previous.png</normaloff>:/icon/Resources/icon/Previous.png</iconset>
</property>
<property name="text">
<string>前一招(&amp;B)</string>
</property>
<property name="shortcut">
<string>Ctrl+Left</string>
</property>
</action>
<action name="actionNext_F">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/Next.png</normaloff>:/icon/Resources/icon/Next.png</iconset>
</property>
<property name="text">
<string>后一招(&amp;F)</string>
</property>
<property name="toolTip">
<string>后一招(F)</string>
</property>
<property name="shortcut">
<string>Ctrl+Right</string>
</property>
</action>
<action name="actionEnd_E">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/Last.png</normaloff>:/icon/Resources/icon/Last.png</iconset>
</property>
<property name="text">
<string>最后局面(&amp;E)</string>
</property>
<property name="shortcut">
<string>Ctrl+Down</string>
</property>
</action>
<action name="actionAutoRun_A">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/Play.png</normaloff>:/icon/Resources/icon/Play.png</iconset>
</property>
<property name="text">
<string>自动演示(&amp;A)</string>
</property>
<property name="toolTip">
<string>自动演示(A)</string>
</property>
</action>
<action name="actionResign_R">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/BreakpointHS.png</normaloff>:/icon/Resources/icon/BreakpointHS.png</iconset>
</property>
<property name="text">
<string>认输(&amp;G)</string>
</property>
</action>
<action name="actionLimited_T">
<property name="checked">
<bool>false</bool>
</property>
<property name="text">
<string>限制步数和时间(&amp;T)...</string>
</property>
<property name="toolTip">
<string>限制步数和时间(T)</string>
</property>
</action>
<action name="actionLocal_L">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/FullScreenHS.png</normaloff>:/icon/Resources/icon/FullScreenHS.png</iconset>
</property>
<property name="text">
<string>本机对战(&amp;L)</string>
</property>
<property name="toolTip">
<string>本机对战(L)</string>
</property>
</action>
<action name="actionInternet_I">
<property name="checkable">
<bool>true</bool>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/Web.png</normaloff>:/icon/Resources/icon/Web.png</iconset>
</property>
<property name="text">
<string>网络对战(&amp;I)</string>
</property>
<property name="toolTip">
<string>网络对战(I)</string>
</property>
</action>
<action name="actionEngine_E">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/OptionsHS.png</normaloff>:/icon/Resources/icon/OptionsHS.png</iconset>
</property>
<property name="text">
<string>引擎设置(&amp;E)...</string>
</property>
<property name="toolTip">
<string>引擎设置(E)</string>
</property>
</action>
<action name="actionEngine1_T">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/Black.png</normaloff>:/icon/Resources/icon/Black.png</iconset>
</property>
<property name="text">
<string>电脑执先手(&amp;T)</string>
</property>
<property name="toolTip">
<string>电脑执先手(T)</string>
</property>
</action>
<action name="actionEngine2_R">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/White.png</normaloff>:/icon/Resources/icon/White.png</iconset>
</property>
<property name="text">
<string>电脑执后手(&amp;R)</string>
</property>
<property name="toolTip">
<string>电脑执白(R)</string>
</property>
</action>
<action name="actionSetting_O">
<property name="enabled">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/PrimaryKeyHS.png</normaloff>:/icon/Resources/icon/PrimaryKeyHS.png</iconset>
</property>
<property name="text">
<string>设置(&amp;O)...</string>
</property>
</action>
<action name="actionToolBar_T">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>工具栏(&amp;T)</string>
</property>
</action>
<action name="actionDockBar_D">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>信息栏(&amp;D)</string>
</property>
</action>
<action name="actionMusic_M">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>背景音乐(&amp;M)</string>
</property>
<property name="visible">
<bool>false</bool>
</property>
</action>
<action name="actionSound_S">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>落子音效(&amp;S)</string>
</property>
</action>
<action name="actionAnimation_A">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>落子动画(&amp;A)</string>
</property>
<property name="toolTip">
<string>落子动画(A)</string>
</property>
</action>
<action name="actionViewHelp_V">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/Help.png</normaloff>:/icon/Resources/icon/Help.png</iconset>
</property>
<property name="text">
<string>查看帮助(&amp;V)</string>
</property>
<property name="shortcut">
<string>F1</string>
</property>
</action>
<action name="actionWeb_W">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/HomeHS.png</normaloff>:/icon/Resources/icon/HomeHS.png</iconset>
</property>
<property name="text">
<string>作者主页(&amp;W)</string>
</property>
<property name="toolTip">
<string>作者主页(W)</string>
</property>
</action>
<action name="actionAbout_A">
<property name="text">
<string>关于(&amp;A)...</string>
</property>
<property name="toolTip">
<string>关于(A)</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>GameView</class>
<extends>QGraphicsView</extends>
<header>gameview.h</header>
</customwidget>
<customwidget>
<class>SizeHintListView</class>
<extends>QListView</extends>
<header>sizehintlistview.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="ninechesswindow.qrc"/>
</resources>
<connections>
<connection>
<sender>actionDockBar_D</sender>
<signal>toggled(bool)</signal>
<receiver>dockWidget</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>507</x>
<y>214</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionToolBar_T</sender>
<signal>toggled(bool)</signal>
<receiver>mainToolBar</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>289</x>
<y>28</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionExit_X</sender>
<signal>triggered()</signal>
<receiver>NineChessWindowClass</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>289</x>
<y>207</y>
</hint>
</hints>
</connection>
<connection>
<sender>mainToolBar</sender>
<signal>visibilityChanged(bool)</signal>
<receiver>actionToolBar_T</receiver>
<slot>setChecked(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>280</x>
<y>47</y>
</hint>
<hint type="destinationlabel">
<x>-1</x>
<y>-1</y>
</hint>
</hints>
</connection>
<connection>
<sender>dockWidget</sender>
<signal>visibilityChanged(bool)</signal>
<receiver>actionDockBar_D</receiver>
<slot>setChecked(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>421</x>
<y>267</y>
</hint>
<hint type="destinationlabel">
<x>-1</x>
<y>-1</y>
</hint>
</hints>
</connection>
</connections>
</ui>

126
NineChess/src/boarditem.cpp Normal file
View File

@ -0,0 +1,126 @@
#include "boarditem.h"
#include "graphicsconst.h"
#include <QPainter>
BoardItem::BoardItem(QGraphicsItem *parent ) : QGraphicsItem(parent),
size(BOARD_SIZE),
sizeShadow(5.0),
hasObliqueLine(false)
{
Q_UNUSED(parent)
// 棋盘中心放在场景中心
setPos(0, 0);
// 初始化24个落子点
for (int i = 0; i < RING; i++)
{
// 内圈的12点钟方向为第一个位置按顺时针方向排序
// 然后是中圈和外圈
qreal a = (i+1)*LINE_INTERVAL;
position[i*SEAT+0].rx() = 0;
position[i*SEAT+0].ry() = -a;
position[i*SEAT+1].rx() = a;
position[i*SEAT+1].ry() = -a;
position[i*SEAT+2].rx() = a;
position[i*SEAT+2].ry() = 0;
position[i*SEAT+3].rx() = a;
position[i*SEAT+3].ry() = a;
position[i*SEAT+4].rx() = 0;
position[i*SEAT+4].ry() = a;
position[i*SEAT+5].rx() = -a;
position[i*SEAT+5].ry() = a;
position[i*SEAT+6].rx() = -a;
position[i*SEAT+6].ry() = 0;
position[i*SEAT+7].rx() = -a;
position[i*SEAT+7].ry() = -a;
}
}
BoardItem::~BoardItem()
{
}
QRectF BoardItem::boundingRect() const
{
return QRectF(-size/2, -size/2, size+sizeShadow, size+sizeShadow);
}
QPainterPath BoardItem::shape() const
{
QPainterPath path;
path.addRect(boundingRect());
return path;
}
void BoardItem::setDiagonal(bool arg)
{
hasObliqueLine = arg;
update(boundingRect());
}
void BoardItem::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
// 填充阴影
painter->fillRect(boundingRect(), QBrush(QColor(64, 64, 64)));
// 填充图片
painter->drawPixmap(-size/2, -size/2, size, size, QPixmap(":/image/Resources/image/board.png"));
// 黑色实线画笔
QPen pen(QBrush(Qt::black), LINE_WEIGHT, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin);
painter->setPen(pen);
// 空画刷
painter->setBrush(Qt::NoBrush);
for (int i = 0; i < RING; i++)
{
// 画3个方框
painter->drawPolygon(position+i*SEAT, SEAT);
}
// 画4条纵横线
painter->drawLine(position[0], position[(RING-1)*SEAT]);
painter->drawLine(position[2], position[(RING-1)*SEAT+2]);
painter->drawLine(position[4], position[(RING-1)*SEAT+4]);
painter->drawLine(position[6], position[(RING-1)*SEAT+6]);
if (hasObliqueLine)
{
// 画4条斜线
painter->drawLine(position[1], position[(RING-1)*SEAT+1]);
painter->drawLine(position[3], position[(RING-1)*SEAT+3]);
painter->drawLine(position[5], position[(RING-1)*SEAT+5]);
painter->drawLine(position[7], position[(RING-1)*SEAT+7]);
}
}
QPointF BoardItem::nearestPosition(QPointF const pos)
{
// 初始最近点设为(0,0)点
QPointF nearestPos = QPointF(0,0);
// 寻找最近的落子点
for (int i = 0; i < RING*SEAT; i++)
{
// 如果鼠标点距离落子点在棋子半径内
if (QLineF(pos, position[i]).length() < PIECE_SIZE/2)
{
nearestPos = position[i];
break;
}
}
return nearestPos;
}
bool BoardItem::pos2cp(QPointF pos, int &c, int &p)
{
// 寻找最近的落子点
for (int i = 0; i < RING*SEAT; i++)
{
// 如果pos点在落子点附近
if (QLineF(pos, position[i]).length() < PIECE_SIZE/6)
{
c = i / SEAT + 1;
p = i % SEAT + 1;
return true;
}
}
return false;
}

41
NineChess/src/boarditem.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef BOARDITEM_H
#define BOARDITEM_H
#include <QGraphicsItem>
class BoardItem : public QGraphicsItem
{
public:
explicit BoardItem(QGraphicsItem *parent = 0);
~BoardItem();
QRectF boundingRect() const;
QPainterPath shape() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget * widget = 0);
// 用UserType+1表示棋子用qgraphicsitem_cast()判断是否为BoardItem类的对象
// 还有一个方式是把类名放在Data的0key位置setData(0, "BoardItem")然后用data(0)来判断
enum { Type = UserType + 1 };
int type() const { return Type; }
// 设置有无斜线
void setDiagonal(bool arg = true);
// 返回最近的落子点
QPointF nearestPosition(QPointF const pos);
// 将落子点坐标转化为模型用的圈、位
bool pos2cp(QPointF pos, int &c, int &p);
// 3圈禁止修改
static const int RING = 3;
// 8位禁止修改
static const int SEAT = 8;
private:
// 棋盘尺寸
qreal size;
// 影子尺寸
qreal sizeShadow;
// 24个落子点
QPointF position[RING * SEAT];
// 是否有斜线
bool hasObliqueLine;
};
#endif // BOARDITEM_H

View File

@ -0,0 +1,530 @@
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
#include <QGraphicsView>
#include <QGraphicsSceneMouseEvent>
#include <QKeyEvent>
#include <QApplication>
#include <Qsound>
#include <QDebug>
#include "gamecontroller.h"
#include "graphicsconst.h"
#include "boarditem.h"
#include "pieceitem.h"
GameController::GameController(GameScene & scene, QObject *parent) : QObject(parent),
scene(scene),
piece(NULL),
isEditing(false),
isInverted(false),
isEngine1(false),
isEngine2(false),
hasAnimation(true),
hasSound(true),
timeID(0),
timeLimit(0),
stepsLimit(0)
{
// 设置场景尺寸大小为棋盘大小的1.08倍
scene.setSceneRect(-BOARD_SIZE * 0.54, -BOARD_SIZE * 0.54, BOARD_SIZE*1.08, BOARD_SIZE*1.08);
// 已在view的样式表中添加背景scene中不用添加背景
// 区别在于view中的背景不随视图变换而变换scene中的背景随视图变换而变换
//scene.setBackgroundBrush(QPixmap(":/image/Resources/image/background.png"));
// 初始化音效文件路径
QString dir = QCoreApplication::applicationDirPath();
soundNewgame = dir + "/sound/newgame.wav";
soundChoose = dir + "/sound/choose.wav";
soundMove = dir + "/sound/move.wav";
soundDrog = dir + "/sound/drog.wav";
soundForbidden = dir + "/sound/forbidden.wav";
soundRemove = dir + "/sound/remove.wav";
soundWin = dir + "/sound/win.wav";
soundLoss = dir + "/sound/loss.wav";
gameReset();
// 安装事件过滤器监视scene的各个事件由于我重载了QGraphicsScene相关事件在重载函数中已设定不必安装监视器。
//scene.installEventFilter(this);
}
GameController::~GameController()
{
}
const QMap<int, QStringList> GameController::getActions()
{
// 主窗口更新菜单栏
// 之所以不用信号和槽的模式,是因为发信号的时候槽还来不及关联
QMap<int, QStringList> actions;
for (int i = 0; i < NineChess::RULENUM; i++)
{
// QMap的key存放int索引值value存放规则名称和规则提示
QStringList strlist;
strlist.append(tr(NineChess::RULES[i].name));
strlist.append(tr(NineChess::RULES[i].info));
actions.insert(i, strlist);
}
return actions;
}
void GameController::gameStart()
{
// 每隔100毫秒调用一次定时器处理函数
timeID = startTimer(100);
}
void GameController::gameReset()
{
// 停止计时器
if (timeID != 0)
killTimer(timeID);
// 定时器ID为0
timeID = 0;
// 重置游戏
chess.reset();
// 清除棋子
qDeleteAll(pieceList);
pieceList.clear();
piece = NULL;
// 重新绘制棋盘
scene.setDiagonal(chess.getRule()->hasObliqueLine);
// 读取规则限时要求
timeLimit = chess.getRule()->maxTime;
// 如果规则不要求计时则time1和time2表示已用时间
if (timeLimit <= 0) {
// 将玩家的已用时间清零
time1 = time2 = 0;
}
else
{
// 将玩家的剩余时间置为限定时间
time1 = time2 = timeLimit * 60000;
}
// 发出信号通知主窗口更新LCD显示
QTime qtime = QTime(0, 0, 0, 0).addMSecs(time1);
emit time1Changed(qtime.toString("mm:ss.zzz"));
emit time2Changed(qtime.toString("mm:ss.zzz"));
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundNewgame);
}
void GameController::setEditing(bool arg)
{
isEditing = arg;
}
void GameController::setInvert(bool arg)
{
isInverted = arg;
// 遍历所有棋子
foreach(PieceItem * p, pieceList)
{
if (p)
{
// 黑子变白
if (p->getModel() == PieceItem::blackPiece)
p->setModel(PieceItem::whitePiece);
// 白子变黑
else if (p->getModel() == PieceItem::whitePiece)
p->setModel(PieceItem::blackPiece);
// 刷新棋子显示
p->update();
}
}
}
void GameController::setRule(int ruleNo)
{
// 停止计时器
if (timeID != 0)
killTimer(timeID);
// 定时器ID为0
timeID = 0;
// 更新规则,原限时和限步不变
struct NineChess::Rule rule;
if (ruleNo >= 0 && ruleNo < NineChess::RULENUM)
rule = NineChess::RULES[ruleNo];
rule.maxSteps = stepsLimit;
rule.maxTime = timeLimit;
// 设置模型规则,重置游戏
chess.setRule(&rule);
// 清除棋子
qDeleteAll(pieceList);
pieceList.clear();
piece = NULL;
// 重新绘制棋盘
scene.setDiagonal(chess.getRule()->hasObliqueLine);
// 如果规则不要求计时则time1和time2表示已用时间
if (timeLimit <= 0) {
// 将玩家的已用时间清零
time1 = time2 = 0;
}
else
{
// 将玩家的剩余时间置为限定时间
time1 = time2 = timeLimit * 60000;
}
// 发出信号通知主窗口更新LCD显示
QTime qtime = QTime(0, 0, 0, 0).addMSecs(time1);
emit time1Changed(qtime.toString("mm:ss.zzz"));
emit time2Changed(qtime.toString("mm:ss.zzz"));
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundNewgame);
}
void GameController::setRule(int ruleNo, int stepLimited, int timeLimited)
{
// 停止计时器
if (timeID != 0)
killTimer(timeID);
// 定时器ID为0
timeID = 0;
// 更新规则,原限时和限步不变
struct NineChess::Rule rule;
if (ruleNo >= 0 && ruleNo < NineChess::RULENUM)
rule = NineChess::RULES[ruleNo];
stepsLimit = rule.maxSteps = stepLimited;
timeLimit = rule.maxTime = timeLimited;
// 设置模型规则,重置游戏
chess.setRule(&rule);
// 清除棋子
qDeleteAll(pieceList);
pieceList.clear();
piece = NULL;
// 重新绘制棋盘
scene.setDiagonal(chess.getRule()->hasObliqueLine);
// 如果规则不要求计时则time1和time2表示已用时间
if (timeLimit <= 0) {
// 将玩家的已用时间清零
time1 = time2 = 0;
}
else
{
// 将玩家的剩余时间置为限定时间
time1 = time2 = timeLimit * 60000;
}
// 发出信号通知主窗口更新LCD显示
QTime qtime = QTime(0, 0, 0, 0).addMSecs(time1);
emit time1Changed(qtime.toString("mm:ss.zzz"));
emit time2Changed(qtime.toString("mm:ss.zzz"));
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundNewgame);
}
void GameController::setEngine1(bool arg)
{
isEngine1 = arg;
if (arg)
qDebug() << "Player1 is computer.";
else
qDebug() << "Player1 is not computer.";
}
void GameController::setEngine2(bool arg)
{
isEngine2 = arg;
if (arg)
qDebug() << "Player2 is computer.";
else
qDebug() << "Player2 is not computer.";
}
void GameController::setAnimation(bool arg)
{
hasAnimation = arg;
}
void GameController::setSound(bool arg)
{
hasSound = arg;
}
void GameController::playSound(QString &soundPath)
{
if (hasSound)
QSound::play(soundPath);
}
bool GameController::eventFilter(QObject * watched, QEvent * event)
{
return QObject::eventFilter(watched, event);
}
void GameController::timerEvent(QTimerEvent *event)
{
static QTime qt1, qt2;
// 玩家的已用时间
chess.getPlayer_TimeMS(time1, time2);
// 如果规则要求计时则time1和time2表示倒计时
if (timeLimit > 0)
{
// 玩家的剩余时间
time1 = timeLimit * 60000 - time1;
time2 = timeLimit * 60000 - time2;
}
qt1 = QTime(0, 0, 0, 0).addMSecs(time1);
qt2 = QTime(0, 0, 0, 0).addMSecs(time2);
emit time1Changed(qt1.toString("mm:ss.zzz"));
emit time2Changed(qt2.toString("mm:ss.zzz"));
// 如果胜负已分
if (chess.whoWin() != NineChess::NOBODY)
{
// 停止计时
killTimer(timeID);
// 定时器ID为0
timeID = 0;
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundWin);
}
/*
int ti = time.elapsed();
static QTime t;
if (ti < 0)
ti += 86400; // 防止过24:00引起的时间误差加上一天中总秒数
if (timeWhos == 1)
{
time1 = ti - time2;
// 用于显示时间的临时变量多出的50毫秒用于消除计时器误差产生的跳动
t = QTime(0, 0, 0, 50).addMSecs(time1);
//qDebug() << t;
emit time1Changed(t.toString("hh:mm:ss"));
}
else if (timeWhos == 2)
{
time2 = ti - time1;
// 用于显示时间的临时变量多出的50毫秒用于消除计时器误差产生的跳动
t = QTime(0, 0, 0, 50).addMSecs(time2);
//qDebug() << t;
emit time2Changed(t.toString("hh:mm:ss"));
}
*/
}
// 槽函数根据QGraphicsScene的信号和状态来执行选子、落子或去子
bool GameController::actionPiece(QPointF pos)
{
bool result = false;
switch (chess.getPhase()) {
case NineChess::GAME_NOTSTARTED:
// 如果未开局则开局这里还要继续判断不可break
gameStart();
chess.start();
case NineChess::GAME_OPENING:
// 如果是开局阶段(轮流落下新子),落子
if (chess.getAction() == NineChess::ACTION_PLACE) {
result = placePiece(pos);
}// 去子
else if (chess.getAction() == NineChess::ACTION_REMOVE) {
result = removePiece(pos);
}
// 如果完成后进入中局,则删除禁点
if (chess.getPhase() == NineChess::GAME_MID && chess.getRule()->hasForbidden)
cleanForbidden();
break;
case NineChess::GAME_MID:
// 如果是中局阶段(轮流移子)
// 选子
if (chess.getAction() == NineChess::ACTION_CHOOSE) {
result = choosePiece(pos);
}// 移子
else if (chess.getAction() == NineChess::ACTION_PLACE) {
// 如果移子不成功,尝试重新选子
if (!movePiece(pos))
result = choosePiece(pos);
}// 去子
else if (chess.getAction() == NineChess::ACTION_REMOVE) {
result = removePiece(pos);
}
break;
// 如果是结局状态,不做任何响应
default:
break;
}
if (result)
{
if (chess.whoWin() != NineChess::NOBODY)
playSound(soundWin);
}
return result;
}
// 选子
PieceItem *GameController::choosePiece(QPointF pos)
{
int c, p;
if (!scene.pos2cp(pos, c, p))
return false;
PieceItem *piece = NULL;
QGraphicsItem *item = scene.itemAt(pos, QTransform());
if (!item) {
scene.clearSelection();
this->piece->setSelected(true);
return false;
}
piece = qgraphicsitem_cast<PieceItem *>(item);
if (!piece)
return false;
if (chess.choose(c, p)) {
scene.clearSelection();
this->piece = piece;
this->piece->setSelected(true);
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundChoose);
return piece;
}
else
{
scene.clearSelection();
if (this->piece)
this->piece->setSelected(true);
}
return NULL;
}
// 落下新子
PieceItem *GameController::placePiece(QPointF pos)
{
int c, p;
if (!scene.pos2cp(pos, c, p))
return NULL;
PieceItem *newP = NULL;
PieceItem::Models md;
if (chess.whosTurn() == NineChess::PLAYER1)
{
md = isInverted ? PieceItem::whitePiece : PieceItem::blackPiece;
}
else {
md = isInverted ? PieceItem::blackPiece : PieceItem::whitePiece;
}
if (!chess.place(c, p)) {
scene.clearSelection();
if (this->piece)
this->piece->setSelected(true);
return NULL;
}
newP = new PieceItem;
newP->setModel(md);
newP->setDeleted(false);
newP->setPos(pos);
newP->setNum(chess.getPieceNum(c, p));
// 如果重复三连不可用,则显示棋子序号
if (!(chess.getRule()->canRepeated))
newP->setShowNum(true);
pieceList.append(newP);
scene.addItem(newP);
scene.clearSelection();
this->piece = newP;
this->piece->setSelected(true);
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundDrog);
return newP;
}
// 移动旧子
bool GameController::movePiece(QPointF pos)
{
if (!piece)
return false;
int c, p;
if (!scene.pos2cp(pos, c, p))
return false;
if (chess.place(c, p))
{
piece->setPos(pos);
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundMove);
return true;
}
scene.clearSelection();
this->piece->setSelected(true);
return false;
}
// 去子
bool GameController::removePiece(QPointF pos)
{
int c, p;
if (!scene.pos2cp(pos, c, p))
return false;
if (!chess.remove(c, p)) {
scene.clearSelection();
if (this->piece)
this->piece->setSelected(true);
return false;
}
PieceItem *piece = NULL;
QGraphicsItem *item = scene.itemAt(pos, QTransform());
if (!item) {
scene.clearSelection();
if (this->piece)
this->piece->setSelected(true);
return false;
}
piece = qgraphicsitem_cast<PieceItem *>(item);
if (!piece) {
scene.clearSelection();
if (this->piece)
this->piece->setSelected(true);
return false;
}
// 如果开局阶段有禁点
if (chess.getPhase() == NineChess::GAME_OPENING && chess.getRule()->hasForbidden)
{
piece->setDeleted();
}
else
{
pieceList.removeOne(piece);
delete piece;
this->piece = NULL;
}
scene.clearSelection();
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundRemove);
return true;
}
bool GameController::cleanForbidden()
{
for each (PieceItem *p in pieceList)
{
if (p->isDeleted()) {
pieceList.removeOne(p);
delete p;
}
}
return true;
}

View File

@ -0,0 +1,128 @@
/* 这个类处理场景对象QGraphicsScene
* MVC模型中唯一的控制模块
*
* QGraphicsScene实现它
*
*/
#ifndef GAMECONTROLLER_H
#define GAMECONTROLLER_H
#include <QTime>
#include <QPointF>
#include <QMap>
#include <QList>
#include "gamescene.h"
#include "ninechess.h"
class PieceItem;
class GameController : public QObject
{
Q_OBJECT
public:
GameController(GameScene &scene, QObject *parent = 0);
~GameController();
//主窗口菜单栏明细
const QMap <int, QStringList> getActions();
int getTimeLimit() { return timeLimit; }
int getStepsLimit() { return stepsLimit; }
signals:
// 玩家1(先手)用时改变的信号
void time1Changed(const QString &time);
// 玩家2(后手)用时改变的信号
void time2Changed(const QString &time);
// 通知主窗口更新状态栏的信号
void statusBarChanged(const QString & message);
public slots:
// 游戏开始
void gameStart();
// 游戏重置
void gameReset();
// 设置编辑棋局状态
void setEditing(bool arg = true);
// 设置黑白反转状态
void setInvert(bool arg = true);
// 设置规则,不改变限时限步
void setRule(int ruleNo);
// 设置规则,改变限时限步
void setRule(int ruleNo, int stepLimited, int timeLimited);
// 让电脑执先手
void setEngine1(bool arg = true);
// 让电脑执后手
void setEngine2(bool arg = true);
// 是否有落子动画
void setAnimation(bool arg = true);
// 是否有落子音效
void setSound(bool arg = true);
// 播放声音
void playSound(QString &soundPath);
// 槽函数根据QGraphicsScene的信号和状态来执行选子、落子或去子
bool actionPiece(QPointF p);
protected:
bool eventFilter(QObject * watched, QEvent * event);
void timerEvent(QTimerEvent * event);
// 选子
PieceItem *choosePiece(QPointF pos);
// 落下新子
PieceItem *placePiece(QPointF pos);
// 移动旧子
bool movePiece(QPointF pos);
// 去子
bool removePiece(QPointF pos);
// 删除禁止点子
bool cleanForbidden();
private:
// 棋对象的数据模型
NineChess chess;
// 棋局的场景类
GameScene &scene;
// 所有棋子
QList<PieceItem *> pieceList;
// 当前棋子
PieceItem *piece;
// 玩家1手棋数、玩家2手棋数、待去棋数
int player1_InHand, player2_InHand, num_NeedRemove;
// 是否处于“编辑棋局”状态
bool isEditing;
// 是否黑白反转
bool isInverted;
// 是否电脑执先手
bool isEngine1;
// 是否电脑执后手
bool isEngine2;
// 是否有落子动画
bool hasAnimation;
// 是否有落子音效
bool hasSound;
// 定时器ID
int timeID;
// 规则限时(分钟)
int timeLimit;
// 规则限步数
int stepsLimit;
// 玩家1剩余时间毫秒
int time1;
// 玩家2剩余时间毫秒
int time2;
// 用于主窗口状态栏显示的字符串
QString message;
// 文字棋谱
QStringList manual;
// 各个音效文件路径
QString soundNewgame;
QString soundChoose;
QString soundMove;
QString soundDrog;
QString soundForbidden;
QString soundRemove;
QString soundWin;
QString soundLoss;
};
#endif // GAMECONTROLLER_H

View File

@ -0,0 +1,93 @@
#include "gamescene.h"
#include "pieceitem.h"
#include "boarditem.h"
#include <QGraphicsItem>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QKeyEvent>
#include <QDebug>
GameScene::GameScene(QObject *parent) : QGraphicsScene(parent), board(NULL)
{
// 添加棋盘
board = new BoardItem;
board->setDiagonal(false);
addItem(board);
}
GameScene::~GameScene()
{
if(board)
delete board;
}
void GameScene::keyPressEvent(QKeyEvent *keyEvent)
{
// 屏蔽掉Shift和Control按键事实证明没用按键事件未必由试图类处理
if(keyEvent->key() == Qt::Key_Shift || keyEvent->key() == Qt::Key_Control)
return;
QGraphicsScene::keyPressEvent(keyEvent);
}
void GameScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
//什么也不做,屏蔽双击事件
}
void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
// 只处理左键事件
if(mouseEvent->button() != Qt::LeftButton)
return;
// 调用默认事件处理函数
QGraphicsScene::mousePressEvent(mouseEvent);
// 如果不是棋子则结束
QGraphicsItem *item = itemAt(mouseEvent->scenePos(), QTransform());
if (!item || item->type() != PieceItem::Type)
{
return;
}
// 取消其它棋子的选中状态
//for each (QGraphicsItem * item in selectedItems())
//{
// item->setSelected(false);
//}
}
void GameScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
// 只处理左键事件
if(mouseEvent->button() != Qt::LeftButton)
return;
// 调用默认事件处理函数
QGraphicsScene::mouseReleaseEvent(mouseEvent);
// 如果是棋盘
QGraphicsItem *item = itemAt(mouseEvent->scenePos(), QTransform());
if (!item || item->type() == BoardItem::Type)
{
QPointF p = mouseEvent->scenePos();
p = board->nearestPosition(p);
if (p != QPointF(0, 0))
// 发送鼠标点最近的落子点
emit mouseReleased(p);
}// 如果是棋子
else if (item->type() == PieceItem::Type)
{
// 将当前棋子在场景中的位置发送出去
emit mouseReleased(item->scenePos());
}
}
bool GameScene::pos2cp(QPointF pos, int &c, int &p)
{
return board->pos2cp(pos, c, p);
}
void GameScene::setDiagonal(bool arg)
{
if (board)
board->setDiagonal(arg);
}

36
NineChess/src/gamescene.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef GAMESCENE_H
#define GAMESCENE_H
#include <QGraphicsScene>
class BoardItem;
class GameScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit GameScene(QObject *parent = nullptr);
~GameScene();
// 将落子点坐标转化为模型用的圈、位
bool pos2cp(QPointF pos, int &c, int &p);
// 设置棋盘斜线
void setDiagonal(bool arg = true);
protected:
void keyPressEvent(QKeyEvent *keyEvent);
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent);
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
signals:
void mouseReleased(QPointF);
public slots:
private:
// 棋盘对象
BoardItem *board;
};
#endif // GAMESCENE_H

View File

@ -0,0 +1,99 @@
#include "gameview.h"
#include <QMatrix>
#include <QDebug>
GameView::GameView(QWidget * parent) :
QGraphicsView(parent)
{
Q_UNUSED(parent)
// 初始化缩放因子为1.0
sx = 1.0;
sy = 1.0;
}
GameView::~GameView()
{
}
void GameView::flip()
{
// 视图上下翻转
/* 以下用到了很多图形变换矩阵方面的知识
* scale方法Qt的图形变换是针对坐标系的
*
* sx 0 0
* S = 0 sy 0
* 0 0 1
*
* 1 0 0
* 0 -1 0
* 0 0 1
*/
// 方法一: 直接在原变换矩阵基础上乘以上面的矩阵
// QMatrix只对变换矩阵前两列赋值
setMatrix(matrix() * QMatrix(1, 0, 0, -1, 0, 0));
/* 方法二: 人工计算好新的变换矩阵后再对场景赋值
*
QMatrix mt = matrix();
mt.setMatrix(-mt.m11(), mt.m12(), -mt.m21(), mt.m22(), -mt.dx(), mt.dy());
setMatrix(mt);
*/
}
void GameView::mirror()
{
// 视图左右镜像
/* 左右镜像应在原变换矩阵基础上乘以一个如下的矩阵:
* -1 0 0
* 0 1 0
* 0 0 1
*/
setMatrix(matrix() * QMatrix(-1, 0, 0, 1, 0, 0));
}
void GameView::turnRight()
{
// 视图须时针旋转90°
/* 不要用scale方法视图镜像或翻转后它的转向会反过来
*
* cos(α) sin(α) 0
* R = -sin(α) cos(α) 0
* 0 0 1
* 90°
* 0 1 0
* -1 0 0
* 0 0 1
*/
setMatrix(matrix() * QMatrix(0, 1, -1, 0, 0, 0));
}
void GameView::turnLeft()
{
// 视图逆时针旋转90°
/* 视图逆时针旋转90°应在原变换矩阵基础上乘以一个如下的矩阵
* 0 -1 0
* 1 0 0
* 0 0 1
*/
setMatrix(matrix() * QMatrix(0, -1, 1, 0, 0, 0));
}
void GameView::resizeEvent(QResizeEvent * event)
{
// 让场景适合视图
Q_UNUSED(event)
if (sceneRect().width() <= 0 || sceneRect().height() <= 0)
return;
// 恢复缩放前的大小
scale(1/sx, 1/sy);
// 设置缩放因子
sx = width() / sceneRect().width();
sy = height() / sceneRect().height();
sx = sx < sy ? sx : sy;
sy = sx;
// 缩放视图适合场景大小
scale(sx, sy);
//qDebug() << "scale :" << sx;
}

29
NineChess/src/gameview.h Normal file
View File

@ -0,0 +1,29 @@
// 派生这个类主要是为了让视图适应场景大小及图像旋转镜像操作
#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H
#include <QGraphicsView>
class GameView : public QGraphicsView
{
Q_OBJECT
public:
explicit GameView(QWidget * parent);
~GameView();
public slots:
void flip();
void mirror();
void turnRight();
void turnLeft();
protected:
void resizeEvent(QResizeEvent * event);
private:
// 缩放因子
qreal sx, sy;
};
#endif // GRAPHICSVIEW_H

View File

@ -0,0 +1,12 @@
// 定义绘图相关常量的头文件
#ifndef GRAPHICSCONST
#define GRAPHICSCONST
const int BOARD_SIZE = 600; // 棋盘大小
const int BOARD_MINISIZE = 150; // 最小宽高即1/4大小
const int PIECE_SIZE = 56; // 棋子大小
const int LINE_INTERVAL = 72; // 线间距
const int LINE_WEIGHT = 3; // 线宽
#endif // GRAPHICSCONST

10
NineChess/src/main.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "ninechesswindow.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
NineChessWindow w;
w.show();
return a.exec();
}

967
NineChess/src/ninechess.cpp Normal file
View File

@ -0,0 +1,967 @@
/****************************************************************************
** by liuweilhy, 2013.01.14
** Mail: liuweilhy@163.com
** This file is part of the NineChess game.
****************************************************************************/
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
#include "ninechess.h"
// 对静态常量数组的定义要放在类外,不要放在头文件
// 预定义的4套规则
const struct NineChess::Rule NineChess::RULES[RULENUM] = {
{
"成三棋", // 成三棋
"双方各九颗子,开局依次摆子;\n" // 规则说明
"凡出现三子相连,就提掉对手一子;\n"
"不能提对手的“三连”子,除非无子可提;\n"
"同时出现两个“三连”只能提一子;\n"
"摆完后依次走子,每次只能往相邻位置走一步;\n"
"把对手棋子提到少于3颗时胜利\n"
"走棋阶段不能行动(被“闷”)算负。",
9, // 双方各9子
3, // 赛点子数为3
false, // 没有斜线
false, // 没有禁点,摆棋阶段被提子的点可以再摆子
false, // 先摆棋者先行棋
true, // 可以重复成三
false, // 多个“三连”只能提一子
true, // 摆棋满子闷棋只有12子棋才出现算先手负
true, // 走棋阶段不能行动(被“闷”)算负
false, // 剩三子时不可以飞棋
0, // 不计步数
0 // 不计时
},
{
"打三棋(12连棋)", // 打三棋
"规则与成三棋基本相同只是它用12颗子并且有斜线\n" // 规则说明
"摆棋阶段被提子的位置不能再摆子,直到走棋阶段;\n"
"摆棋阶段,摆满棋盘算先手负;\n"
"走棋阶段,后摆棋的一方先走;\n"
"一步出现几个“三连”就可以提几个子。",
12, // 双方各12子
3, // 赛点子数为3
true, // 有斜线
true, // 有禁点,摆棋阶段被提子的点不能再摆子
true, // 后摆棋者先行棋
true, // 可以重复成三
true, // 出现几个“三连”就可以提几个子
true, // 摆棋满子闷棋只有12子棋才出现算先手负
true, // 走棋阶段不能行动(被“闷”)算负
false, // 剩三子时不可以飞棋
0, // 不计步数
0 // 不计时
},
{
"九连棋", // 九连棋
"规则与成三棋基本相同,只是它的棋子有序号,\n" // 规则说明
"相同序号、位置的“三连”不能重复提子;\n"
"走棋阶段不能行动(被“闷”),则由对手继续走棋;\n"
"一步出现几个“三连”就可以提几个子。",
9, // 双方各9子
3, // 赛点子数为3
false, // 没有斜线
false, // 没有禁点,摆棋阶段被提子的点可以再摆子
false, // 先摆棋者先行棋
false, // 不可以重复成三
true, // 出现几个“三连”就可以提几个子
true, // 摆棋满子闷棋只有12子棋才出现算先手负
false, // 走棋阶段不能行动(被“闷”),则由对手继续走棋
false, // 剩三子时不可以飞棋
0, // 不计步数
0 // 不计时
},
{
"莫里斯九子棋", // 莫里斯九子棋
"规则与成三棋基本相同,只是在走子阶段,\n" // 规则说明
"当一方仅剩3子时他可以飞子到任意空位。",
9, // 双方各9子
3, // 赛点子数为3
false, // 没有斜线
false, // 没有禁点,摆棋阶段被提子的点可以再摆子
false, // 先摆棋者先行棋
true, // 可以重复成三
false, // 多个“三连”只能提一子
true, // 摆棋满子闷棋只有12子棋才出现算先手负
true, // 走棋阶段不能行动(被“闷”)算负
true, // 剩三子时可以飞棋
0, // 不计步数
0 // 不计时
}
};
const char NineChess::inBoard[(RING + 2)*SEAT] = {
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\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()
{
// 默认选择第0号规则即“成三棋”
setData(&RULES[0]);
}
NineChess::~NineChess()
{
}
bool NineChess::setData(const struct Rule *rule, int step, int flags, const char *boardsource,
int p1_InHand, int p2_InHand, int num_NeedRemove)
{
// 根据规则
this->rule = *rule;
// 设置步数
this->step = step;
// 设置状态
// 局面阶段标识
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 == NULL)
memset(this->board, 0, sizeof(this->board));
else
memcpy(this->board, boardsource, sizeof(this->board));
// 生成招法表
for (int i = 1; i <= RING; i++)
{
for (int j = 0; j < SEAT; j++)
{
// 顺时针走一步的位置
moveTable[i*SEAT + j][0] = i * SEAT + (j + 1) % SEAT;
// 逆时针走一步的位置
moveTable[i*SEAT + j][1] = i * SEAT + (j + SEAT - 1) % SEAT;
// 如果是0、2、4、6位偶数位或是有斜线
if (!(j & 1) || this->rule.hasObliqueLine) {
if (i > 1) {
// 向内走一步的位置
moveTable[i*SEAT + j][2] = (i - 1)*SEAT + j;
}
if (i < RING) {
// 向外走一步的位置
moveTable[i*SEAT + j][3] = (i + 1)*SEAT + j;
}
}
// 对于无斜线情况下的1、3、5、7位奇数位则都设为棋盘外点默认'\x00'
//else {
// // 向内走一步的位置设为随便棋盘外一点
// moveTable[i*SEAT+j][2] = '\x00';
// // 向外走一步的位置设为随便棋盘外一点
// moveTable[i*SEAT+j][3] = '\x00';
//}
}
}
// 生成成三表
for (int j = 0; j < SEAT; j++)
{
// 内外方向的“成三”
// 如果是0、2、4、6位偶数位或是有斜线
if (!(j & 1) || this->rule.hasObliqueLine) {
millTable[1 * SEAT + j][0][0] = 2 * SEAT + j;
millTable[1 * SEAT + j][0][1] = 3 * SEAT + j;
millTable[2 * SEAT + j][0][0] = 1 * SEAT + j;
millTable[2 * SEAT + j][0][1] = 3 * SEAT + j;
millTable[3 * SEAT + j][0][0] = 1 * SEAT + j;
millTable[3 * SEAT + j][0][1] = 2 * SEAT + j;
}
// 对于无斜线情况下的1、3、5、7位奇数位
else {
// 置空该组“成三”
millTable[1 * SEAT + j][0][0] = 0;
millTable[1 * SEAT + j][0][1] = 0;
millTable[2 * SEAT + j][0][0] = 0;
millTable[2 * SEAT + j][0][1] = 0;
millTable[3 * SEAT + j][0][0] = 0;
millTable[3 * SEAT + j][0][1] = 0;
}
// 当前圈上的“成三”
// 如果是0、2、4、6位
if (!(j & 1)) {
millTable[1 * SEAT + j][1][0] = 1 * SEAT + (j + 1) % SEAT;
millTable[1 * SEAT + j][1][1] = 1 * SEAT + (j + SEAT - 1) % SEAT;
millTable[2 * SEAT + j][1][0] = 2 * SEAT + (j + 1) % SEAT;
millTable[2 * SEAT + j][1][1] = 2 * SEAT + (j + SEAT - 1) % SEAT;
millTable[3 * SEAT + j][1][0] = 3 * SEAT + (j + 1) % SEAT;
millTable[3 * SEAT + j][1][1] = 3 * SEAT + (j + SEAT - 1) % SEAT;
// 置空另一组“成三”
millTable[1 * SEAT + j][2][0] = 0;
millTable[1 * SEAT + j][2][1] = 0;
millTable[2 * SEAT + j][2][0] = 0;
millTable[2 * SEAT + j][2][1] = 0;
millTable[3 * SEAT + j][2][0] = 0;
millTable[3 * SEAT + j][2][1] = 0;
}
// 对于1、3、5、7位奇数位
else {
// 当前圈上逆时针的“成三”
millTable[1 * SEAT + j][1][0] = 1 * SEAT + (j + SEAT - 2) % SEAT;
millTable[1 * SEAT + j][1][1] = 1 * SEAT + (j + SEAT - 1) % SEAT;
millTable[2 * SEAT + j][1][0] = 2 * SEAT + (j + SEAT - 2) % SEAT;
millTable[2 * SEAT + j][1][1] = 2 * SEAT + (j + SEAT - 1) % SEAT;
millTable[3 * SEAT + j][1][0] = 3 * SEAT + (j + SEAT - 2) % SEAT;
millTable[3 * SEAT + j][1][1] = 3 * SEAT + (j + SEAT - 1) % SEAT;
// 当前圈上顺时针的“成三”
millTable[1 * SEAT + j][2][0] = 1 * SEAT + (j + 1) % SEAT;
millTable[1 * SEAT + j][2][1] = 1 * SEAT + (j + 2) % SEAT;
millTable[2 * SEAT + j][2][0] = 2 * SEAT + (j + 1) % SEAT;
millTable[2 * SEAT + j][2][1] = 2 * SEAT + (j + 2) % SEAT;
millTable[3 * SEAT + j][2][0] = 3 * SEAT + (j + 1) % SEAT;
millTable[3 * SEAT + j][2][1] = 3 * SEAT + (j + 2) % SEAT;
}
}
// 计算盘面子数
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();
// 不选中棋子
posOfSelected = 0;
// 用时置零
player1_MS = player2_MS = 0;
setTip();
return true;
}
bool NineChess::setRule(const struct Rule *rule)
{
setData(rule);
return true;
}
void NineChess::getData(struct Rule &rule, int &step, int &chess, 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;
}
bool NineChess::reset()
{
return setData(&rule);
}
bool NineChess::start()
{
if (phase == GAME_OVER)
reset();
update();
if (phase == GAME_NOTSTARTED)
phase = GAME_OPENING;
ftime(&startTimeb);
// 用时置零
player1_MS = player2_MS = 0;
return true;
}
int NineChess::cp2pos(int c, int p)
{
if (c < 1 || c > RING || p < 1 || p > SEAT)
return 0;
return c * SEAT + p - 1;
}
bool NineChess::place(int c, int p)
{
// 如果局面为"未开局"或“结局”返回false
if (phase == GAME_NOTSTARTED || phase == GAME_OVER)
return false;
// 如非“落子”状态返回false
if (action != ACTION_PLACE)
return false;
// 如果落子位置在棋盘外、已有子点或禁点返回false
int pos = cp2pos(c, p);
if (!inBoard[pos] || board[pos])
return false;
// 对于开局落子
char piece = '\x00';
int n = 0;
if (phase == GAME_OPENING) {
// 先手下
if (turn == PLAYER1)
{
piece = '\x11' + rule.numOfChess - player1_InHand;
board[pos] = piece;
player1_InHand--;
player1_Remain++;
}
// 后手下
else
{
piece = '\x21' + rule.numOfChess - player2_InHand;
board[pos] = piece;
player2_InHand--;
player2_Remain++;
}
posOfSelected = pos;
step++;
// 如果决出胜负
if (win()) {
setTip();
return true;
}
n = addMills(posOfSelected);
// 开局阶段未成三
if (n == 0) {
// 如果双方都无未放置的棋子
if (player1_InHand == 0 && player2_InHand == 0) {
// 进入中局阶段
phase = GAME_MID;
// 进入选子状态
action = ACTION_CHOOSE;
// 清除禁点
cleanForbidden();
// 设置轮到谁走
if (rule.isDefensiveMoveFirst) {
turn = PLAYER2;
}
else {
turn = PLAYER1;
}
// 再决胜负
if (win()) {
setTip();
return true;
}
}
// 如果双方还有子
else {
// 设置轮到谁走
changeTurn();
}
}
// 如果成三
else {
// 设置去子数目
num_NeedRemove = rule.removeMore ? n : 1;
// 进入去子状态
action = ACTION_REMOVE;
setTip();
}
setTip();
return true;
}
// 对于中局落子
else if (phase == GAME_MID) {
// 如果落子不合法
if ((turn == PLAYER1 && (player1_Remain > rule.numAtLest || !rule.canFly)) ||
(turn == PLAYER2 && (player2_Remain > rule.numAtLest || !rule.canFly))) {
int i;
for (i = 0; i < 4; i++) {
if (pos == moveTable[posOfSelected][i])
break;
}
// 不在招法表中
if (i == 4)
return false;
}
// 移子
board[pos] = board[posOfSelected];
board[posOfSelected] = '\x00';
posOfSelected = pos;
step++;
n = addMills(posOfSelected);
// 中局阶段未成三
if (n == 0) {
// 进入选子状态
action = ACTION_CHOOSE;
// 设置轮到谁走
changeTurn();
// 如果决出胜负
if (win()) {
setTip();
return true;
}
}
// 中局阶段成三
else {
// 设置去子数目
num_NeedRemove = rule.removeMore ? n : 1;
// 进入去子状态
action = ACTION_REMOVE;
setTip();
}
setTip();
return true;
}
return false;
}
bool NineChess::remove(int c, int p)
{
// 如果局面为"未开局"或“结局”返回false
if (phase == GAME_NOTSTARTED || phase == GAME_OVER)
return false;
// 如非“去子”状态返回false
if (action != ACTION_REMOVE)
return false;
// 如果去子完成返回false
if (num_NeedRemove <= 0)
return false;
int pos = cp2pos(c, p);
// 对手
enum Player opponent = PLAYER2;
if (turn == PLAYER2)
opponent = PLAYER1;
// 判断去子不是对手棋
if (getWhosPiece(c, p) != opponent)
return false;
// 如果当前子是否处于“三连”之中,且对方还未全部处于“三连”之中
if (isInMills(pos) && !isAllInMills(opponent)) {
return false;
}
// 去子(设置禁点)
if (rule.hasForbidden && phase == GAME_OPENING)
board[pos] = '\x0f';
else // 去子
board[pos] = '\x00';
if (turn == PLAYER1)
player2_Remain--;
else if (turn == PLAYER2)
player1_Remain--;
posOfSelected = 0;
num_NeedRemove--;
step++;
// 去子完成
// 如果决出胜负
if (win()) {
setTip();
return true;
}
// 还有其余的子要去吗
if (num_NeedRemove > 0) {
// 继续去子
return true;
}
// 所有去子都完成了
else {
// 开局阶段
if (phase == GAME_OPENING) {
// 如果双方都无未放置的棋子
if (player1_InHand == 0 && player2_InHand == 0) {
// 进入中局阶段
phase = GAME_MID;
// 进入选子状态
action = ACTION_CHOOSE;
// 清除禁点
cleanForbidden();
// 设置轮到谁走
if (rule.isDefensiveMoveFirst) {
turn = PLAYER2;
}
else {
turn = PLAYER1;
}
// 再决胜负
if (win()) {
setTip();
return true;
}
}
// 如果双方还有子
else {
// 进入落子状态
action = ACTION_PLACE;
// 设置轮到谁走
changeTurn();
// 如果决出胜负
if (win()) {
setTip();
return true;
}
}
}
// 中局阶段
else {
// 进入选子状态
action = ACTION_CHOOSE;
// 设置轮到谁走
changeTurn();
// 如果决出胜负
if (win()) {
setTip();
return true;
}
}
}
setTip();
return true;
}
bool NineChess::choose(int c, int p)
{
// 如果局面不是"中局”返回false
if (phase != GAME_MID)
return false;
// 如非“选子”或“落子”状态返回false
if (action != ACTION_CHOOSE && action != ACTION_PLACE)
return false;
int pos = cp2pos(c, p);
// 根据先后手,判断可选子
char t;
if (turn == PLAYER1)
t = '\x10';
else if (turn == PLAYER2)
t = '\x20';
// 判断选子是否可选
if (board[pos] & t) {
// 判断pos处的棋子是否被“闷”
if (isSurrounded(pos)) {
return false;
}
// 选子
posOfSelected = pos;
// 选子完成,进入落子状态
action = ACTION_PLACE;
return true;
}
return false;
}
inline bool NineChess::update()
{
// 根据局面调整计时器
switch (phase)
{
case NineChess::GAME_OPENING:
case NineChess::GAME_MID:
ftime(&currentTimeb);
// 在时间更新时增添一套胜负判断的代码以免频繁调用win()带来的效率问题
if (turn == PLAYER1) {
player1_MS = (long)(currentTimeb.time - startTimeb.time) * 1000
+ (currentTimeb.millitm - startTimeb.millitm) - player2_MS;
// 如果玩家1超时
if (rule.maxTime > 0 && player1_MS > rule.maxTime * 60000) {
player1_MS = rule.maxTime * 60000;
winner = PLAYER2;
phase = GAME_OVER;
tip = "玩家1超时恭喜玩家2获胜";
}
}
else if (turn == PLAYER2) {
player2_MS = (long)(currentTimeb.time - startTimeb.time) * 1000
+ (currentTimeb.millitm - startTimeb.millitm) - player1_MS;
// 如果玩家2超时
if (rule.maxTime > 0 && player2_MS > rule.maxTime * 60000) {
player2_MS = rule.maxTime * 60000;
winner = PLAYER1;
phase = GAME_OVER;
tip = "玩家2超时恭喜玩家1获胜";
}
}
return true;
case NineChess::GAME_NOTSTARTED:
return true;
case NineChess::GAME_OVER:
return true;
default:
return true;
}
}
// 是否分出胜负
bool NineChess::win()
{
if (phase == GAME_OVER)
return true;
if (phase == GAME_NOTSTARTED)
return false;
// 如果有时间限定
if (rule.maxTime > 0) {
// 更新时间,判断胜负
update();
if (winner != NOBODY)
return true;
}
// 如果有步数限定
if (rule.maxSteps > 0) {
if (step > rule.maxSteps) {
winner = DRAW;
phase = GAME_OVER;
return true;
}
}
// 如果玩家1子数小于赛点则玩家2获胜
if (player1_Remain + player1_InHand < rule.numAtLest) {
winner = PLAYER2;
phase = GAME_OVER;
return true;
}
// 如果玩家2子数小于赛点则玩家1获胜
else if (player2_Remain + player2_InHand < rule.numAtLest) {
winner = PLAYER1;
phase = GAME_OVER;
return true;
}
// 如果摆满了,根据规则判断胜负
else if (player1_Remain + player2_Remain >= SEAT * RING) {
if (rule.isFullLose) {
winner = PLAYER2;
phase = GAME_OVER;
return true;
}
else
{
winner = DRAW;
phase = GAME_OVER;
return true;
}
}
// 如果中局被“闷”
else if (phase == GAME_MID && action == ACTION_CHOOSE && isAllSurrounded(turn)) {
tip = (turn == PLAYER1) ? "玩家1无子可走" : "玩家2无子可走";
// 规则要求被“闷”判负,则对手获胜
if (rule.isNoWayLose) {
winner = (turn == PLAYER1) ? PLAYER2 : PLAYER1;
phase = GAME_OVER;
return true;
}
// 否则让棋,由对手走
else
{
changeTurn();
return false;
}
}
return false;
}
bool NineChess::command(const char *cmd)
{
return true;
}
void NineChess::setCmdline()
{
}
int NineChess::isInMills(int pos)
{
int n = 0;
int pos1, pos2;
char m = board[pos] & '\x30';
for (int i = 0; i < 3; i++)
{
pos1 = millTable[pos][i][0];
pos2 = millTable[pos][i][1];
if (m & board[pos1] & board[pos2])
n++;
}
return n;
}
int NineChess::addMills(int pos)
{
//成三用一个64位整数了规则如下
//0x 00 00 00 00 00 00 00 00
// unused unused piece1 pos1 piece2 pos2 piece3 pos3
//piece1、piece2、piece3按照序号从小到大顺序排放
long long mill = 0;
int n = 0;
int p[3], min, temp;
char m = board[pos] & '\x30';
for (int i = 0; i < 3; i++)
{
p[0] = pos;
p[1] = millTable[pos][i][0];
p[2] = millTable[pos][i][1];
// 如果成三
if (m & board[p[1]] & board[p[2]]) {
// 排序
for (int j = 0; j < 2; j++) {
min = j;
for (int k = j + 1; k < 3; k++) {
if (p[min] > p[k])
min = k;
}
if (min != j) {
temp = p[min];
p[min] = p[j];
p[j] = temp;
}
}
// 成三
mill = (((long long)board[p[0]]) << 40)
+ (((long long)p[0]) << 32)
+ (((long long)board[p[1]]) << 24)
+ (((long long)p[1]) << 16)
+ (((long long)board[p[2]]) << 8)
+ (long long)p[2];
// 如果允许相同三连反复去子
if (rule.canRepeated) {
n++;
}
// 如果不允许相同三连反复去子
else
{
// 迭代器
list<long long>::iterator itor;
// 遍历
for ( itor = millList.begin(); itor != millList.end(); itor++)
{
if (mill == *itor)
break;
}
// 如果没找到历史项
if (itor == millList.end()) {
n++;
millList.push_back(mill);
}
}
}
}
return n;
}
bool NineChess::isAllInMills(enum Player player)
{
char ch = '\x00';
if (player == PLAYER1)
ch = '\x10';
else if (player == PLAYER2)
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) {
if (!isInMills(i*SEAT + j)) {
return false;
}
}
}
return true;
}
// 判断玩家的棋子是否被围
bool NineChess::isSurrounded(int pos)
{
// 判断pos处的棋子是否被“闷”
if ((turn == PLAYER1 && (player1_Remain > rule.numAtLest || !rule.canFly)) ||
(turn == PLAYER2 && (player2_Remain > rule.numAtLest || !rule.canFly))) {
int i, movePos;
for (i = 0; i < 4; i++) {
movePos = moveTable[pos][i];
if (movePos && !board[movePos])
break;
}
// 被围住
if (i == 4)
return true;
}
// 没被围住
return false;
}
// 判断玩家的棋子是否全部被围
bool NineChess::isAllSurrounded(enum Player ply)
{
char t = '\x30';
if (ply == PLAYER1)
t &= '\x10';
else if (ply == PLAYER2)
t &= '\x20';
// 如果摆满
if (player1_Remain + player2_Remain >= SEAT * RING)
return true;
for (int i = 1; i <= RING; i++)
{
for (int j = 0; j < SEAT; j++)
{
int movePos;
if (t & board[i*SEAT + j]) {
for (int k = 0; k < 4; k++) {
movePos = moveTable[i*SEAT + j][k];
if (movePos && !board[movePos])
return false;
}
}
}
}
return true;
}
void NineChess::cleanForbidden()
{
for (int i = 1; i <= RING; i++)
for (int j = 0; j < SEAT; j++) {
if (board[i*SEAT + j] == '\x0f')
board[i*SEAT + j] = '\x00';
}
}
enum NineChess::Player NineChess::changeTurn()
{
// 设置轮到谁走
return turn = (turn == PLAYER1) ? PLAYER2 : PLAYER1;
}
void NineChess::setTip()
{
switch (phase)
{
case NineChess::GAME_NOTSTARTED:
tip = "轮到玩家1落子剩余" + std::to_string(player1_InHand) + "";
break;
case NineChess::GAME_OPENING:
if (action == ACTION_PLACE) {
if (turn == PLAYER1) {
tip = "轮到玩家1落子剩余" + std::to_string(player1_InHand) + "";
}
else if (turn == PLAYER2) {
tip = "轮到玩家2落子剩余" + std::to_string(player2_InHand) + "";
}
}
else if (action == ACTION_REMOVE) {
if (turn == PLAYER1) {
tip = "轮到玩家1去子需去" + std::to_string(num_NeedRemove) + "";
}
else if (turn == PLAYER2) {
tip = "轮到玩家2去子需去" + std::to_string(num_NeedRemove) + "";
}
}
break;
case NineChess::GAME_MID:
if (action == ACTION_PLACE || action == ACTION_CHOOSE) {
if (turn == PLAYER1) {
tip = "轮到玩家1选子移动";
}
else if (turn == PLAYER2) {
tip = "轮到玩家2选子移动";
}
}
else if (action == ACTION_REMOVE) {
if (turn == PLAYER1) {
tip = "轮到玩家1去子需去" + std::to_string(num_NeedRemove) + "";
}
else if (turn == PLAYER2) {
tip = "轮到玩家2去子需去" + std::to_string(num_NeedRemove) + "";
}
}
break;
case NineChess::GAME_OVER:
if (winner == DRAW)
tip = "超出限定步数,双方平局";
else if (winner == PLAYER1) {
if (tip.find("无子可走") != tip.npos)
tip += "恭喜玩家1获胜";
else
tip = "恭喜玩家1获胜";
}
else if (winner == PLAYER2) {
if (tip.find("无子可走") != tip.npos)
tip += "恭喜玩家2获胜";
else
tip = "恭喜玩家2获胜";
}
break;
default:
break;
}
}
enum NineChess::Player NineChess::getWhosPiece(int c, int p)
{
int pos = cp2pos(c, p);
if (board[pos] & '\x10')
return PLAYER1;
else if (board[pos] & '\x20')
return PLAYER2;
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();
p1_ms = player1_MS;
p2_ms = player2_MS;
}

251
NineChess/src/ninechess.h Normal file
View File

@ -0,0 +1,251 @@
/****************************************************************************
** by liuweilhy, 2013.01.14
** Mail: liuweilhy@163.com
** This file is part of the NineChess game.
****************************************************************************/
#ifndef NINECHESS
#define NINECHESS
#include <sys/timeb.h>
#include <string>
#include <list>
using std::string;
using std::list;
// 棋类(在数据模型内,玩家只分先后手,不分黑白)
class NineChess
{
public:
// 公有的结构体和枚举,只是类型定义,不是变量!
// 规则结构体
struct Rule
{
// 规则名称
const char *name;
// 规则介绍
const char *info;
// 任一方子数各9子或各12子
int numOfChess;
// 赛点子数,少于则判负
int numAtLest;
// 是否有斜线
bool hasObliqueLine;
// 是否有禁点(摆棋阶段被提子的点不能再摆子)
bool hasForbidden;
// 是否后摆棋者先行棋
bool isDefensiveMoveFirst;
// 相同顺序和位置的重复“三连”是否可反复提子
bool canRepeated;
// 多个“三连”能否多提子
bool removeMore;
// 摆棋满子闷棋只有12子棋才出现是否算先手负false为和棋
bool isFullLose;
// 走棋阶段不能行动被“闷”是否算负false则轮空由对手走棋
bool isNoWayLose;
// 剩三子时是否可以飞棋
bool canFly;
// 最大步数,超出判和
int maxSteps;
// 包干最长时间超出判负为0则不计时
int maxTime;
};
// 局面阶段标识
enum Phases {
GAME_NOTSTARTED = 0x00000001, // 未开局
GAME_OPENING = 0x00000002, // 开局(摆棋)
GAME_MID = 0x00000004, // 中局(走棋)
GAME_OVER = 0x00000008 // 结局
};
// 玩家标识,轮流状态,胜负标识
enum Player {
PLAYER1 = 0x00000010, // 玩家1
PLAYER2 = 0x00000020, // 玩家2
DRAW = 0x00000040, // 双方和棋
NOBODY = 0x00000080 // 胜负未分
};
// 动作状态标识
enum Actions {
ACTION_CHOOSE = 0x00000100, // 选子
ACTION_PLACE = 0x00000200, // 落子
ACTION_REMOVE = 0x00000400 // 提子
};
// 5个静态成员常量
// 3圈禁止修改
static const int RING = 3;
// 8位禁止修改
static const int SEAT = 8;
// 预定义的规则数目
static const int RULENUM = 4;
// 预定义的规则
static const struct Rule RULES[RULENUM];
public:
NineChess();
~NineChess();
// 设置棋局状态和棋盘数据,用于初始化
bool setData(const struct Rule *rule,
int step = 0, // 默认起始步数为0
int flags = GAME_NOTSTARTED | PLAYER1 | ACTION_PLACE | NOBODY, // 默认状态
const char *boardsource = NULL, // 默认空棋盘
int p1_InHand = 12, // 玩家1剩余未放置子数
int p2_InHand = 12, // 玩家2剩余未放置子数
int num_NeedRemove = 0 // 尚待去除的子数
);
// 设置规则
bool setRule(const struct Rule *rule);
// 获取棋局状态和棋盘数据
void getData(struct Rule &rule, int &step, int &flags, const char *&boardsource, int &p1_InHand, int &p2_InHand, int &num_NeedRemove);
// 获取当前规则
const struct Rule *getRule() { return &rule; }
// 获取当前步数
int getStep() { return step; }
// 获取局面阶段标识
enum Phases getPhase() { return phase; }
// 获取轮流状态标识
enum Player whosTurn() { return turn; }
// 获取动作状态标识
enum Actions getAction() { return action; }
// 判断胜负
enum Player whoWin() { return winner; }
// 获取当前招法
const char *getCmdline() { return cmdline; }
// 获取棋局的字符提示
const string getTip() { return tip; }
// 获取位置点棋子的归属人
enum Player getWhosPiece(int c, int p);
// 获取位置点棋子的序号
int getPieceNum(int c, int p);
// 玩家1剩余未放置子数
int getPlayer1_InHand() { return player1_InHand; }
// 玩家2剩余未放置子数
int getPlayer2_InHand() { return player2_InHand; }
// 玩家1盘面剩余子数
int getPlayer1_Remain() { return player1_Remain; }
// 玩家1盘面剩余子数
int getPlayer2_Remain() { return player2_Remain; }
// 尚待去除的子数
int getNum_NeedRemove() { return num_NeedRemove; }
// 玩家1和玩家2的用时
void getPlayer_TimeMS(int &p1_ms, int &p2_ms);
// 游戏清空
bool reset();
// 游戏开始
bool start();
// 选子在第c圈第p个位置为迎合日常c和p下标都从1开始
bool choose(int c, int p);
// 落子在第c圈第p个位置为迎合日常c和p下标都从1开始
bool place(int c, int p);
// 去子在第c圈第p个位置为迎合日常c和p下标都从1开始
bool remove(int c, int p);
// 命令行解析函数
bool command(const char *cmd);
protected:
// 设置当前招法的命令行指令,即一招棋谱
void setCmdline();
// 判断棋盘pos处的棋子处于几个“三连”中
int isInMills(int pos);
// 判断玩家的所有棋子是否都处于“三连”状态
bool isAllInMills(enum Player);
// 判断玩家的棋子是否被围
bool isSurrounded(int pos);
// 判断玩家的棋子是否全部被围
bool isAllSurrounded(enum Player);
// 三连加入列表
int addMills(int pos);
// 将第c圈第p位转化为棋盘下标形式c和p下标都从1开始
int cp2pos(int c, int p);
// 更新时间和状态,用内联函数以提高效率
inline bool update();
// 是否分出胜负
bool win();
// 清除所有禁点
void cleanForbidden();
// 改变轮流
enum NineChess::Player changeTurn();
// 设置提示
void setTip();
private:
// 当前使用的规则
struct Rule rule;
// 当前步数
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;
// 游戏起始时间
timeb startTimeb;
// 当前游戏时间
timeb currentTimeb;
// 玩家1用时毫秒
long player1_MS;
// 玩家2用时毫秒
long player2_MS;
/* 棋局抽象为一个5×8的char数组上下两行留空
* 0x00
* 0x0F
* 0x10(N-1)+0x101N子
* 0x20(N-1)+0x201N子
* (board[i] & 0x10)
* (board[i] & 0x20)
*/
char board[(RING+2)*SEAT];
// 选中的棋子在board中的位置
int posOfSelected;
// 空棋盘点位,用于判断一个棋子位置是否在棋盘上
static const char inBoard[(RING+2)*SEAT];
// 招法表每个位置有最多4种走法顺时针、逆时针、向内、向外
static char moveTable[(RING+2)*SEAT][4];
// 成三表,表示棋盘上各个位置有成三关系的对应位置表
static char millTable[(RING+2)*SEAT][3][2];
/* 本打算用如下的结构体来表示“三连”
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;
// 当前招法的命令行指令,即一招棋谱
char cmdline[32];
// 当前棋局的字符提示
string tip;
// 招法不用结构体表示了用int表示=原位置*256+新位置落子没有原位置的计为0xff
short move;
};
#endif

View File

@ -0,0 +1,384 @@
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
#include "ninechesswindow.h"
#include "gamecontroller.h"
#include "gamescene.h"
#include <QMap>
#include <QMessageBox>
#include <QTimer>
#include <QDialog>
#include <QButtonGroup>
#include <QPushButton>
#include <QComboBox>
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QLabel>
#include <QHelpEvent>
#include <QToolTip>
#include <QDebug>
NineChessWindow::NineChessWindow(QWidget *parent)
: QMainWindow(parent),
scene(NULL),
game(NULL),
ruleNo(0)
{
ui.setupUi(this);
//去掉标题栏
//setWindowFlags(Qt::FramelessWindowHint);
//设置透明(窗体标题栏不透明,背景透明,如果不去掉标题栏,背景就变为黑色)
//setAttribute(Qt::WA_TranslucentBackground);
//设置全体透明度系数
//setWindowOpacity(0.7);
// 设置场景
scene = new GameScene(this);
// 关联视图和场景
ui.gameView->setScene(scene);
// 视图反走样
ui.gameView->setRenderHint(QPainter::Antialiasing, true);
// 初始化各个控件
// 视图反锯齿
ui.gameView->setRenderHint(QPainter::Antialiasing);
// 关联既有动作信号和主窗口槽
// 视图上下翻转
connect(ui.actionFlip_F, &QAction::triggered,
ui.gameView, &GameView::flip);
// 视图左右镜像
connect(ui.actionMirror_M, &QAction::triggered,
ui.gameView, &GameView::mirror);
// 视图须时针旋转90°
connect(ui.actionTurnRight_R, &QAction::triggered,
ui.gameView, &GameView::turnRight);
// 视图逆时针旋转90°
connect(ui.actionTurnLeftt_L, &QAction::triggered,
ui.gameView, &GameView::turnLeft);
// 因功能限制,使部分功能不可用
ui.actionNew_N->setDisabled(true);
ui.actionOpen_O->setDisabled(true);
ui.actionSave_S->setDisabled(true);
ui.actionSaveAs_A->setDisabled(true);
ui.actionViewText_V->setDisabled(true);
ui.actionPrevious_B->setDisabled(true);
ui.actionNext_F->setDisabled(true);
ui.actionEnd_E->setDisabled(true);
ui.actionAutoRun_A->setDisabled(true);
ui.actionEngine_E->setDisabled(true);
ui.actionInternet_I->setDisabled(true);
ui.actionEngine1_T->setDisabled(true);
ui.actionEngine2_R->setDisabled(true);
ui.actionSetting_O->setDisabled(true);
ui.actionAnimation_A->setDisabled(true);
// 初始化游戏规则菜单
ui.menu_R->installEventFilter(this);
// 安装一次性定时器,执行初始化
QTimer::singleShot(0, this, SLOT(initialize()));
}
NineChessWindow::~NineChessWindow()
{
if (game != NULL)
delete game;
}
bool NineChessWindow::eventFilter(QObject *watched, QEvent *event)
{
// 重载这个函数只是为了让规则菜单显示提示
if (watched == ui.menu_R)
{
switch (event->type())
{
case QEvent::ToolTip:
QHelpEvent * he = dynamic_cast <QHelpEvent *> (event);
QAction *action = ui.menu_R->actionAt(he->pos());
if (action)
{
QToolTip::showText(he->globalPos(), action->toolTip(), this);
return true;
}
break;
}
}
QMainWindow::eventFilter(watched, event);
}
void NineChessWindow::initialize()
{
// 如果游戏已经初始化,则退出
if (game != NULL)
return;
// 开辟一个新的游戏控制器
game = new GameController(*scene, this);
// 添加新菜单栏动作
QMap <int, QStringList> actions = game->getActions();
QMap <int, QStringList>::const_iterator i;
for (i = actions.constBegin(); i != actions.constEnd(); i++) {
// qDebug() << i.key() << i.value();
// QMap的key存放int索引值value存放规则名称和规则提示
QAction *ruleAction = new QAction(i.value().at(0), this);
ruleAction->setToolTip(i.value().at(1));
ruleAction->setCheckable(true);
// 索引值放在QAction的Data里
ruleAction->setData(i.key());
// 添加到动作列表
ruleActionList.append(ruleAction);
// 添加到“规则”菜单
ui.menu_R->addAction(ruleAction);
connect(ruleAction, SIGNAL(triggered()),
this, SLOT(actionRules_triggered()));
}
// 关联主窗口动作信号和控制器的槽
connect(ui.actionEngine1_T, SIGNAL(toggled(bool)),
game, SLOT(setEngine1(bool)));
connect(ui.actionEngine2_R, SIGNAL(toggled(bool)),
game, SLOT(setEngine2(bool)));
connect(ui.actionSound_S, SIGNAL(toggled(bool)),
game, SLOT(setSound(bool)));
connect(ui.actionAnimation_A, SIGNAL(toggled(bool)),
game, SLOT(setAnimation(bool)));
// 关联控制器的信号和主窗口控件的槽
// 注意采用信号和槽而非采用在GameController中直接控制NineChessWindow
// 是MVC模型中控制器与视图相分离的方式有利于程序梳理
// 更新LCD1显示玩家1用时
connect(game, SIGNAL(time1Changed(QString)),
ui.lcdNumber_1, SLOT(display(QString)));
// 更新LCD2显示玩家2用时
connect(game, SIGNAL(time2Changed(QString)),
ui.lcdNumber_2, SLOT(display(QString)));
// 关联场景的信号和控制器的槽
connect(scene, SIGNAL(mouseReleased(QPointF)),
game, SLOT(actionPiece(QPointF)));
// 为状态栏添加一个正常显示的标签
QLabel *statusBarlabel = new QLabel(this);
ui.statusBar->addWidget(statusBarlabel);
// 更新状态栏
connect(game, SIGNAL(statusBarChanged(QString)),
statusBarlabel, SLOT(setText(QString)));
// 默认第2号规则
ruleNo = 2;
// 设置选中当前规则的菜单项
ruleActionList.at(ruleNo)->setChecked(true);
// 重置游戏规则
game->setRule(ruleNo);
}
void NineChessWindow::actionRules_triggered()
{
// setChecked函数会发出toggled信号在这里响应toggled信号会陷入死循环
// 取消其它规则的选择
foreach(QAction *action, ruleActionList)
action->setChecked(false);
// 选择当前规则
QAction *action = dynamic_cast<QAction *>(sender());
action->setChecked(true);
ruleNo = action->data().toInt();
// 重置游戏规则
game->setRule(ruleNo);
}
void NineChessWindow::on_actionNew_N_triggered()
{
}
void NineChessWindow::on_actionOpen_O_triggered()
{
}
void NineChessWindow::on_actionSave_S_triggered()
{
}
void NineChessWindow::on_actionSaveAs_A_triggered()
{
}
void NineChessWindow::on_actionViewText_V_triggered()
{
}
void NineChessWindow::on_actionEdit_E_toggled(bool arg1)
{
}
void NineChessWindow::on_actionInvert_I_toggled(bool arg1)
{
// 如果黑白反转
if (arg1)
{
// 设置玩家1和玩家2的标识图
ui.actionEngine1_T->setIcon(QIcon(":/icon/Resources/icon/White.png"));
ui.actionEngine2_R->setIcon(QIcon(":/icon/Resources/icon/Black.png"));
ui.picLabel1->setPixmap(QPixmap(":/icon/Resources/icon/White.png"));
ui.picLabel2->setPixmap(QPixmap(":/icon/Resources/icon/Black.png"));
}
else
{
// 设置玩家1和玩家2的标识图
ui.actionEngine1_T->setIcon(QIcon(":/icon/Resources/icon/Black.png"));
ui.actionEngine2_R->setIcon(QIcon(":/icon/Resources/icon/White.png"));
ui.picLabel1->setPixmap(QPixmap(":/icon/Resources/icon/Black.png"));
ui.picLabel2->setPixmap(QPixmap(":/icon/Resources/icon/White.png"));
}
// 让控制器改变棋子颜色
game->setInvert(arg1);
}
void NineChessWindow::on_actionBegin_S_triggered()
{
if (game == NULL)
return;
game->gameReset();
}
void NineChessWindow::on_actionPrevious_B_triggered()
{
}
void NineChessWindow::on_actionNext_F_triggered()
{
}
void NineChessWindow::on_actionEnd_E_triggered()
{
}
void NineChessWindow::on_actionAutoRun_A_toggled(bool arg1)
{
}
void NineChessWindow::on_actionResign_R_triggered()
{
}
void NineChessWindow::on_actionLimited_T_triggered()
{
/* 其实本来可以用设计器做个ui然后从QDialog派生个自己的对话框
*
*
* QDialog界面
*/
int stepLimited = game->getStepsLimit();
int timeLimited = game->getTimeLimit();
// 定义新对话框
QDialog *dialog = new QDialog(this);
dialog->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
dialog->setObjectName(QStringLiteral("Dialog"));
dialog->setWindowTitle(tr("步数和时间限制"));
dialog->resize(256, 108);
dialog->setModal(true);
// 生成各个控件
QFormLayout *formLayout = new QFormLayout(dialog);
QLabel *label_step = new QLabel(dialog);
QLabel *label_time = new QLabel(dialog);
QComboBox *comboBox_step = new QComboBox(dialog);
QComboBox *comboBox_time = new QComboBox(dialog);
QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog);
// 设置各个控件ObjectName不设也没关系
/*formLayout->setObjectName(QStringLiteral("formLayout"));
label_step->setObjectName(QStringLiteral("label_step"));
label_time->setObjectName(QStringLiteral("label_time"));
comboBox_step->setObjectName(QStringLiteral("comboBox_step"));
comboBox_time->setObjectName(QStringLiteral("comboBox_time"));
buttonBox->setObjectName(QStringLiteral("buttonBox"));*/
// 设置各个控件数据
label_step->setText(tr("超出限制步数判和:"));
label_time->setText(tr("任意一方超时判负:"));
comboBox_step->addItem(tr("无限制"), 0);
comboBox_step->addItem(tr("50步"), 50);
comboBox_step->addItem(tr("100步"), 100);
comboBox_step->addItem(tr("200步"), 200);
comboBox_time->addItem(tr("无限制"), 0);
comboBox_time->addItem(tr("5分钟"), 5);
comboBox_time->addItem(tr("10分钟"), 10);
comboBox_time->addItem(tr("20分钟"), 20);
comboBox_step->setCurrentIndex(comboBox_step->findData(stepLimited));
comboBox_time->setCurrentIndex(comboBox_time->findData(timeLimited));
buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
buttonBox->setCenterButtons(true);
buttonBox->button(QDialogButtonBox::Ok)->setText(tr("确定"));
buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("取消"));
// 布局
formLayout->setSpacing(6);
formLayout->setContentsMargins(11, 11, 11, 11);
formLayout->setWidget(0, QFormLayout::LabelRole, label_step);
formLayout->setWidget(0, QFormLayout::FieldRole, comboBox_step);
formLayout->setWidget(1, QFormLayout::LabelRole, label_time);
formLayout->setWidget(1, QFormLayout::FieldRole, comboBox_time);
formLayout->setWidget(2, QFormLayout::SpanningRole, buttonBox);
// 关联信号和槽函数
connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
// 收集数据
if (dialog->exec() == QDialog::Accepted) {
stepLimited = comboBox_step->currentData().toInt();
timeLimited = comboBox_time->currentData().toInt();
// 重置游戏规则
game->setRule(ruleNo, stepLimited, timeLimited);
}
// 删除对话框,子控件会一并删除
delete dialog;
}
void NineChessWindow::on_actionLocal_L_triggered()
{
ui.actionLocal_L->setChecked(true);
ui.actionInternet_I->setChecked(false);
}
void NineChessWindow::on_actionInternet_I_triggered()
{
ui.actionLocal_L->setChecked(false);
ui.actionInternet_I->setChecked(true);
}
void NineChessWindow::on_actionEngine_E_triggered()
{
}
void NineChessWindow::on_actionViewHelp_V_triggered()
{
}
void NineChessWindow::on_actionWeb_W_triggered()
{
}
void NineChessWindow::on_actionAbout_A_triggered()
{
QMessageBox aboutBox;
aboutBox.setText(tr("九连棋"));
aboutBox.setInformativeText(tr("by liuweilhy"));
aboutBox.setIcon(QMessageBox::Information);
aboutBox.exec();
}

View File

@ -0,0 +1,74 @@
#ifndef NINECHESSWINDOW_H
#define NINECHESSWINDOW_H
#include <QtWidgets/QMainWindow>
#include "ui_ninechesswindow.h"
class GameScene;
class GameController;
class NineChessWindow : public QMainWindow
{
Q_OBJECT
public:
NineChessWindow(QWidget *parent = 0);
~NineChessWindow();
protected:
bool eventFilter(QObject * watched, QEvent * event);
private:
// 界面文件
Ui::NineChessWindowClass ui;
// 视图场景
GameScene *scene;
// 控制器
GameController *game;
// 动态增加的菜单栏动作列表
QList <QAction *> ruleActionList;
// 游戏的规则号,涉及菜单项和对话框,所以要有
int ruleNo;
private slots:
// 初始化
void initialize();
// 动态增加的菜单栏动作的槽函数
void actionRules_triggered();
// 下面是各动作的槽函数
// 注释掉的是已在UI管理器或主窗口初始化函数中连接好的
void on_actionNew_N_triggered();
void on_actionOpen_O_triggered();
void on_actionSave_S_triggered();
void on_actionSaveAs_A_triggered();
void on_actionViewText_V_triggered();
//void on_actionExit_X_triggered();
void on_actionEdit_E_toggled(bool arg1);
//void on_actionFlip_F_triggered();
//void on_actionMirror_M_triggered();
//void on_actionTurnRight_R_triggered();
//void on_actionTurnLeftt_L_triggered();
void on_actionInvert_I_toggled(bool arg1);
void on_actionBegin_S_triggered();
void on_actionPrevious_B_triggered();
void on_actionNext_F_triggered();
void on_actionEnd_E_triggered();
void on_actionAutoRun_A_toggled(bool arg1);
void on_actionResign_R_triggered();
void on_actionLimited_T_triggered();
void on_actionLocal_L_triggered();
void on_actionInternet_I_triggered();
void on_actionEngine_E_triggered();
//void on_actionEngine1_R_toggled(bool arg1);
//void on_actionEngine2_T_toggled(bool arg1);
//void on_actionSetting_O_triggered();
//void on_actionToolBar_T_toggled(bool arg1);
//void on_actionDockBar_D_toggled(bool arg1);
//void on_actionSound_S_toggled(bool arg1);
//void on_actionAnimation_A_toggled(bool arg1);
void on_actionViewHelp_V_triggered();
void on_actionWeb_W_triggered();
void on_actionAbout_A_triggered();
};
#endif // NINECHESSWINDOW_H

131
NineChess/src/pieceitem.cpp Normal file
View File

@ -0,0 +1,131 @@
#include "pieceitem.h"
#include "graphicsconst.h"
#include <QPainter>
#include <QStyleOption>
PieceItem::PieceItem(QGraphicsItem *parent) : QGraphicsItem(parent),
num(0),
deleted(false),
showNum(false)
{
Q_UNUSED(parent)
// 允许选择和移动
setFlags(ItemIsSelectable
// | ItemIsMovable
);
// 设置缓存模式
setCacheMode(DeviceCoordinateCache);
//setAcceptHoverEvents(true);
// 鼠标放在棋子上时显示为伸开的手形
setCursor(Qt::OpenHandCursor);
// 只接受左键事件
setAcceptedMouseButtons(Qt::LeftButton);
// 默认模型为没有棋子
model = noPiece;
// 棋子尺寸
size = PIECE_SIZE;
// 选中子标识线宽度
chooseLineWeight = LINE_WEIGHT;
// 删除线宽度
removeLineWeight = LINE_WEIGHT * 5;
// 选中线为黄色
chooseLineColor = Qt::darkYellow;
// 删除线为橘红色
removeLineColor = QColor(0xff, 0x75, 0);
}
PieceItem::~PieceItem()
{
}
QRectF PieceItem::boundingRect() const
{
return QRectF(-size/2, -size/2, size, size);
}
QPainterPath PieceItem::shape() const
{
QPainterPath path;
path.addEllipse(boundingRect());
return path;
}
void PieceItem::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
// 空模型不画棋子
// 如果模型为黑色,则画黑色棋子
if (model == blackPiece)
painter->drawPixmap(-size/2, -size/2, size, size,
QPixmap(":/image/Resources/image/black_piece.png"));
// 如果模型为白色,则画白色棋子
else if (model == whitePiece)
painter->drawPixmap(-size/2, -size/2, size, size,
QPixmap(":/image/Resources/image/white_piece.png"));
// 如果模型要求显示序号
if (showNum)
{
// 如果模型为黑色,用白色笔画序号
painter->setPen(QColor(255, 255, 255));
// 如果模型为白色,用白色笔画序号
if (model == whitePiece)
painter->setPen(QColor(0, 0, 0));
// 字体
QFont font;
font.setFamily("Arial");
font.setPointSize(size/3);
painter->setFont(font);
// 画序号,默认中间位置偏下,需微调
painter->drawText(boundingRect().adjusted(0, 0, 0, -size/12), Qt::AlignCenter, QString::number(num));
}
// 如果模型为选中状态,则画上四个小直角
if (isSelected())
{
QPen pen(chooseLineColor, chooseLineWeight, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin);
painter->setPen(pen);
int xy = (size-chooseLineWeight)/2;
painter->drawLine(-xy, -xy, -xy, -xy/2);
painter->drawLine(-xy, -xy, -xy/2, -xy);
painter->drawLine(xy, -xy, xy, -xy/2);
painter->drawLine(xy, -xy, xy/2, -xy);
painter->drawLine(xy, xy, xy, xy/2);
painter->drawLine(xy, xy, xy/2, xy);
painter->drawLine(-xy, xy, -xy, xy/2);
painter->drawLine(-xy, xy, -xy/2, xy);
}
// 如果模型为删除状态,则画上叉号
if (deleted)
{
QPen pen(removeLineColor, removeLineWeight, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin);
painter->setPen(pen);
painter->drawLine(-size / 3, -size / 3, size / 3, size / 3);
painter->drawLine(size / 3, -size / 3, -size / 3, size / 3);
}
}
void PieceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
// 鼠标按下时变为握住的手形
setCursor(Qt::ClosedHandCursor);
QGraphicsItem::mousePressEvent(event);
}
void PieceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsItem::mouseMoveEvent(event);
}
void PieceItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
// 鼠标松开时变为伸开的手形
setCursor(Qt::OpenHandCursor);
QGraphicsItem::mouseReleaseEvent(event);
}

67
NineChess/src/pieceitem.h Normal file
View File

@ -0,0 +1,67 @@
#ifndef CHESSITEM_H
#define CHESSITEM_H
#include <QGraphicsItem>
class PieceItem : public QGraphicsItem
{
public:
explicit PieceItem(QGraphicsItem *parent = 0);
~PieceItem();
QRectF boundingRect() const;
QPainterPath shape() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget * widget = 0);
// 用UserType+2表示棋子用qgraphicsitem_cast()判断是否为PieceItem类的对象
// 还有一个方式是把类名放在Data的0key位置setData(0, "PieceItem")然后用data(0)来判断
enum { Type = UserType + 2 };
int type() const { return Type; }
// 模型状态枚举,用位运算标明
enum Models {
noPiece = 0x1, // 空棋子
blackPiece = 0x2, // 黑色棋子
whitePiece = 0x4, // 白色棋子
};
enum Models getModel() { return model; }
void setModel(enum Models model) { this->model = model; }
void setNum(int n) { num = n; }
bool isDeleted() { return deleted; }
void setDeleted(bool deleted = true)
{
this->deleted = deleted;
if (deleted)
this->model = noPiece;
update(boundingRect());
}
void setShowNum(bool show = true) { this->showNum = show; }
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
private:
// 棋子本质
enum Models model;
// 棋子序号黑白都从1开始
int num;
// 棋子尺寸
qreal size;
// 有无删除线
bool deleted;
// 显示序号
bool showNum;
// 选中子标识线宽度
qreal chooseLineWeight;
// 删除线宽度
qreal removeLineWeight;
// 选中线颜色
QColor chooseLineColor;
// 删除线颜色
QColor removeLineColor;
};
#endif // CHESSITEM_H

View File

@ -0,0 +1,28 @@
/* QListView派生类
* sizeHint函数
*
* QDockWidget没有很好的控制初始大小的方法resize函数没效果
* 使
* ui.listView->setFixedWidth(108);
*
*/
#ifndef SIZEHINTLISTVIEW
#define SIZEHINTLISTVIEW
#include <QListView>
class SizeHintListView : public QListView
{
public:
SizeHintListView(QWidget * parent = 0) {}
QSize sizeHint() const{
QSize size = QListView::sizeHint();
// 缺省宽度设为128这样就不太宽了
size.setWidth(128);
return size;
}
};
#endif // SIZEHINTLISTVIEW

43
Readme.md Normal file
View File

@ -0,0 +1,43 @@
# 九联棋 NineChess
#### 项目介绍:
本游戏根据作者儿时游戏——“九联棋”编制,加上“成三棋”、“打三棋”和“莫里斯九子棋”,共三种规则玩法。
三种规则略有差异,鼠标放在相应菜单项有会有详细的规则提示。
#### 软件构架:
+ GUI框架Qt5.10Qt5大版本下均可通用。
+ 编译器MSVC2017MSVC2013及以上版本可用。
+ 源文件编码:所有头文件(*.h)和源文件(*.cpp)采用UTF-8+BOM编码格式。pro文件等采用UTF-8无BOM编码。
+ 本程序采用MVC模型——视图——控制器设计规范对应类如下
```
MVC
├─Model
│ └─NineChess用标准C++写的棋类模型,处理下棋过程
├─View
│ ├─NineChessWindow从QMainWindow派生的主窗口类由Qt自动生成
│ ├─SizeHintListView从QListView派生的列表框
│ ├─GameScene从QGraphicsScene派生的场景类
│ ├─GameView从QGraphicsView派生的视图框
│ ├─BoardItem从QGraphicsItem派生的棋盘图形类
│ └─PiecedItem从QGraphicsItem派生的棋子图形类
└─Controller
└─GameController从QObject派生的控制类
```
+ 这个程序用到了很多Qt特性其模式后期可以扩展到各种棋类游戏适合初学者一看。
#### 许可协议
参见Licence.txt
#### 更新历史
参见History.txt
#### 作者声明:
多年前上大学那会儿,笔者就打算做这么个程序出来。然而,条件比较艰苦:
一来没有老师教课上只学了C语言和VBC++是笔者自学的一个人啃晦涩过时的MFC;
二来我穷到连个电脑都没有……
三嘛,就是贪玩……
工作之后有条件了我又自学了C#和Qt但都很肤浅没深入学只用来做几个小工具而已。
从5月末开始消沉到后来步入人生低谷我终于有大把的时间来思考人生。
风雨过后,我想起把时间用在兴趣爱好上。于是,这个小游戏诞生了!
如果你发现本程序有什么问题或好的建议请与本人联系。我的邮箱是liuweilhy@163.com
>          ——by liuweilhy 2015年11月6日