优化结构,内嵌声音

This commit is contained in:
liuweilhy 2018-09-21 02:13:15 +08:00
parent a22595a93d
commit c4c1bdf583
20 changed files with 555 additions and 149 deletions

320
.gitignore vendored
View File

@ -1,11 +1,311 @@
################################################################################
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
################################################################################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
/NineChess/debug
/NineChess/release
/NineChess/GeneratedFiles
/NineChess/x64
/NineChess/x86
/NineChess/.vs
/.vs
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# QT
# C++ objects and libs
*.slo
*.lo
*.o
*.a
*.la
*.lai
*.so
*.dll
*.dylib
# Qt-es
object_script.*.Release
object_script.*.Debug
*_plugin_import.cpp
/.qmake.cache
/.qmake.stash
*.pro.user
*.pro.user.*
*.qbs.user
*.qbs.user.*
*.moc
moc_*.cpp
moc_*.h
qrc_*.cpp
ui_*.h
*.qmlc
*.jsc
Makefile*
*build-*
# Qt unit tests
target_wrapper.*
# QtCreator
*.autosave
# QtCreator Qml
*.qmlproject.user
*.qmlproject.user.*
# QtCreator CMake
CMakeLists.txt.user*

View File

@ -1,8 +1,13 @@
九连棋 NineChess
更新历史:
2018/5/19 V1.0
# 九连棋 NineChess
## 更新历史:
### 2018/9/14 V1.1
1. 添加棋谱及历史纪录浏览功能。
2. 添加棋谱保存与打开功能。
### 2018/5/19 V1.0
1. Qt5.10.1+MSVC2017重构
2. 游戏可以正确运行,实现本机对战功能,其它功能待完善。
2015/11/6 V0.1
### 2015/11/6 V0.1
1. 无算法只有界面的程序。

View File

@ -1,4 +1,4 @@
本软件代码遵循LGPL v3协议其中
本软件代码遵循LGPL v3协议其中
1. 对于Qt库遵循GPL协议。任何人都可以免费使用但必须保持其开源
2. 对于原作者自行开发的代码:
2.1 任何人可以不经原作者授权使用、修改和分发此代码但必须保持LGPL v3协议
@ -6,5 +6,5 @@
本软件的可执行文件:
1. Qt库文件归Qt版权方所有
2. 其余可执行文件,任何人可以免费使用、传播,但不得反汇编、修改,不得商用及其它违法用途。
2. 其余可执行文件,任何人可以免费使用、传播,但不得商用及其它违法用途。
—— by liuweilhy 2018.05.21

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.6.1, 2018-08-30T00:01:19. -->
<!-- Written by QtCreator 4.6.1, 2018-09-02T15:21:34. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@ -209,6 +209,7 @@
<ClCompile Include="src\pieceitem.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
<ClInclude Include="src\boarditem.h" />
<QtMoc Include="src\gamecontroller.h">
</QtMoc>
@ -262,6 +263,7 @@
</QtUic>
</ItemGroup>
<ItemGroup>
<None Include="..\Readme.md" />
<None Include="Resources\icon\ActualSizeHS.png" />
<None Include="Resources\icon\Black.png" />
<None Include="Resources\icon\BreakpointHS.png" />
@ -302,12 +304,15 @@
<None Include="Resources\image\white_piece.png" />
</ItemGroup>
<ItemGroup>
<None Include="History.txt" />
<None Include="NineChess.rc" />
<None Include="Readme.txt" />
<ResourceCompile Include="NineChess.rc" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="NineChess.rc" />
<Text Include="..\History.txt" />
<Text Include="..\Licence.txt" />
<Text Include="..\范例棋谱.txt" />
</ItemGroup>
<ItemGroup>
<Image Include="NineChess.ico" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">

View File

@ -107,6 +107,9 @@
<ClInclude Include="src\pieceitem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Generated Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
@ -236,17 +239,7 @@
<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>
<None Include="..\Readme.md" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="NineChess.rc" />
@ -256,4 +249,12 @@
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<Text Include="..\History.txt" />
<Text Include="..\Licence.txt" />
<Text Include="..\范例棋谱.txt" />
</ItemGroup>
<ItemGroup>
<Image Include="NineChess.ico" />
</ItemGroup>
</Project>

View File

