AI运用前的最后一次GUI更新:

优化了大量编译警告,优化场景动画,添加禁止音效。
This commit is contained in:
liuweilhy 2018-11-14 21:00:00 +08:00
parent 0f3c3819fd
commit 602af2b340
11 changed files with 85 additions and 59 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.7.2, 2018-11-12T00:10:52. -->
<!-- Written by QtCreator 4.7.2, 2018-11-14T00:28:28. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
@ -312,7 +312,7 @@
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">ninechess.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/media/sniper/Work/My program/QT/NineChess/build-ninechess-Desktop_Qt_5_12_0_GCC_64bit-Debug</value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>

View File

@ -5,12 +5,12 @@
class BoardItem : public QGraphicsItem
{
public:
explicit BoardItem(QGraphicsItem *parent = 0);
explicit BoardItem(QGraphicsItem *parent = nullptr);
~BoardItem();
QRectF boundingRect() const;
QPainterPath shape() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget * widget = 0);
QWidget * widget = nullptr);
// 用UserType+1表示棋子用qgraphicsitem_cast()判断是否为BoardItem类的对象
// 还有一个方式是把类名放在Data的0key位置setData(0, "BoardItem")然后用data(0)来判断

View File

@ -19,7 +19,7 @@
GameController::GameController(GameScene &scene, QObject *parent) : QObject(parent),
// 是否浏览过历史纪录
scene(scene),
currentPiece(NULL),
currentPiece(nullptr),
currentRow(-1),
isEditing(false),
isInverted(false),
@ -91,7 +91,7 @@ void GameController::gameReset()
// 清除棋子
qDeleteAll(pieceList);
pieceList.clear();
currentPiece = NULL;
currentPiece = nullptr;
// 重新绘制棋盘
scene.setDiagonal(chess.getRule()->hasObliqueLine);
@ -296,13 +296,14 @@ void GameController::timerEvent(QTimerEvent *event)
*/
}
bool GameController::command(QString &cmd)
bool GameController::command(QString &cmd, bool update /*= true*/)
{
if (chess.command(cmd.toStdString().c_str())) {
if (chess.getPhase() == NineChess::GAME_NOTSTARTED) {
gameReset();
gameStart();
}
if (update)
updateScence(chess);
// 将新增的棋谱行插入到ListModel
currentRow = manualListModel.rowCount() - 1;
@ -323,14 +324,14 @@ bool GameController::command(QString &cmd)
}
// 历史局面
void GameController::phaseChange(int row, bool change /*= false*/)
bool GameController::phaseChange(int row)
{
// 如果row是当前浏览的棋谱行直接推出不刷新
// 如果row是当前浏览的棋谱行需要刷新
if (currentRow == row)
return;
else
currentRow = row;
return false;
// 需要刷新
currentRow = row;
int rows = manualListModel.rowCount();
QStringList mlist = manualListModel.stringList();
qDebug() << "rows:" << rows << " current:" << row;
@ -341,8 +342,9 @@ void GameController::phaseChange(int row, bool change /*= false*/)
}
// 下面这步关键,让悔棋者承担时间损失
chessTemp.setStartTimeb(chess.getStartTimeb());
// 刷新棋局场景
updateScence(chessTemp);
return true;
}
// 槽函数根据QGraphicsScene的信号和状态来执行选子、落子或去子
@ -434,7 +436,7 @@ bool GameController::actionPiece(QPointF pos)
playSound(":/sound/Resources/sound/win.wav");
}
updateScence(this->chess);
updateScence();
return result;
}
@ -445,7 +447,7 @@ bool GameController::choosePiece(QPointF pos)
if (!scene.pos2cp(pos, c, p)) {
return false;
}
PieceItem *piece = NULL;
PieceItem *piece = nullptr;
QGraphicsItem *item = scene.itemAt(pos, QTransform());
piece = qgraphicsitem_cast<PieceItem *>(item);
if (!piece) {
@ -455,11 +457,13 @@ bool GameController::choosePiece(QPointF pos)
// 发信号更新状态栏
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 播放音效
// 播放选子音效
playSound(":/sound/Resources/sound/choose.wav");
return true;
}
else {
// 播放禁止音效
playSound(":/sound/Resources/sound/forbidden.wav");
return false;
}
}
@ -472,6 +476,8 @@ bool GameController::placePiece(QPointF pos)
return false;
}
if (!chess.place(c, p)) {
// 播放禁止音效
playSound(":/sound/Resources/sound/forbidden.wav");
return false;
}
// 发信号更新状态栏
@ -502,6 +508,8 @@ bool GameController::movePiece(QPointF pos)
playSound(":/sound/Resources/sound/move.wav");
return true;
}
// 播放禁止音效
playSound(":/sound/Resources/sound/forbidden.wav");
return false;
}
@ -513,6 +521,8 @@ bool GameController::removePiece(QPointF pos)
return false;
}
if (!chess.remove(c, p)) {
// 播放禁止音效
playSound(":/sound/Resources/sound/forbidden.wav");
return false;
}
@ -550,6 +560,11 @@ bool GameController::giveUp()
return result;
}
bool GameController::updateScence()
{
return updateScence(chess);
}
bool GameController::updateScence(NineChess &chess)
{
const char *board = chess.getBoard();
@ -563,7 +578,7 @@ bool GameController::updateScence(NineChess &chess)
QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup;
// 棋子就位
PieceItem *piece = NULL;
PieceItem *piece = nullptr;
for (int i = 0; i < n; i++)
{
piece = pieceList.at(i);

View File

@ -26,7 +26,7 @@ class GameController : public QObject
Q_OBJECT
public:
GameController(GameScene &scene, QObject *parent = 0);
GameController(GameScene &scene, QObject *parent = nullptr);
~GameController();
//主窗口菜单栏明细
const QMap <int, QStringList> getActions();
@ -73,9 +73,12 @@ public slots:
// 认输
bool giveUp();
// 棋谱的命令行执行
bool command(QString &cmd);
bool command(QString &cmd, bool update = true);
// 历史局面及局面改变
void phaseChange(int row, bool change = false);
bool phaseChange(int row);
// 更新棋局显示,每步后必须执行
bool updateScence();
bool updateScence(NineChess &chess);
protected:
bool eventFilter(QObject * watched, QEvent * event);
@ -89,8 +92,6 @@ protected:
bool movePiece(QPointF pos);
// 去子
bool removePiece(QPointF pos);
// 更新棋局显示,每步后必须执行
bool updateScence(NineChess &chess);
private:
// 棋对象的数据模型

View File

@ -9,7 +9,7 @@
#include <QDebug>
GameScene::GameScene(QObject *parent) : QGraphicsScene(parent),
board(NULL),
board(nullptr),
pos_p1(LINE_INTERVAL * 4, LINE_INTERVAL * 6),
pos_p1_g(LINE_INTERVAL* (-4), LINE_INTERVAL * 6),
pos_p2(LINE_INTERVAL * (-4), LINE_INTERVAL * (-6)),
@ -29,7 +29,7 @@ GameScene::~GameScene()
void GameScene::keyPressEvent(QKeyEvent *keyEvent)
{
// 屏蔽掉Shift和Control按键事实证明没用按键事件未必由图类处理
// 屏蔽掉Shift和Control按键事实证明没用按键事件未必由图类处理
if(keyEvent->key() == Qt::Key_Shift || keyEvent->key() == Qt::Key_Control)
return;
QGraphicsScene::keyPressEvent(keyEvent);
@ -38,16 +38,17 @@ void GameScene::keyPressEvent(QKeyEvent *keyEvent)
void GameScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
//什么也不做,屏蔽双击事件
Q_UNUSED(mouseEvent)
}
void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
//什么也不做,屏蔽鼠标按下事件
Q_UNUSED(mouseEvent)
/*
// 只处理左键事件
if(mouseEvent->button() != Qt::LeftButton)
return;
// 调用默认事件处理函数
QGraphicsScene::mousePressEvent(mouseEvent);
// 如果不是棋子则结束
QGraphicsItem *item = itemAt(mouseEvent->scenePos(), QTransform());
if (!item || item->type() != PieceItem::Type)
@ -55,11 +56,9 @@ void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
return;
}
// 取消其它棋子的选中状态
//for (QGraphicsItem * item: selectedItems())
//{
// item->setSelected(false);
//}
// 调用默认事件处理函数
//QGraphicsScene::mousePressEvent(mouseEvent);
*/
}
void GameScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
@ -67,8 +66,6 @@ void GameScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
// 只处理左键事件
if(mouseEvent->button() != Qt::LeftButton)
return;
// 调用默认事件处理函数
QGraphicsScene::mouseReleaseEvent(mouseEvent);
// 如果是棋盘
QGraphicsItem *item = itemAt(mouseEvent->scenePos(), QTransform());
@ -85,6 +82,9 @@ void GameScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
// 将当前棋子在场景中的位置发送出去
emit mouseReleased(item->scenePos());
}
// 调用默认事件处理函数
//QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
QPointF GameScene::cp2pos(int c, int p)

