增加棋谱功能

This commit is contained in:
liuweilhy 2018-08-18 11:47:27 +08:00
parent 2f8fbab50a
commit b3654dd794
7 changed files with 107 additions and 69 deletions

View File

@ -221,7 +221,12 @@
<QtMoc Include="src\ninechesswindow.h">
</QtMoc>
<ClInclude Include="src\pieceitem.h" />
<ClInclude Include="src\sizehintlistview.h" />
<QtMoc Include="src\sizehintlistview.h">
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\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</IncludePath>
<Define Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_MULTIMEDIA_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_CORE_LIB</Define>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\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</IncludePath>
<Define Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;QT_MULTIMEDIA_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_CORE_LIB;NDEBUG</Define>
</QtMoc>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">

View File

@ -107,9 +107,6 @@
<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">
@ -254,4 +251,9 @@
<ItemGroup>
<ResourceCompile Include="NineChess.rc" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="src\sizehintlistview.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
</Project>

View File

@ -105,6 +105,10 @@ void GameController::gameReset()
// 将玩家的剩余时间置为限定时间
time1 = time2 = timeLimit * 60000;
}
// 更新棋谱
manualListModel.removeRows(0, manualListModel.rowCount());
manualListModel.insertRow(0);
manualListModel.setData(manualListModel.index(0), chess.getCmdLine());
// 发出信号通知主窗口更新LCD显示
QTime qtime = QTime(0, 0, 0, 0).addMSecs(time1);
emit time1Changed(qtime.toString("mm:ss.zzz"));
@ -143,12 +147,6 @@ void GameController::setInvert(bool arg)
void GameController::setRule(int ruleNo, int stepLimited /*= -1*/, int timeLimited /*= -1*/)
{
// 停止计时器
if (timeID != 0)
killTimer(timeID);
// 定时器ID为0
timeID = 0;
// 更新规则,原限时和限步不变
if (ruleNo < 0 || ruleNo >= NineChess::RULENUM)
return;
@ -159,36 +157,8 @@ void GameController::setRule(int ruleNo, int stepLimited /*= -1*/, int timeLimit
// 设置模型规则,重置游戏
chess.setData(&NineChess::RULES[ruleNo], stepsLimit, timeLimit);
// 清除棋子
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"));
// 更新棋谱
manualListModel.removeRows(0, manualListModel.rowCount());
manualListModel.insertRow(0);
manualListModel.setData(manualListModel.index(0), chess.getCmdLine());
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
playSound(soundNewgame);
// 重置游戏
gameReset();
}
void GameController::setEngine1(bool arg)
@ -344,6 +314,11 @@ bool GameController::actionPiece(QPointF pos)
return result;
}
// 历史局面
void GameController::phaseChange(const QModelIndex &index)
{
}
// 选子
PieceItem *GameController::choosePiece(QPointF pos)
{

View File

@ -14,6 +14,7 @@
#include <QList>
#include <QTextStream>
#include <QStringListModel>
#include <QModelIndex>
#include "gamescene.h"
#include "ninechess.h"
@ -64,8 +65,10 @@ public slots:
void setSound(bool arg = true);
// 播放声音
void playSound(QString &soundPath);
// 槽函数,根据QGraphicsScene的信号和状态来执行选子、落子或去子
// 根据QGraphicsScene的信号和状态来执行选子、落子或去子
bool actionPiece(QPointF p);
// 历史局面
void phaseChange(const QModelIndex &index);
protected:
bool eventFilter(QObject * watched, QEvent * event);

View File

@ -47,9 +47,6 @@ NineChessWindow::NineChessWindow(QWidget *parent)
// 因功能限制,使部分功能不可用
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);
@ -74,6 +71,7 @@ NineChessWindow::NineChessWindow(QWidget *parent)
// 初始化游戏规则菜单
ui.menu_R->installEventFilter(this);
// 安装一次性定时器,执行初始化
QTimer::singleShot(0, this, SLOT(initialize()));
}
@ -144,10 +142,13 @@ void NineChessWindow::initialize()
game, SLOT(setSound(bool)));
connect(ui.actionAnimation_A, SIGNAL(toggled(bool)),
game, SLOT(setAnimation(bool)));
connect(ui.listView, SIGNAL(activated(const QModelIndex &index)),
game, SLOT(phaseChange(const QModelIndex &index)));
/* 关联控制器的信号和主窗口控件的槽
GameController中直接控制NineChessWindow
MVC模型中控制器与视图相分离的方式 */
// 关联控制器的信号和主窗口控件的槽
// 注意采用信号和槽而非采用在GameController中直接控制NineChessWindow
// 是MVC模型中控制器与视图相分离的方式有利于程序梳理
// 更新LCD1显示玩家1用时
connect(game, SIGNAL(time1Changed(QString)),
ui.lcdNumber_1, SLOT(display(QString)));
@ -180,6 +181,24 @@ void NineChessWindow::initialize()
// 关联列表视图和字符串列表模型
ui.listView->setModel(& game->manualListModel);
// 因为QListView的rowsInserted在setModel之后才能启动
// 第一次需手动初始化选中listView第一项
qDebug() << ui.listView->model();
ui.listView->setCurrentIndex(ui.listView->model()->index(0, 0));
// 初始局面、前一步、后一步、最终局面的槽
connect(ui.actionBegin_S, &QAction::triggered,
this, &NineChessWindow::on_actionRowChange);
connect(ui.actionPrevious_B, &QAction::triggered,
this, &NineChessWindow::on_actionRowChange);
connect(ui.actionNext_F, &QAction::triggered,
this, &NineChessWindow::on_actionRowChange);
connect(ui.actionEnd_E, &QAction::triggered,
this, &NineChessWindow::on_actionRowChange);
// 手动在listView里选择招法后更新的槽
connect(ui.listView, &SizeHintListView::currentChangedSignal,
this, &NineChessWindow::on_actionRowChange);
// 更新四个键的状态
on_actionRowChange();
}
void NineChessWindow::actionRules_triggered()
@ -270,26 +289,48 @@ void NineChessWindow::on_actionInvert_I_toggled(bool arg1)
game->setInvert(arg1);
}
void NineChessWindow::on_actionBegin_S_triggered()
// 前后招的公共槽
void NineChessWindow::on_actionRowChange()
{
if (game == NULL)
return;
game->gameReset();
}
QModelIndex index = ui.listView->currentIndex();
int row = index.row();
void NineChessWindow::on_actionPrevious_B_triggered()
{
QObject * const obsender = this->sender();
if (obsender != NULL) {
if (obsender == (QObject *)ui.actionBegin_S) {
ui.listView->setCurrentIndex(ui.listView->model()->index(0, 0));
}
else if (obsender == (QObject *)ui.actionPrevious_B) {
if (row > 0) {
ui.listView->setCurrentIndex(ui.listView->model()->index(row - 1, 0));
}
}
else if (obsender == (QObject *)ui.actionNext_F) {
if (row < ui.listView->model()->rowCount() - 1) {
ui.listView->setCurrentIndex(ui.listView->model()->index(row + 1, 0));
}
}
else if (obsender == (QObject *)ui.actionEnd_E) {
ui.listView->setCurrentIndex(ui.listView->model()->index(ui.listView->model()->rowCount() - 1, 0));
}
}
void NineChessWindow::on_actionNext_F_triggered()
{
}
void NineChessWindow::on_actionEnd_E_triggered()
{
}
index = ui.listView->currentIndex();
row = index.row();
ui.actionBegin_S->setEnabled(true);
ui.actionPrevious_B->setEnabled(true);
ui.actionNext_F->setEnabled(true);
ui.actionEnd_E->setEnabled(true);
if (row <= 0) {
ui.actionBegin_S->setEnabled(false);
ui.actionPrevious_B->setEnabled(false);
}
if (row >= ui.listView->model()->rowCount()-1)
{
ui.actionNext_F->setEnabled(false);
ui.actionEnd_E->setEnabled(false);
}
}
void NineChessWindow::on_actionAutoRun_A_toggled(bool arg1)