@ -1,43 +1,52 @@
<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"/>
<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">
<file>Resources/sound/choose.wav</file>
<file>Resources/sound/drog.wav</file>
<file>Resources/sound/forbidden.wav</file>
<file>Resources/sound/loss.wav</file>
<file>Resources/sound/move.wav</file>
<file>Resources/sound/newgame.wav</file>
<file>Resources/sound/remove.wav</file>
<file>Resources/sound/win.wav</file>
</qresource>
</RCC>

View File

@ -98,7 +98,7 @@
<addaction name="actionEnd_E"/>
<addaction name="actionAutoRun_A"/>
<addaction name="separator"/>
<addaction name="actionResign_R"/>
<addaction name="actionGiveUp_G"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menu_E">
@ -648,7 +648,7 @@
<string>自动演示(A)</string>
</property>
</action>
<action name="actionResign_R">
<action name="actionGiveUp_G">
<property name="icon">
<iconset resource="ninechesswindow.qrc">
<normaloff>:/icon/Resources/icon/BreakpointHS.png</normaloff>:/icon/Resources/icon/BreakpointHS.png</iconset>

35
NineChess/resource.h Normal file
View File

@ -0,0 +1,35 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 NineChess.rc 使用
//
#define _USE_DECLSPECS_FOR_SAL 0
#define _USE_ATTRIBUTES_FOR_SAL 0
#define __drv_typeConst 0
#define __drv_typeCond 1
#define VS_VERSION_INFO 1
#define VFFF_ISSHAREDFILE 0x0001
#define VFF_CURNEDEST 0x0001
#define VIFF_FORCEINSTALL 0x0001
#define WINAPI_FAMILY_PC_APP 2
#define __drv_typeBitset 2
#define VFF_FILEINUSE 0x0002
#define VIFF_DONTDELETEOLD 0x0002
#define WINAPI_FAMILY_PHONE_APP 3
#define __drv_typeExpr 3
#define WINAPI_FAMILY_SYSTEM 4
#define VFF_BUFFTOOSMALL 0x0004
#define WINAPI_FAMILY_SERVER 5
#define _SAL_VERSION 20
#define WINAPI_FAMILY_DESKTOP_APP 100
#define VS_USER_DEFINED 100
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,11 +1,12 @@
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
#include <QGraphicsView>
#include <QGraphicsSceneMouseEvent>
#include <QKeyEvent>
#include <QApplication>
#include <Qsound>
#include <QSound>
#include <QDebug>
#include <QMessageBox>
#include <QAbstractButton>
@ -33,16 +34,6 @@ stepsLimit(0)
// 已在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相关事件在重载函数中已设定不必安装监视器。
@ -124,7 +115,7 @@ void GameController::gameReset()
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundNewgame);
playSound(":/sound/Resources/sound/newgame.wav");
}
void GameController::setEditing(bool arg)
@ -199,10 +190,11 @@ void GameController::setSound(bool arg)
hasSound = arg;
}
void GameController::playSound(QString &soundPath)
void GameController::playSound(const QString &soundPath)
{
if (hasSound)
QSound::play(soundPath);
if (hasSound) {
QSound::play(soundPath);
}
}
bool GameController::eventFilter(QObject * watched, QEvent * event)
@ -237,7 +229,7 @@ void GameController::timerEvent(QTimerEvent *event)
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundWin);
playSound(":/sound/Resources/sound/win.wav");
}
/*
int ti = time.elapsed();
@ -396,8 +388,9 @@ bool GameController::actionPiece(QPointF pos)
manualListModel.insertRow(++currentRow);
manualListModel.setData(manualListModel.index(currentRow), (*i).c_str());
}
if (chess.whoWin() != NineChess::NOBODY)
playSound(soundWin);
if (chess.whoWin() != NineChess::NOBODY &&
(manualListModel.data(manualListModel.index(currentRow-1))).toString().contains("Time over."))
playSound(":/sound/Resources/sound/win.wav");
}
updateScence(this->chess);
@ -422,7 +415,7 @@ bool GameController::choosePiece(QPointF pos)
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundChoose);
playSound(":/sound/Resources/sound/choose.wav");
return true;
}
else {
@ -444,7 +437,7 @@ bool GameController::placePiece(QPointF pos)
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundDrog);
playSound(":/sound/Resources/sound/drog.wav");
return true;
}
@ -465,7 +458,7 @@ bool GameController::movePiece(QPointF pos)
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundMove);
playSound(":/sound/Resources/sound/move.wav");
return true;
}
return false;
@ -486,23 +479,35 @@ bool GameController::removePiece(QPointF pos)
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundRemove);
playSound(":/sound/Resources/sound/remove.wav");
return true;
}
/* 下面的用不到了
bool GameController::cleanForbidden()
bool GameController::giveUp()
{
for (PieceItem *p : pieceList)
{
if (p->isDeleted()) {
pieceList.removeOne(p);
delete p;
}
}
return true;
bool result = false;
if (chess.whosTurn() == NineChess::PLAYER1)
result = chess.giveup(NineChess::PLAYER1);
else if (chess.whosTurn() == NineChess::PLAYER2)
result = chess.giveup(NineChess::PLAYER2);
if (result)
{
// 将新增的棋谱行插入到ListModel
currentRow = manualListModel.rowCount() - 1;
int k = 0;
// 输出命令行
for (auto i = (chess.getCmdList())->begin(); i != (chess.getCmdList())->end(); ++i) {
// 跳过已添加的因标准list容器没有下标
if (k++ <= currentRow)
continue;
manualListModel.insertRow(++currentRow);
manualListModel.setData(manualListModel.index(currentRow), (*i).c_str());
}
if (chess.whoWin() != NineChess::NOBODY)
playSound(":/sound/Resources/sound/loss.wav");
}
return result;
}
*/
bool GameController::updateScence(NineChess &chess)
{

View File

@ -64,9 +64,11 @@ public slots:
// 是否有落子音效
void setSound(bool arg = true);
// 播放声音
void playSound(QString &soundPath);
void playSound(const QString &soundPath);
// 根据QGraphicsScene的信号和状态来执行选子、落子或去子
bool actionPiece(QPointF p);
// 认输
bool giveUp();
// 棋谱的命令行执行
bool command(QString &cmd);
// 历史局面及局面改变
@ -84,8 +86,6 @@ protected:
bool movePiece(QPointF pos);
// 去子
bool removePiece(QPointF pos);
// 删除禁止点子
//bool cleanForbidden();
// 更新棋局显示,每步后必须执行
bool updateScence(NineChess &chess);
@ -131,15 +131,6 @@ private:
// 用于主窗口状态栏显示的字符串
QString message;
// 各个音效文件路径
QString soundNewgame;
QString soundChoose;
QString soundMove;
QString soundDrog;
QString soundForbidden;
QString soundRemove;
QString soundWin;
QString soundLoss;
};
#endif // GAMECONTROLLER_H