View File

@ -164,7 +164,7 @@ bool NineChess::setData(const struct Rule *rule, int s, int t, int step, int fla
// 胜负标识
winner = NOBODY;
// 当前棋局3×8
if (boardsource == NULL)
if (boardsource == nullptr)
memset(this->board, 0, sizeof(this->board));
else
memcpy(this->board, boardsource, sizeof(this->board));
@ -315,7 +315,7 @@ bool NineChess::setData(const struct Rule *rule, int s, int t, int step, int fla
return false;
}
return true;
//return true;
}
void NineChess::getData(struct Rule &rule, int &step, int &chess, const char *&board,
@ -688,7 +688,7 @@ bool NineChess::choose(int c, int p)
return false;
int pos = cp2pos(c, p);
// 根据先后手,判断可选子
char t;
char t ='\0';
if (turn == PLAYER1)
t = '\x10';
else if (turn == PLAYER2)

View File

@ -95,7 +95,7 @@ public:
int t = 0, // 限制时间
int step = 0, // 默认起始步数为0
int flags = GAME_NOTSTARTED | PLAYER1 | ACTION_PLACE | NOBODY, // 默认状态
const char *boardsource = NULL, // 默认空棋盘
const char *boardsource = nullptr, // 默认空棋盘
int p1_InHand = 12, // 玩家1剩余未放置子数
int p2_InHand = 12, // 玩家2剩余未放置子数
int num_NeedRemove = 0 // 尚待去除的子数

View File

@ -24,8 +24,8 @@
NineChessWindow::NineChessWindow(QWidget *parent)
: QMainWindow(parent),
scene(NULL),
game(NULL),
scene(nullptr),
game(nullptr),
ruleNo(0)
{
ui.setupUi(this);
@ -80,7 +80,7 @@ NineChessWindow::NineChessWindow(QWidget *parent)
NineChessWindow::~NineChessWindow()
{
if (game != NULL)
if (game != nullptr)
delete game;
qDeleteAll(ruleActionList);
if (file.isOpen())
@ -115,8 +115,7 @@ void NineChessWindow::initialize()
// 添加新菜单栏动作
QMap <int, QStringList> actions = game->getActions();
QMap <int, QStringList>::const_iterator i;
for (i = actions.constBegin(); i != actions.constEnd(); i++) {
for (auto 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);
@ -260,18 +259,29 @@ void NineChessWindow::on_actionOpen_O_triggered()
msgBox.exec();
return;
}
//打开文件,只读方式打开
bool isok = file.open(QFileDevice::ReadOnly | QFileDevice::Text);
if (isok = true)
if (isok)
{
//读文件
QTextStream textStream(&file);
QString cmd;
cmd = textStream.readLine();
// 读取并显示棋谱时,不必刷新棋局场景
if(!(game->command(cmd,false))) {
// 定义新对话框
QMessageBox msgBox(QMessageBox::Warning, tr("文件错误"), tr("不是正确的棋谱文件"), QMessageBox::Ok);
msgBox.exec();
return;
}
while (!textStream.atEnd())
{
cmd = textStream.readLine();
game->command(cmd);
game->command(cmd, false);
}
// 最后刷新棋局场景
game->updateScence();
}
}
}
@ -283,7 +293,7 @@ void NineChessWindow::on_actionSave_S_triggered()
file.close();
//打开文件,只写方式打开
bool isok = file.open(QFileDevice::WriteOnly | QFileDevice::Text);
if (isok = true)
if (isok)
{
//写文件
QTextStream textStream(&file);
@ -308,7 +318,7 @@ void NineChessWindow::on_actionSaveAs_A_triggered()
file.setFileName(path);
//打开文件,只写方式打开
bool isok = file.open(QFileDevice::WriteOnly | QFileDevice::Text);
if (isok = true)
if (isok)
{
//写文件
QTextStream textStream(&file);
@ -357,21 +367,21 @@ void NineChessWindow::on_actionRowChange()
int currentRow = ui.listView->currentIndex().row();
QObject * const obsender = sender();
if (obsender != NULL) {
if (obsender == (QObject *)ui.actionBegin_S) {
if (obsender != nullptr) {
if (obsender == ui.actionBegin_S) {
ui.listView->setCurrentIndex(model->index(0, 0));
}
else if (obsender == (QObject *)ui.actionPrevious_B) {
else if (obsender == ui.actionPrevious_B) {
if (currentRow > 0) {
ui.listView->setCurrentIndex(model->index(currentRow - 1, 0));
}
}
else if (obsender == (QObject *)ui.actionNext_F) {
else if (obsender == ui.actionNext_F) {
if (currentRow < rows - 1) {
ui.listView->setCurrentIndex(model->index(currentRow + 1, 0));
}
}
else if (obsender == (QObject *)ui.actionEnd_E) {
else if (obsender == ui.actionEnd_E) {
ui.listView->setCurrentIndex(model->index(rows - 1, 0));
}
currentRow = ui.listView->currentIndex().row();
@ -412,9 +422,9 @@ void NineChessWindow::on_actionRowChange()
}
// 更新局面
game->phaseChange(currentRow);
bool changed = game->phaseChange(currentRow);
// 处理自动播放时的动画
if (game->isAnimation()) {
if (changed && game->isAnimation()) {
int waitTime = game->getDurationTime() + 50;
// 使用QEventLoop进行非阻塞延时CPU占用低
QEventLoop loop;
@ -596,7 +606,7 @@ void NineChessWindow::on_actionInternet_I_triggered()
void NineChessWindow::on_actionEngine_E_triggered()
{
// 空着,有时间再做
}
void NineChessWindow::on_actionViewHelp_V_triggered()

View File

@ -15,7 +15,7 @@ class NineChessWindow : public QMainWindow
Q_OBJECT
public:
NineChessWindow(QWidget *parent = 0);
NineChessWindow(QWidget *parent = nullptr);
~NineChessWindow();
protected:

View File

@ -10,12 +10,12 @@ class PieceItem : public QObject, public QGraphicsItem
Q_PROPERTY(QPointF pos READ pos WRITE setPos)
public:
explicit PieceItem(QGraphicsItem *parent = 0);
explicit PieceItem(QGraphicsItem *parent = nullptr);
~PieceItem();
QRectF boundingRect() const;
QPainterPath shape() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget * widget = 0);
QWidget * widget = nullptr);
// 用UserType+2表示棋子用qgraphicsitem_cast()判断是否为PieceItem类的对象
// 还有一个方式是把类名放在Data的0key位置setData(0, "PieceItem")然后用data(0)来判断

View File

@ -18,7 +18,7 @@ class SizeHintListView : public QListView
Q_OBJECT
public:
SizeHintListView(QWidget * parent = 0) { Q_UNUSED(parent) }
SizeHintListView(QWidget * parent = nullptr) { Q_UNUSED(parent) }
QSize sizeHint() const {
QSize size = QListView::sizeHint();
// 缺省宽度设为128这样就不太宽了