View File

@ -54,10 +54,8 @@ private slots:
//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_actionRowChange();
void on_actionAutoRun_A_toggled(bool arg1);
void on_actionResign_R_triggered();
void on_actionLimited_T_triggered();

View File

@ -11,9 +11,12 @@
#define SIZEHINTLISTVIEW
#include <QListView>
#include <QDebug>
class SizeHintListView : public QListView
{
Q_OBJECT
public:
SizeHintListView(QWidget * parent = 0) {}
QSize sizeHint() const {
@ -23,16 +26,27 @@ public:
return size;
}
signals:
// 需要一个currentChanged信号但默认没有需要把这个槽改造成信号
void currentChangedSignal(const QModelIndex &current, const QModelIndex &previous);
protected:
// 屏蔽掉双击编辑功能
void mouseDoubleClickEvent(QMouseEvent *event) {}
// 插入新行后自动选中最后一个
void rowsInserted(const QModelIndex &parent, int start, int end) {
QModelIndex id = model()->index(model()->rowCount()-1, 0);
// 调用父类函数为使滚动条更新否则scrollToBottom不能正确执行。
QListView::rowsInserted(parent, start, end);
QModelIndex id = model()->index(end, 0);
setCurrentIndex(id);
update();
scrollToBottom();
}
// 需要一个currentChanged信号但默认没有需要把这个槽改造成信号
// activated信号需要按下回车才发出selectedChanged和clicked信号也不合适
void currentChanged(const QModelIndex &current, const QModelIndex &previous) {
QListView::currentChanged(current, previous);
emit currentChangedSignal(current, previous);
}
};
#endif // SIZEHINTLISTVIEW