View File

@ -6,9 +6,11 @@ GameView::GameView(QWidget * parent) :
QGraphicsView(parent)
{
Q_UNUSED(parent)
/* 不使用下面的方法
// 初始化缩放因子为1.0
sx = 1.0;
sy = 1.0;
*/
}
GameView::~GameView()
@ -29,8 +31,8 @@ void GameView::flip()
* 0 -1 0
* 0 0 1
*/
// 方法一: 直接在原变换矩阵基础上乘以上面的矩阵
// QMatrix只对变换矩阵前两列赋值
// 方法一: 直接在原变换矩阵基础上乘以上面的矩阵
// QMatrix只对变换矩阵前两列赋值
setMatrix(matrix() * QMatrix(1, 0, 0, -1, 0, 0));
/* 方法二: 人工计算好新的变换矩阵后再对场景赋值
*
@ -81,12 +83,12 @@ void GameView::turnLeft()
void GameView::resizeEvent(QResizeEvent * event)
{
/* 不使用下面的形式了
// 让场景适合视图
Q_UNUSED(event)
if (sceneRect().width() <= 0 || sceneRect().height() <= 0)
return;
// 恢复缩放前的大小
scale(1/sx, 1/sy);
scale(1 / sx, 1 / sy);
// 设置缩放因子
sx = width() / sceneRect().width();
sy = height() / sceneRect().height();
@ -95,5 +97,9 @@ void GameView::resizeEvent(QResizeEvent * event)
// 缩放视图适合场景大小
scale(sx, sy);
//qDebug() << "scale :" << sx;
*/
// 使用如下形式,更简洁
QGraphicsView::resizeEvent(event);
fitInView(sceneRect(), Qt::KeepAspectRatio);
}

View File

@ -22,8 +22,8 @@ protected:
void resizeEvent(QResizeEvent * event);
private:
// 缩放因子
qreal sx, sy;
// 缩放因子,代码更新后不使用了
// qreal sx, sy;
};
#endif // GRAPHICSVIEW_H

View File

