完善“历史局面”功能
This commit is contained in:
parent
b3654dd794
commit
2d7a795f97
|
@ -243,6 +243,11 @@
|
|||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
@ -258,14 +263,14 @@
|
|||
<widget class="QLabel" name="label1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>2</horstretch>
|
||||
<horstretch>3</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>微软雅黑</family>
|
||||
<pointsize>10</pointsize>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
@ -319,6 +324,11 @@
|
|||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
@ -334,14 +344,14 @@
|
|||
<widget class="QLabel" name="label2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>2</horstretch>
|
||||
<horstretch>3</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>微软雅黑</family>
|
||||
<pointsize>10</pointsize>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
@ -379,6 +389,45 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelInfo">
|
||||
<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/Help.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelRule">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>8</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>AmdtSymbols</family>
|
||||
<pointsize>7</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>rule</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SizeHintListView" name="listView">
|
||||
<property name="font">
|
||||
|
|
|
@ -109,6 +109,11 @@ QPointF BoardItem::nearestPosition(QPointF const pos)
|
|||
return nearestPos;
|
||||
}
|
||||
|
||||
QPointF BoardItem::cp2pos(int c, int p)
|
||||
{
|
||||
return position[(c-1)*SEAT+p-1];
|
||||
}
|
||||
|
||||
bool BoardItem::pos2cp(QPointF pos, int &c, int &p)
|
||||
{
|
||||
// 寻找最近的落子点
|
||||
|
|
|
@ -20,6 +20,8 @@ public:
|
|||
void setDiagonal(bool arg = true);
|
||||
// 返回最近的落子点
|
||||
QPointF nearestPosition(QPointF const pos);
|
||||
// 将模型的圈、位转化为落子点坐标
|
||||
QPointF cp2pos(int c, int p);
|
||||
// 将落子点坐标转化为模型用的圈、位
|
||||
bool pos2cp(QPointF pos, int &c, int &p);
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
#include "boarditem.h"
|
||||
#include "pieceitem.h"
|
||||
|
||||
GameController::GameController(GameScene & scene, QObject *parent) : QObject(parent),
|
||||
GameController::GameController(GameScene &scene, QObject *parent) : QObject(parent),
|
||||
// 是否浏览过历史纪录
|
||||
scene(scene),
|
||||
piece(NULL),
|
||||
isEditing(false),
|
||||
|
@ -22,11 +23,10 @@ isEngine2(false),
|
|||
hasAnimation(true),
|
||||
hasSound(true),
|
||||
timeID(0),
|
||||
ruleNo(-1),
|
||||
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"));
|
||||
|
@ -85,6 +85,7 @@ void GameController::gameReset()
|
|||
timeID = 0;
|
||||
// 重置游戏
|
||||
chess.reset();
|
||||
chessTemp.reset();
|
||||
|
||||
// 清除棋子
|
||||
qDeleteAll(pieceList);
|
||||
|
@ -109,6 +110,7 @@ void GameController::gameReset()
|
|||
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"));
|
||||
|
@ -129,7 +131,7 @@ void GameController::setInvert(bool arg)
|
|||
{
|
||||
isInverted = arg;
|
||||
// 遍历所有棋子
|
||||
foreach(PieceItem * p, pieceList)
|
||||
for (PieceItem * p : pieceList)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
|
@ -150,12 +152,15 @@ void GameController::setRule(int ruleNo, int stepLimited /*= -1*/, int timeLimit
|
|||
// 更新规则,原限时和限步不变
|
||||
if (ruleNo < 0 || ruleNo >= NineChess::RULENUM)
|
||||
return;
|
||||
this->ruleNo = ruleNo;
|
||||
|
||||
if (stepLimited != -1 && timeLimited != -1) {
|
||||
stepsLimit = stepLimited;
|
||||
timeLimit = timeLimited;
|
||||
}
|
||||
// 设置模型规则,重置游戏
|
||||
chess.setData(&NineChess::RULES[ruleNo], stepsLimit, timeLimit);
|
||||
chessTemp = chess;
|
||||
|
||||
// 重置游戏
|
||||
gameReset();
|
||||
|
@ -253,6 +258,21 @@ void GameController::timerEvent(QTimerEvent *event)
|
|||
*/
|
||||
}
|
||||
|
||||
// 历史局面
|
||||
void GameController::phaseChange(int row, bool change /*= false*/)
|
||||
{
|
||||
int rows = manualListModel.rowCount();
|
||||
QStringList mlist = manualListModel.stringList();
|
||||
qDebug() << "rows: " << rows;
|
||||
for (int i = 0; i <= row; i++)
|
||||
{
|
||||
qDebug() << mlist.at(i);
|
||||
chessTemp.command(mlist.at(i).toStdString().c_str());
|
||||
}
|
||||
|
||||
updateScence(chessTemp);
|
||||
}
|
||||
|
||||
// 槽函数,根据QGraphicsScene的信号和状态来执行选子、落子或去子
|
||||
bool GameController::actionPiece(QPointF pos)
|
||||
{
|
||||
|
@ -300,12 +320,13 @@ bool GameController::actionPiece(QPointF pos)
|
|||
if (result)
|
||||
{
|
||||
int row = manualListModel.rowCount();
|
||||
int size = chess.getCmdList()->size();
|
||||
auto i = (chess.getCmdList())->rbegin();
|
||||
int c = 0;
|
||||
// 输出命令行
|
||||
for (int n = size - row; n > 0; n--) {
|
||||
manualListModel.insertRow(row);
|
||||
manualListModel.setData(manualListModel.index(row), (*(i++)).c_str());
|
||||
for (auto i = (chess.getCmdList())->begin(); i != (chess.getCmdList())->end(); ++i) {
|
||||
if (++c <= row)
|
||||
continue;
|
||||
manualListModel.insertRow(c - 1);
|
||||
manualListModel.setData(manualListModel.index(c - 1), (*i).c_str());
|
||||
}
|
||||
if (chess.whoWin() != NineChess::NOBODY)
|
||||
playSound(soundWin);
|
||||
|
@ -314,11 +335,6 @@ bool GameController::actionPiece(QPointF pos)
|
|||
return result;
|
||||
}
|
||||
|
||||
// 历史局面
|
||||
void GameController::phaseChange(const QModelIndex &index)
|
||||
{
|
||||
}
|
||||
|
||||
// 选子
|
||||
PieceItem *GameController::choosePiece(QPointF pos)
|
||||
{
|
||||
|
@ -470,7 +486,7 @@ bool GameController::removePiece(QPointF pos)
|
|||
|
||||
bool GameController::cleanForbidden()
|
||||
{
|
||||
foreach(PieceItem *p, pieceList)
|
||||
for (PieceItem *p : pieceList)
|
||||
{
|
||||
if (p->isDeleted()) {
|
||||
pieceList.removeOne(p);
|
||||
|
@ -479,3 +495,46 @@ bool GameController::cleanForbidden()
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameController::updateScence(NineChess &chess)
|
||||
{
|
||||
// 清除棋子
|
||||
qDeleteAll(pieceList);
|
||||
pieceList.clear();
|
||||
piece = NULL;
|
||||
|
||||
const char *board = chess.getBoard();
|
||||
|
||||
for (int i = NineChess::SEAT; i < (NineChess::SEAT)*(NineChess::RING + 1); i++) {
|
||||
QPointF pos = scene.cp2pos(i / NineChess::SEAT, i % NineChess::SEAT + 1);
|
||||
if (board[i] & 0x30) {
|
||||
PieceItem *newP = NULL;
|
||||
PieceItem::Models md;
|
||||
if (isInverted)
|
||||
md = (board[i] & 0x10) ? PieceItem::whitePiece : PieceItem::blackPiece;
|
||||
else
|
||||
md = (board[i] & 0x10) ? PieceItem::blackPiece : PieceItem::whitePiece;
|
||||
newP = new PieceItem;
|
||||
newP->setModel(md);
|
||||
newP->setPos(pos);
|
||||
newP->setNum(chess.getPieceNum(i / NineChess::SEAT, i % NineChess::SEAT + 1));
|
||||
// 如果重复三连不可用,则显示棋子序号
|
||||
if (!(chess.getRule()->canRepeated))
|
||||
newP->setShowNum(true);
|
||||
pieceList.append(newP);
|
||||
scene.addItem(newP);
|
||||
}
|
||||
else if (board[i] & 0x0F) {
|
||||
PieceItem *newP = NULL;
|
||||
newP = new PieceItem;
|
||||
newP->setDeleted();
|
||||
newP->setPos(pos);
|
||||
pieceList.append(newP);
|
||||
scene.addItem(newP);
|
||||
}
|
||||
}
|
||||
|
||||
scene.clearSelection();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
#include <QTextStream>
|
||||
#include <QStringListModel>
|
||||
#include <QModelIndex>
|
||||
#include "gamescene.h"
|
||||
#include "ninechess.h"
|
||||
#include "gamescene.h"
|
||||
//#include "sizehintlistview.h"
|
||||
|
||||
class PieceItem;
|
||||
|
||||
|
@ -29,6 +30,7 @@ public:
|
|||
~GameController();
|
||||
//主窗口菜单栏明细
|
||||
const QMap <int, QStringList> getActions();
|
||||
int getRuleNo() { return ruleNo; }
|
||||
int getTimeLimit() { return timeLimit; }
|
||||
int getStepsLimit() { return stepsLimit; }
|
||||
// 文本流
|
||||
|
@ -45,6 +47,8 @@ signals:
|
|||
void statusBarChanged(const QString & message);
|
||||
|
||||
public slots:
|
||||
// 设置规则
|
||||
void setRule(int ruleNo, int stepLimited = -1, int timeLimited = -1);
|
||||
// 游戏开始
|
||||
void gameStart();
|
||||
// 游戏重置
|
||||
|
@ -53,8 +57,6 @@ public slots:
|
|||
void setEditing(bool arg = true);
|
||||
// 设置黑白反转状态
|
||||
void setInvert(bool arg = true);
|
||||
// 设置规则
|
||||
void setRule(int ruleNo, int stepLimited = -1, int timeLimited = -1);
|
||||
// 让电脑执先手
|
||||
void setEngine1(bool arg = true);
|
||||
// 让电脑执后手
|
||||
|
@ -67,11 +69,12 @@ public slots:
|
|||
void playSound(QString &soundPath);
|
||||
// 根据QGraphicsScene的信号和状态来执行选子、落子或去子
|
||||
bool actionPiece(QPointF p);
|
||||
// 历史局面
|
||||
void phaseChange(const QModelIndex &index);
|
||||
// 历史局面及局面改变
|
||||
void phaseChange(int row, bool change = false);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject * watched, QEvent * event);
|
||||
// 定时器
|
||||
void timerEvent(QTimerEvent * event);
|
||||
// 选子
|
||||
PieceItem *choosePiece(QPointF pos);
|
||||
|
@ -83,12 +86,18 @@ protected:
|
|||
bool removePiece(QPointF pos);
|
||||
// 删除禁止点子
|
||||
bool cleanForbidden();
|
||||
// 更新棋局显示
|
||||
bool updateScence(NineChess &chess);
|
||||
|
||||
private:
|
||||
// 棋对象的数据模型
|
||||
NineChess chess;
|
||||
// 棋对象的数据模型(临时)
|
||||
NineChess chessTemp;
|
||||
// 棋局的场景类
|
||||
GameScene &scene;
|
||||
// 棋谱列表
|
||||
//SizeHintListView &listView;
|
||||
// 所有棋子
|
||||
QList<PieceItem *> pieceList;
|
||||
// 当前棋子
|
||||
|
@ -109,6 +118,8 @@ private:
|
|||
bool hasSound;
|
||||
// 定时器ID
|
||||
int timeID;
|
||||
// 规则变化
|
||||
int ruleNo;
|
||||
// 规则限时(分钟)
|
||||
int timeLimit;
|
||||
// 规则限步数
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "gamescene.h"
|
||||
#include "gamescene.h"
|
||||
#include "pieceitem.h"
|
||||
#include "boarditem.h"
|
||||
#include <QGraphicsItem>
|
||||
|
@ -50,7 +50,7 @@ void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
|||
}
|
||||
|
||||
// 取消其它棋子的选中状态
|
||||
//foreach (QGraphicsItem * item, selectedItems())
|
||||
//for (QGraphicsItem * item: selectedItems())
|
||||
//{
|
||||
// item->setSelected(false);
|
||||
//}
|
||||
|
@ -81,12 +81,17 @@ void GameScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
|||
}
|
||||
}
|
||||
|
||||
QPointF GameScene::cp2pos(int c, int p)
|
||||
{
|
||||
return board->cp2pos(c, p);
|
||||
}
|
||||
|
||||
bool GameScene::pos2cp(QPointF pos, int &c, int &p)
|
||||
{
|
||||
return board->pos2cp(pos, c, p);
|
||||
}
|
||||
|
||||
void GameScene::setDiagonal(bool arg)
|
||||
void GameScene::setDiagonal(bool arg /*= true*/)
|
||||
{
|
||||
if (board)
|
||||
board->setDiagonal(arg);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef GAMESCENE_H
|
||||
#ifndef GAMESCENE_H
|
||||
#define GAMESCENE_H
|
||||
|
||||
#include <QGraphicsScene>
|
||||
|
@ -11,6 +11,8 @@ class GameScene : public QGraphicsScene
|
|||
public:
|
||||
explicit GameScene(QObject *parent = nullptr);
|
||||
~GameScene();
|
||||
// 将模型的圈、位转化为落子点坐标
|
||||
QPointF cp2pos(int c, int p);
|
||||
// 将落子点坐标转化为模型用的圈、位
|
||||
bool pos2cp(QPointF pos, int &c, int &p);
|
||||
// 设置棋盘斜线
|
||||
|
|
|
@ -130,7 +130,9 @@ bool NineChess::setData(const struct Rule *rule, int s, int t, int step, int fla
|
|||
this->rule.maxTime = t;
|
||||
// 设置步数
|
||||
this->step = step;
|
||||
|
||||
// 设置状态
|
||||
|
||||
// 局面阶段标识
|
||||
if (flags & GAME_NOTSTARTED)
|
||||
phase = GAME_NOTSTARTED;
|
||||
|
@ -327,9 +329,72 @@ void NineChess::getData(struct Rule &rule, int &step, int &chess, const char *&b
|
|||
num_NeedRemove = this->num_NeedRemove;
|
||||
}
|
||||
|
||||
const char * NineChess::getBoard()
|
||||
{
|
||||
return board;
|
||||
}
|
||||
|
||||
bool NineChess::reset()
|
||||
{
|
||||
return setData(&rule);
|
||||
if (phase == GAME_NOTSTARTED && player1_MS == player2_MS == 0)
|
||||
return true;
|
||||
|
||||
// 步数归零
|
||||
step = 0;
|
||||
|
||||
// 局面阶段标识
|
||||
phase = GAME_NOTSTARTED;
|
||||
|
||||
// 轮流状态标识
|
||||
turn = PLAYER1;
|
||||
|
||||
// 动作状态标识
|
||||
action = ACTION_PLACE;
|
||||
|
||||
// 胜负标识
|
||||
winner = NOBODY;
|
||||
|
||||
// 当前棋局(3×8)
|
||||
memset(board, 0, sizeof(board));
|
||||
|
||||
// 盘面子数归零
|
||||
player1_Remain = player2_Remain = 0;
|
||||
|
||||
// 设置玩家盘面剩余子数和未放置子数
|
||||
player1_InHand = player2_InHand = rule.numOfChess;
|
||||
|
||||
// 设置去子状态时的剩余尚待去除子数
|
||||
num_NeedRemove = 0;
|
||||
|
||||
// 清空成三记录
|
||||
millList.clear();
|
||||
|
||||
// 不选中棋子
|
||||
posOfSelected = 0;
|
||||
|
||||
// 用时置零
|
||||
player1_MS = player2_MS = 0;
|
||||
|
||||
// 提示
|
||||
setTip();
|
||||
|
||||
// 计棋谱
|
||||
cmdlist.clear();
|
||||
int i;
|
||||
for (i = 0; i < RULENUM; i++) {
|
||||
if (strcmp(this->rule.name, RULES[i].name) == 0)
|
||||
break;
|
||||
}
|
||||
if (sprintf(cmdline, "r%1u s%03u t%02u", i + 1, rule.maxSteps, rule.maxTime) > 0) {
|
||||
cmdlist.push_back(string(cmdline));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
cmdline[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NineChess::start()
|
||||
|
@ -362,9 +427,13 @@ int NineChess::cp2pos(int c, int p)
|
|||
|
||||
bool NineChess::place(int c, int p, long time_p /* = -1*/)
|
||||
{
|
||||
// 如果局面为"未开局"或“结局”,返回false
|
||||
if (phase == GAME_NOTSTARTED || phase == GAME_OVER)
|
||||
// 如果局面为“结局”,返回false
|
||||
if (phase == GAME_OVER)
|
||||
return false;
|
||||
// 如果局面为“未开局”,则开具
|
||||
if (phase == GAME_NOTSTARTED)
|
||||
start();
|
||||
|
||||
// 如非“落子”状态,返回false
|
||||
if (action != ACTION_PLACE)
|
||||
return false;
|
||||
|
|
|
@ -102,6 +102,8 @@ public:
|
|||
|
||||
// 获取棋局状态和棋盘数据
|
||||
void getData(struct Rule &rule, int &step, int &flags, const char *&boardsource, int &p1_InHand, int &p2_InHand, int &num_NeedRemove);
|
||||
// 获取棋盘数据
|
||||
const char *getBoard();
|
||||
// 获取当前规则
|
||||
const struct Rule *getRule() { return &rule; }
|
||||
// 获取当前步数
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#if _MSC_VER >= 1600
|
||||
#pragma execution_character_set("utf-8")
|
||||
#endif
|
||||
#include "ninechesswindow.h"
|
||||
#include "gamecontroller.h"
|
||||
#include "gamescene.h"
|
||||
#include <QDesktopServices>
|
||||
#include <QMap>
|
||||
#include <QMessageBox>
|
||||
|
@ -19,6 +16,10 @@
|
|||
#include <QHelpEvent>
|
||||
#include <QToolTip>
|
||||
#include <QDebug>
|
||||
#include "ninechesswindow.h"
|
||||
#include "gamecontroller.h"
|
||||
#include "gamescene.h"
|
||||
#include "graphicsconst.h"
|
||||
|
||||
NineChessWindow::NineChessWindow(QWidget *parent)
|
||||
: QMainWindow(parent),
|
||||
|
@ -36,6 +37,9 @@ NineChessWindow::NineChessWindow(QWidget *parent)
|
|||
|
||||
// 设置场景
|
||||
scene = new GameScene(this);
|
||||
// 设置场景尺寸大小为棋盘大小的1.08倍
|
||||
scene->setSceneRect(-BOARD_SIZE * 0.54, -BOARD_SIZE * 0.54, BOARD_SIZE*1.08, BOARD_SIZE*1.08);
|
||||
|
||||
// 初始化各个控件
|
||||
|
||||
// 关联视图和场景
|
||||
|
@ -81,7 +85,6 @@ NineChessWindow::~NineChessWindow()
|
|||
if (game != NULL)
|
||||
delete game;
|
||||
qDeleteAll(ruleActionList);
|
||||
;
|
||||
}
|
||||
|
||||
bool NineChessWindow::eventFilter(QObject *watched, QEvent *event)
|
||||
|
@ -142,8 +145,6 @@ 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
|
||||
|
@ -169,15 +170,12 @@ void NineChessWindow::initialize()
|
|||
|
||||
// 默认第2号规则
|
||||
ruleNo = 2;
|
||||
|
||||
// 设置选中当前规则的菜单项
|
||||
ruleActionList.at(ruleNo)->setChecked(true);
|
||||
|
||||
// 重置游戏规则
|
||||
game->setRule(ruleNo);
|
||||
// 规则提示
|
||||
//QString tip_Rule = QString("%1\n%2").arg(tr(NineChess::RULES[ruleNo].name))
|
||||
// .arg(tr(NineChess::RULES[ruleNo].info));
|
||||
// 更新规则显示
|
||||
ruleInfo();
|
||||
|
||||
// 关联列表视图和字符串列表模型
|
||||
ui.listView->setModel(& game->manualListModel);
|
||||
|
@ -201,11 +199,33 @@ void NineChessWindow::initialize()
|
|||
on_actionRowChange();
|
||||
}
|
||||
|
||||
void NineChessWindow::ruleInfo()
|
||||
{
|
||||
int s = game->getStepsLimit();
|
||||
int t = game->getTimeLimit();
|
||||
QString tl(" 不限时");
|
||||
QString sl(" 不限步");
|
||||
if (s > 0)
|
||||
sl = " 限" + QString::number(s) + "步";
|
||||
if (t > 0)
|
||||
tl = " 限时" + QString::number(s) + "分";
|
||||
|
||||
// 规则显示
|
||||
ui.labelRule->setText(tl + sl);
|
||||
// 规则提示
|
||||
ui.labelInfo->setToolTip(QString(NineChess::RULES[ruleNo].name) + "\n" +
|
||||
NineChess::RULES[ruleNo].info);
|
||||
ui.labelRule->setToolTip(ui.labelInfo->toolTip());
|
||||
|
||||
//QString tip_Rule = QString("%1\n%2").arg(tr(NineChess::RULES[ruleNo].name))
|
||||
// .arg(tr(NineChess::RULES[ruleNo].info));
|
||||
}
|
||||
|
||||
void NineChessWindow::actionRules_triggered()
|
||||
{
|
||||
// setChecked函数会发出toggled信号,在这里响应toggled信号会陷入死循环
|
||||
// 取消其它规则的选择
|
||||
foreach(QAction *action, ruleActionList)
|
||||
for(QAction *action: ruleActionList)
|
||||
action->setChecked(false);
|
||||
// 选择当前规则
|
||||
QAction *action = dynamic_cast<QAction *>(sender());
|
||||
|
@ -213,9 +233,8 @@ void NineChessWindow::actionRules_triggered()
|
|||
ruleNo = action->data().toInt();
|
||||
// 重置游戏规则
|
||||
game->setRule(ruleNo);
|
||||
// 规则提示
|
||||
//QString tip_Rule = QString("%1\n%2").arg(tr(NineChess::RULES[ruleNo].name))
|
||||
// .arg(tr(NineChess::RULES[ruleNo].info));
|
||||
// 更新规则显示
|
||||
ruleInfo();
|
||||
}
|
||||
|
||||
|
||||
|
@ -292,45 +311,56 @@ void NineChessWindow::on_actionInvert_I_toggled(bool arg1)
|
|||
// 前后招的公共槽
|
||||
void NineChessWindow::on_actionRowChange()
|
||||
{
|
||||
QModelIndex index = ui.listView->currentIndex();
|
||||
int row = index.row();
|
||||
QAbstractItemModel * model = ui.listView->model();
|
||||
int rows = model->rowCount();
|
||||
int currentRow = ui.listView->currentIndex().row();
|
||||
|
||||
QObject * const obsender = this->sender();
|
||||
QObject * const obsender = sender();
|
||||
if (obsender != NULL) {
|
||||
if (obsender == (QObject *)ui.actionBegin_S) {
|
||||
ui.listView->setCurrentIndex(ui.listView->model()->index(0, 0));
|
||||
ui.listView->setCurrentIndex(model->index(0, 0));
|
||||
}
|
||||
else if (obsender == (QObject *)ui.actionPrevious_B) {
|
||||
if (row > 0) {
|
||||
ui.listView->setCurrentIndex(ui.listView->model()->index(row - 1, 0));
|
||||
if (currentRow > 0) {
|
||||
ui.listView->setCurrentIndex(model->index(currentRow - 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));
|
||||
if (currentRow < rows - 1) {
|
||||
ui.listView->setCurrentIndex(model->index(currentRow + 1, 0));
|
||||
}
|
||||
}
|
||||
else if (obsender == (QObject *)ui.actionEnd_E) {
|
||||
ui.listView->setCurrentIndex(ui.listView->model()->index(ui.listView->model()->rowCount() - 1, 0));
|
||||
ui.listView->setCurrentIndex(model->index(rows - 1, 0));
|
||||
}
|
||||
|
||||
currentRow = ui.listView->currentIndex().row();
|
||||
}
|
||||
|
||||
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) {
|
||||
// 更新动作状态
|
||||
if (rows <= 1) {
|
||||
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);
|
||||
}
|
||||
else {
|
||||
if (currentRow <= 0) {
|
||||
ui.actionBegin_S->setEnabled(false);
|
||||
ui.actionPrevious_B->setEnabled(false);
|
||||
ui.actionNext_F->setEnabled(true);
|
||||
ui.actionEnd_E->setEnabled(true);
|
||||
}
|
||||
if (currentRow >= rows - 1)
|
||||
{
|
||||
ui.actionBegin_S->setEnabled(true);
|
||||
ui.actionPrevious_B->setEnabled(true);
|
||||
ui.actionNext_F->setEnabled(false);
|
||||
ui.actionEnd_E->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新局面
|
||||
game->phaseChange(currentRow);
|
||||
}
|
||||
|
||||
void NineChessWindow::on_actionAutoRun_A_toggled(bool arg1)
|
||||
|
@ -413,6 +443,10 @@ void NineChessWindow::on_actionLimited_T_triggered()
|
|||
// 重置游戏规则
|
||||
game->setRule(ruleNo, stepLimited, timeLimited);
|
||||
}
|
||||
|
||||
// 更新规则显示
|
||||
ruleInfo();
|
||||
|
||||
// 删除对话框,子控件会一并删除
|
||||
delete dialog;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ private:
|
|||
int ruleNo;
|
||||
// 文件
|
||||
QFile file;
|
||||
// 更新规则标签
|
||||
void ruleInfo();
|
||||
|
||||
private slots:
|
||||
// 初始化
|
||||
|
|
|
@ -30,10 +30,14 @@ signals:
|
|||
// 需要一个currentChanged信号,但默认没有,需要把这个槽改造成信号
|
||||
void currentChangedSignal(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
protected:
|
||||
protected slots:
|
||||
// 屏蔽掉双击编辑功能
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) {}
|
||||
// 插入新行后自动选中最后一个
|
||||
|
||||
/* 本来重载rowsInserted函数用于在插入新行后自动选中最后一行,
|
||||
但是,在关联Model的insertRow执行后rowsInserted会被立即执行,
|
||||
此时,Model的setData还未被执行,会选中一个空行。
|
||||
所以不再采用这种方式,而是在控制模块中指定。
|
||||
void rowsInserted(const QModelIndex &parent, int start, int end) {
|
||||
// 调用父类函数,为使滚动条更新,否则scrollToBottom不能正确执行。
|
||||
QListView::rowsInserted(parent, start, end);
|
||||
|
@ -41,6 +45,21 @@ protected:
|
|||
setCurrentIndex(id);
|
||||
scrollToBottom();
|
||||
}
|
||||
*/
|
||||
|
||||
// 采用判断最后一个元素是否改变来选中之
|
||||
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
|
||||
const QVector<int> &roles = QVector<int>()) {
|
||||
QAbstractItemView::dataChanged(topLeft, bottomRight, roles);
|
||||
QModelIndex index = model()->index(model()->rowCount() - 1, 0);
|
||||
if (topLeft == bottomRight) {
|
||||
if (index == bottomRight) {
|
||||
setCurrentIndex(index);
|
||||
scrollToBottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 需要一个currentChanged信号,但默认没有,需要把这个槽改造成信号
|
||||
// activated信号需要按下回车才发出,selectedChanged和clicked信号也不合适
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
|
||||
|
|
Loading…
Reference in New Issue