@ -708,6 +708,32 @@ bool NineChess::choose(int c, int p)
return false;
}
bool NineChess::giveup(Player loser)
{
if (phase == GAME_MID || phase == GAME_OPENING)
{
if (loser == PLAYER1)
{
phase = GAME_OVER;
winner = PLAYER2;
tip = "玩家1投子认负恭喜玩家2获胜";
sprintf(cmdline, "Player1 give up!");
cmdlist.push_back(string(cmdline));
return true;
}
else if (loser == PLAYER2)
{
phase = GAME_OVER;
winner = PLAYER1;
tip = "玩家2投子认负恭喜玩家1获胜";
sprintf(cmdline, "Player2 give up!");
cmdlist.push_back(string(cmdline));
return true;
}
}
return false;
}
// 打算用个C++的命令行解析库的,简单的没必要,但中文编码有极小概率出问题
bool NineChess::command(const char *cmd)
{
@ -757,6 +783,18 @@ bool NineChess::command(const char *cmd)
return place(c1, p1, tm);
}
// 认输
args = sscanf(cmd, "Player%1u give up!", &t);
if (args == 1) {
if (t == 1) {
return giveup(PLAYER1);
}
else if (t == 2)
{
return giveup(PLAYER2);
}
}
return false;
}
@ -886,14 +924,26 @@ bool NineChess::win()
}
// 如果中局被“闷”
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;
sprintf(cmdline, "Surrounded. Player%1d win!", winner == PLAYER1 ? 1 : 2);
cmdlist.push_back(string(cmdline));
return true;
if (turn == PLAYER1)
{
tip = "玩家1无子可走恭喜玩家2获胜";
winner = PLAYER2;
phase = GAME_OVER;
sprintf(cmdline, "Player1 no way to go. Player2 win!");
cmdlist.push_back(string(cmdline));
return true;
}
else
{
tip = "玩家2无子可走恭喜玩家1获胜";
winner = PLAYER1;
phase = GAME_OVER;
sprintf(cmdline, "Player2 no way to go. Player1 win!");
cmdlist.push_back(string(cmdline));
return true;
}
}
// 否则让棋,由对手走
else

View File

@ -87,7 +87,7 @@ public:
public:
NineChess();
~NineChess();
virtual ~NineChess();
// 设置棋局状态和棋盘数据,用于初始化
bool setData(const struct Rule *rule,
int s = 0, // 限制步数
@ -156,6 +156,8 @@ public:
bool place(int c, int p, long time_p = -1);
// 去子在第c圈第p个位置为迎合日常c和p下标都从1开始
bool remove(int c, int p, long time_p = -1);
// 认输
bool giveup(Player loser);
// 命令行解析函数
bool command(const char *cmd);

View File

@ -1,6 +1,7 @@
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
#include <QDesktopServices>
#include <QMap>
#include <QMessageBox>
@ -139,7 +140,9 @@ void NineChessWindow::initialize()
}
// 关联主窗口动作信号和控制器的槽
connect(ui.actionEngine1_T, SIGNAL(toggled(bool)),
connect(ui.actionGiveUp_G, SIGNAL(triggered()),
game, SLOT(giveUp()));
connect(ui.actionEngine1_T, SIGNAL(toggled(bool)),
game, SLOT(setEngine1(bool)));
connect(ui.actionEngine2_R, SIGNAL(toggled(bool)),
game, SLOT(setEngine2(bool)));
@ -418,10 +421,6 @@ void NineChessWindow::on_actionAutoRun_A_toggled(bool arg1)
}
void NineChessWindow::on_actionResign_R_triggered()
{
}
void NineChessWindow::on_actionLimited_T_triggered()
{

View File

@ -59,7 +59,7 @@ private slots:
// 前后招的公共槽
void on_actionRowChange();
void on_actionAutoRun_A_toggled(bool arg1);
void on_actionResign_R_triggered();
//void on_actionGiveUp_G_triggered();
void on_actionLimited_T_triggered();
void on_actionLocal_L_triggered();
void on_actionInternet_I_triggered();

View File

@ -15,12 +15,13 @@ showNum(false)
);
// 设置缓存模式
setCacheMode(DeviceCoordinateCache);
//setAcceptHoverEvents(true);
// 鼠标放在棋子上时显示为伸开的手形
setCursor(Qt::OpenHandCursor);
// 只接受左键事件
//setAcceptedMouseButtons(Qt::LeftButton);
// 不接受鼠标事件
setAcceptedMouseButtons(0);
//setAcceptHoverEvents(true);
// 默认模型为没有棋子
model = noPiece;
// 棋子尺寸

View File

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