调整代码格式
This commit is contained in:
parent
ffac849fac
commit
be80990f93
|
@ -54,6 +54,7 @@ void AiThread::run()
|
|||
|
||||
while (!isInterruptionRequested()) {
|
||||
mutex.lock();
|
||||
|
||||
if (chess_->whosTurn() == NineChess::PLAYER1)
|
||||
i = 1;
|
||||
else if (chess_->whosTurn() == NineChess::PLAYER2)
|
||||
|
@ -74,11 +75,14 @@ void AiThread::run()
|
|||
ai_ab.alphaBetaPruning(aiDepth);
|
||||
const char *str = ai_ab.bestMove();
|
||||
qDebug() << "Computer:" << str << "\n";
|
||||
|
||||
if (strcmp(str, "error!"))
|
||||
emit command(str);
|
||||
|
||||
#ifdef DEBUG
|
||||
qDebug() << "Thread" << id << "run" << ++iTemp << "times";
|
||||
#endif
|
||||
|
||||
emit calcFinished();
|
||||
|
||||
// 执行完毕后继续判断
|
||||
|
|
|
@ -3,40 +3,41 @@
|
|||
#include <QPainter>
|
||||
|
||||
BoardItem::BoardItem(QGraphicsItem *parent) : QGraphicsItem(),
|
||||
size(BOARD_SIZE),
|
||||
sizeShadow(5.0),
|
||||
hasObliqueLine(false)
|
||||
size(BOARD_SIZE),
|
||||
sizeShadow(5.0),
|
||||
hasObliqueLine(false)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
// 棋盘中心放在场景中心
|
||||
setPos(0, 0);
|
||||
|
||||
// 初始化24个落子点
|
||||
for (int i = 0; i < RING; i++) {
|
||||
for (int i = 0; i < N_RINGS; 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;
|
||||
position[i * N_SEATS + 0].rx() = 0;
|
||||
position[i * N_SEATS + 0].ry() = -a;
|
||||
position[i * N_SEATS + 1].rx() = a;
|
||||
position[i * N_SEATS + 1].ry() = -a;
|
||||
position[i * N_SEATS + 2].rx() = a;
|
||||
position[i * N_SEATS + 2].ry() = 0;
|
||||
position[i * N_SEATS + 3].rx() = a;
|
||||
position[i * N_SEATS + 3].ry() = a;
|
||||
position[i * N_SEATS + 4].rx() = 0;
|
||||
position[i * N_SEATS + 4].ry() = a;
|
||||
position[i * N_SEATS + 5].rx() = -a;
|
||||
position[i * N_SEATS + 5].ry() = a;
|
||||
position[i * N_SEATS + 6].rx() = -a;
|
||||
position[i * N_SEATS + 6].ry() = 0;
|
||||
position[i * N_SEATS + 7].rx() = -a;
|
||||
position[i * N_SEATS + 7].ry() = -a;
|
||||
}
|
||||
}
|
||||
|
||||
BoardItem::~BoardItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QRectF BoardItem::boundingRect() const
|
||||
|
@ -57,19 +58,19 @@ void BoardItem::setDiagonal(bool arg)
|
|||
update(boundingRect());
|
||||
}
|
||||
|
||||
|
||||
void BoardItem::paint(QPainter *painter,
|
||||
const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
Q_UNUSED(widget)
|
||||
|
||||
// 填充阴影
|
||||
painter->fillRect(boundingRect(), QBrush(QColor(64, 64, 64)));
|
||||
|
||||
// 填充图片
|
||||
painter->drawPixmap(-size / 2, -size / 2, size, size, QPixmap(":/image/resources/image/board.png"));
|
||||
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);
|
||||
|
@ -78,25 +79,26 @@ void BoardItem::paint(QPainter *painter,
|
|||
// 空画刷
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
|
||||
for (int i = 0; i < RING; i++) {
|
||||
for (uint8_t i = 0; i < N_RINGS; i++) {
|
||||
// 画3个方框
|
||||
painter->drawPolygon(position + i * SEAT, SEAT);
|
||||
painter->drawPolygon(position + i * N_SEATS, N_SEATS);
|
||||
}
|
||||
|
||||
// 画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]);
|
||||
painter->drawLine(position[0], position[(N_RINGS - 1) * N_SEATS]);
|
||||
painter->drawLine(position[2], position[(N_RINGS - 1) * N_SEATS + 2]);
|
||||
painter->drawLine(position[4], position[(N_RINGS - 1) * N_SEATS + 4]);
|
||||
painter->drawLine(position[6], position[(N_RINGS - 1) * N_SEATS + 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]);
|
||||
painter->drawLine(position[1], position[(N_RINGS - 1) * N_SEATS + 1]);
|
||||
painter->drawLine(position[3], position[(N_RINGS - 1) * N_SEATS + 3]);
|
||||
painter->drawLine(position[5], position[(N_RINGS - 1) * N_SEATS + 5]);
|
||||
painter->drawLine(position[7], position[(N_RINGS - 1) * N_SEATS + 7]);
|
||||
}
|
||||
|
||||
#ifdef DRAW_SEAT_NUMBER
|
||||
// 画 Seat 编号
|
||||
QPen fontPen(QBrush(Qt::white), LINE_WEIGHT, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin);
|
||||
painter->setPen(fontPen);
|
||||
|
@ -109,8 +111,9 @@ void BoardItem::paint(QPainter *painter,
|
|||
for (int i = 0; i < 8; i++) {
|
||||
char cSeat = '1' + i;
|
||||
QString strSeat(cSeat);
|
||||
painter->drawText(position[(RING - 1) * SEAT + i], strSeat);
|
||||
painter->drawText(position[(N_RINGS - 1) * N_SEATS + i], strSeat);
|
||||
}
|
||||
#endif // DRAW_SEAT_NUMBER
|
||||
}
|
||||
|
||||
QPointF BoardItem::nearestPosition(QPointF const pos)
|
||||
|
@ -119,7 +122,7 @@ QPointF BoardItem::nearestPosition(QPointF const pos)
|
|||
QPointF nearestPos = QPointF(0, 0);
|
||||
|
||||
// 寻找最近的落子点
|
||||
for (int i = 0; i < RING * SEAT; i++) {
|
||||
for (int i = 0; i < N_RINGS * N_SEATS; i++) {
|
||||
// 如果鼠标点距离落子点在棋子半径内
|
||||
if (QLineF(pos, position[i]).length() < PIECE_SIZE / 2) {
|
||||
nearestPos = position[i];
|
||||
|
@ -131,17 +134,17 @@ QPointF BoardItem::nearestPosition(QPointF const pos)
|
|||
|
||||
QPointF BoardItem::cp2pos(int c, int p)
|
||||
{
|
||||
return position[(c - 1) * SEAT + p - 1];
|
||||
return position[(c - 1) * N_SEATS + p - 1];
|
||||
}
|
||||
|
||||
bool BoardItem::pos2cp(QPointF pos, int &c, int &p)
|
||||
{
|
||||
// 寻找最近的落子点
|
||||
for (int i = 0; i < RING * SEAT; i++) {
|
||||
for (int i = 0; i < N_RINGS * N_SEATS; i++) {
|
||||
// 如果pos点在落子点附近
|
||||
if (QLineF(pos, position[i]).length() < PIECE_SIZE / 6) {
|
||||
c = i / SEAT + 1;
|
||||
p = i % SEAT + 1;
|
||||
c = i / N_SEATS + 1;
|
||||
p = i % N_SEATS + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,11 @@ class BoardItem : public QGraphicsItem
|
|||
public:
|
||||
explicit BoardItem(QGraphicsItem *parent = nullptr);
|
||||
~BoardItem();
|
||||
|
||||
QRectF boundingRect() const;
|
||||
|
||||
QPainterPath shape() const;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QWidget *widget = nullptr);
|
||||
|
||||
|
@ -40,10 +43,10 @@ public:
|
|||
bool pos2cp(QPointF pos, int &c, int &p);
|
||||
|
||||
// 3圈,禁止修改!
|
||||
static const int RING = 3;
|
||||
static const uint8_t N_RINGS = 3;
|
||||
|
||||
// 8位,禁止修改!
|
||||
static const int SEAT = 8;
|
||||
static const uint8_t N_SEATS = 8;
|
||||
|
||||
private:
|
||||
// 棋盘尺寸
|
||||
|
@ -53,7 +56,7 @@ private:
|
|||
qreal sizeShadow;
|
||||
|
||||
// 24个落子点
|
||||
QPointF position[RING * SEAT];
|
||||
QPointF position[N_RINGS * N_SEATS];
|
||||
|
||||
// 是否有斜线
|
||||
bool hasObliqueLine;
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
//#define AB_RANDOM_SORT_CHILDREN
|
||||
|
||||
// 调试博弈树 (耗费大量内存)
|
||||
#define DEBUG_AB_TREE
|
||||
//#define DEBUG_AB_TREE
|
||||
|
||||
// »æÖÆ SEAT ±àºÅ
|
||||
#define DRAW_SEAT_NUMBER
|
||||
|
||||
#endif // CONFIG_H
|
|
@ -48,7 +48,8 @@ GameController::GameController(GameScene & scene, QObject * parent) :
|
|||
connect(&ai2, SIGNAL(command(const QString &, bool)),
|
||||
this, SLOT(command(const QString &, bool)));
|
||||
|
||||
// 安装事件过滤器监视scene的各个事件,由于我重载了QGraphicsScene,相关事件在重载函数中已设定,不必安装监视器。
|
||||
// 安装事件过滤器监视scene的各个事件,
|
||||
// 由于我重载了QGraphicsScene,相关事件在重载函数中已设定,不必安装监视器。
|
||||
//scene.installEventFilter(this);
|
||||
}
|
||||
|
||||
|
@ -70,6 +71,7 @@ const QMap<int, QStringList> GameController::getActions()
|
|||
// 主窗口更新菜单栏
|
||||
// 之所以不用信号和槽的模式,是因为发信号的时候槽还来不及关联
|
||||
QMap<int, QStringList> actions;
|
||||
|
||||
for (int i = 0; i < NineChess::N_RULES; i++) {
|
||||
// QMap的key存放int索引值,value存放规则名称和规则提示
|
||||
QStringList strlist;
|
||||
|
@ -77,6 +79,7 @@ const QMap<int, QStringList> GameController::getActions()
|
|||
strlist.append(tr(NineChess::RULES[i].description));
|
||||
actions.insert(i, strlist);
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
@ -223,6 +226,7 @@ void GameController::setRule(int ruleNo, int stepLimited /*= -1*/, int timeLimit
|
|||
stepsLimit = stepLimited;
|
||||
timeLimit = timeLimited;
|
||||
}
|
||||
|
||||
// 设置模型规则,重置游戏
|
||||
chess_.setContext(&NineChess::RULES[ruleNo], stepsLimit, timeLimit);
|
||||
chessTemp = chess_;
|
||||
|
@ -368,6 +372,7 @@ void GameController::mirror()
|
|||
|
||||
// 更新棋谱
|
||||
int row = 0;
|
||||
|
||||
for (auto str : *(chess_.getCmdList())) {
|
||||
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
||||
}
|
||||
|
@ -382,9 +387,11 @@ void GameController::mirror()
|
|||
|
||||
ai1.setAi(chess_);
|
||||
ai2.setAi(chess_);
|
||||
|
||||
if (isEngine1) {
|
||||
ai1.start();
|
||||
}
|
||||
|
||||
if (isEngine2) {
|
||||
ai2.start();
|
||||
}
|
||||
|
@ -407,6 +414,7 @@ void GameController::turnRight()
|
|||
|
||||
// 更新棋谱
|
||||
int row = 0;
|
||||
|
||||
for (auto str : *(chess_.getCmdList())) {
|
||||
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
||||
}
|
||||
|
@ -419,9 +427,11 @@ void GameController::turnRight()
|
|||
|
||||
ai1.setAi(chess_);
|
||||
ai2.setAi(chess_);
|
||||
|
||||
if (isEngine1) {
|
||||
ai1.start();
|
||||
}
|
||||
|
||||
if (isEngine2) {
|
||||
ai2.start();
|
||||
}
|
||||
|
@ -478,6 +488,7 @@ void GameController::timerEvent(QTimerEvent *event)
|
|||
|
||||
qt1 = QTime(0, 0, 0, 0).addMSecs(remainingTime1);
|
||||
qt2 = QTime(0, 0, 0, 0).addMSecs(remainingTime2);
|
||||
|
||||
emit time1Changed(qt1.toString("mm:ss.zzz"));
|
||||
emit time2Changed(qt2.toString("mm:ss.zzz"));
|
||||
|
||||
|
@ -557,6 +568,7 @@ bool GameController::actionPiece(QPointF pos)
|
|||
|
||||
// 如果再决出胜负后悔棋,则重新启动计时
|
||||
if (chess_.whoWin() == NineChess::NOBODY) {
|
||||
|
||||
// 重新启动计时
|
||||
timeID = startTimer(100);
|
||||
|
||||
|
@ -591,7 +603,7 @@ bool GameController::actionPiece(QPointF pos)
|
|||
break;
|
||||
}
|
||||
|
||||
// 如果移子不成功,尝试重新选子,这里不break
|
||||
// 如果移子不成功,尝试重新选子,这里不break
|
||||
|
||||
case NineChess::ACTION_CHOOSE:
|
||||
piece = qgraphicsitem_cast<PieceItem *>(item);
|
||||
|
@ -687,6 +699,7 @@ bool GameController::giveUp()
|
|||
// 将新增的棋谱行插入到ListModel
|
||||
currentRow = manualListModel.rowCount() - 1;
|
||||
int k = 0;
|
||||
|
||||
// 输出命令行
|
||||
for (auto i = (chess_.getCmdList())->begin(); i != (chess_.getCmdList())->end(); ++i) {
|
||||
// 跳过已添加的,因标准list容器没有下标
|
||||
|
@ -698,6 +711,7 @@ bool GameController::giveUp()
|
|||
if (chess_.whoWin() != NineChess::NOBODY)
|
||||
playSound(":/sound/resources/sound/loss.wav");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -706,14 +720,16 @@ bool GameController::command(const QString &cmd, bool update /*= true*/)
|
|||
{
|
||||
Q_UNUSED(hasSound)
|
||||
|
||||
// 防止接收滞后结束的线程发送的指令
|
||||
if (sender() == &ai1 && !isEngine1)
|
||||
return false;
|
||||
// 防止接收滞后结束的线程发送的指令
|
||||
if (sender() == &ai1 && !isEngine1)
|
||||
return false;
|
||||
|
||||
if (sender() == &ai2 && !isEngine2)
|
||||
return false;
|
||||
|
||||
// 声音
|
||||
QString sound;
|
||||
|
||||
switch (chess_.getAction()) {
|
||||
case NineChess::ACTION_CHOOSE:
|
||||
case NineChess::ACTION_PLACE:
|
||||
|
|
|
@ -29,14 +29,14 @@ GameScene::~GameScene()
|
|||
}
|
||||
|
||||
// 屏蔽掉Shift和Control按键,事实证明没用,按键事件未必由视图类处理
|
||||
/*
|
||||
#if 0
|
||||
void GameScene::keyPressEvent(QKeyEvent *keyEvent)
|
||||
{
|
||||
if(keyEvent->key() == Qt::Key_Shift || keyEvent->key() == Qt::Key_Control)
|
||||
return;
|
||||
QGraphicsScene::keyPressEvent(keyEvent);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
void GameScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
|
@ -47,9 +47,10 @@ void GameScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
|||
|
||||
void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
//屏蔽鼠标按下事件
|
||||
// 屏蔽鼠标按下事件
|
||||
mouseEvent->accept();
|
||||
/*
|
||||
|
||||
#if 0
|
||||
// 只处理左键事件
|
||||
if(mouseEvent->button() != Qt::LeftButton)
|
||||
return;
|
||||
|
@ -62,7 +63,7 @@ void GameScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
|||
|
||||
// 调用默认事件处理函数
|
||||
//QGraphicsScene::mousePressEvent(mouseEvent);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
void GameScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
|
|
|
@ -31,9 +31,11 @@ void GameView::flip()
|
|||
* │0 -1 0│
|
||||
* └0 0 1┘
|
||||
*/
|
||||
|
||||
// 方法一: 直接在原变换矩阵基础上乘以上面的矩阵
|
||||
// QMatrix只对变换矩阵前两列赋值
|
||||
setMatrix(matrix() * QMatrix(1, 0, 0, -1, 0, 0));
|
||||
|
||||
/* 方法二: 人工计算好新的变换矩阵后再对场景赋值
|
||||
* 这个方法的效率未必高,还需要人工计算
|
||||
QMatrix mt = matrix();
|
||||
|
@ -98,6 +100,7 @@ void GameView::resizeEvent(QResizeEvent *event)
|
|||
scale(sx, sy);
|
||||
//qDebug() << "scale :" << sx;
|
||||
*/
|
||||
|
||||
// 使用如下形式,更简洁
|
||||
QGraphicsView::resizeEvent(event);
|
||||
fitInView(sceneRect(), Qt::KeepAspectRatio);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* QListView派生类
|
||||
/*
|
||||
* QListView派生类
|
||||
* 之所以要派生这个类,重载sizeHint函数
|
||||
* 只是为了让停靠栏(父窗口)在初始时不至于过宽难看
|
||||
* QDockWidget没有很好的控制初始大小的方法,resize函数没效果
|
||||
|
@ -25,6 +26,7 @@ public:
|
|||
{
|
||||
Q_UNUSED(parent)
|
||||
}
|
||||
|
||||
QSize sizeHint() const
|
||||
{
|
||||
QSize size = QListView::sizeHint();
|
||||
|
@ -55,10 +57,11 @@ protected slots:
|
|||
newEmptyRow = true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* 本来重载rowsInserted函数用于在插入新行后自动选中最后一行,
|
||||
但是,在关联Model的insertRow执行后rowsInserted会被立即执行,
|
||||
此时,Model的setData还未被执行,会选中一个空行。
|
||||
所以不再采用这种方式,而是在控制模块中指定。
|
||||
所以不再采用这种方式,而是在控制模块中指定。*/
|
||||
void rowsInserted(const QModelIndex &parent, int start, int end) {
|
||||
// 调用父类函数,为使滚动条更新,否则scrollToBottom不能正确执行。
|
||||
QListView::rowsInserted(parent, start, end);
|
||||
|
@ -66,7 +69,7 @@ protected slots:
|
|||
setCurrentIndex(id);
|
||||
scrollToBottom();
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
// 采用判断最后一个元素是否改变来选中之
|
||||
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
|
||||
|
|
|
@ -194,14 +194,17 @@ void NineChess::createMoveTable()
|
|||
for (int s = 0; s < N_SEATS; s++) {
|
||||
// 顺时针走一步的位置
|
||||
moveTable[r * N_SEATS + s][0] = r * N_SEATS + (s + 1) % N_SEATS;
|
||||
|
||||
// 逆时针走一步的位置
|
||||
moveTable[r * N_SEATS + s][1] = r * N_SEATS + (s + N_SEATS - 1) % N_SEATS;
|
||||
|
||||
// 如果是 0、2、4、6位(偶数位)或是有斜线
|
||||
if (!(s & 1) || this->currentRule.hasObliqueLines) {
|
||||
if (r > 1) {
|
||||
// 向内走一步的位置
|
||||
moveTable[r * N_SEATS + s][2] = (r - 1) * N_SEATS + s;
|
||||
}
|
||||
|
||||
if (r < N_RINGS) {
|
||||
// 向外走一步的位置
|
||||
moveTable[r * N_SEATS + s][3] = (r + 1) * N_SEATS + s;
|
||||
|
@ -1210,15 +1213,15 @@ bool NineChess::choose(int pos)
|
|||
uint64_t NineChess::chessHash()
|
||||
{
|
||||
/*
|
||||
hash各数据位详解(名为hash,但实际并无冲突,是算法用到的棋局数据的完全表示)
|
||||
57-64位:空白不用,全为0
|
||||
56位:轮流标识,0为先手,1为后手
|
||||
55位:动作标识,落子(选子移动)为0,1为去子
|
||||
7-54位(共48位):从棋盘第一个位置点到最后一个位置点的棋子,每个点用2个二进制位表示,共24个位置点,即48位。
|
||||
0b00表示空白,0b01表示先手棋子,0b10表示后手棋子,0b11表示禁点
|
||||
5-6位(共2位):待去子数,最大为3,用2个二进制位表示即可
|
||||
1-4位:player1的手棋数,不需要player2的(可计算出)
|
||||
*/
|
||||
* hash各数据位详解(名为hash,但实际并无冲突,是算法用到的棋局数据的完全表示)
|
||||
* 57-64位:空白不用,全为0
|
||||
* 56位:轮流标识,0为先手,1为后手
|
||||
* 55位:动作标识,落子(选子移动)为0,1为去子
|
||||
* 7-54位(共48位):从棋盘第一个位置点到最后一个位置点的棋子,每个点用2个二进制位表示,共24个位置点,即48位。
|
||||
* 0b00表示空白,0b01表示先手棋子,0b10表示后手棋子,0b11表示禁点
|
||||
* 5-6位(共2位):待去子数,最大为3,用2个二进制位表示即可
|
||||
* 1-4位:player1的手棋数,不需要player2的(可计算出)
|
||||
*/
|
||||
uint64_t hash = 0ull;
|
||||
|
||||
for (int i = N_SEATS; i < (N_RINGS + 1) * N_SEATS; i++) {
|
||||
|
@ -1332,6 +1335,7 @@ bool NineChess::command(int move)
|
|||
} else {
|
||||
return place(move & 0x00ff);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1346,6 +1350,7 @@ inline long NineChess::update(long time_p /*= -1*/)
|
|||
case NineChess::GAME_PLACING:
|
||||
case NineChess::GAME_MOVING:
|
||||
ftime(¤tTimeb);
|
||||
|
||||
// 更新时间
|
||||
if (time_p >= *player_ms) {
|
||||
*player_ms = ret = time_p;
|
||||
|
@ -1361,14 +1366,19 @@ inline long NineChess::update(long time_p /*= -1*/)
|
|||
*player_ms = ret = (long)(currentTimeb.time - startTimeb.time) * 1000
|
||||
+ (currentTimeb.millitm - startTimeb.millitm) - playerNext_ms;
|
||||
}
|
||||
|
||||
// 有限时要求则判断胜负
|
||||
if (currentRule.maxTimeLedToLose > 0)
|
||||
win();
|
||||
|
||||
return ret;
|
||||
|
||||
case NineChess::GAME_NOTSTARTED:
|
||||
return ret;
|
||||
|
||||
case NineChess::GAME_OVER:
|
||||
return ret;
|
||||
|
||||
default:
|
||||
return ret;
|
||||
}
|
||||
|
@ -1640,20 +1650,23 @@ bool NineChess::isAllSurrounded(char ch)
|
|||
bool NineChess::isAllSurrounded(enum Player ply)
|
||||
{
|
||||
char t = '\x30';
|
||||
|
||||
if (ply == PLAYER1)
|
||||
t &= '\x10';
|
||||
else if (ply == PLAYER2)
|
||||
t &= '\x20';
|
||||
|
||||
return isAllSurrounded(t);
|
||||
}
|
||||
|
||||
void NineChess::cleanForbiddenPoints()
|
||||
{
|
||||
for (int i = 1; i <= N_RINGS; i++)
|
||||
for (int i = 1; i <= N_RINGS; i++) {
|
||||
for (int j = 0; j < N_SEATS; j++) {
|
||||
if (board_[i * N_SEATS + j] == '\x0f')
|
||||
board_[i * N_SEATS + j] = '\x00';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum NineChess::Player NineChess::changeTurn()
|
||||
|
@ -1669,6 +1682,7 @@ void NineChess::setTips()
|
|||
case NineChess::GAME_NOTSTARTED:
|
||||
tips = "轮到黑方落子,剩余" + std::to_string(context.nPiecesInHand_1) + "子";
|
||||
break;
|
||||
|
||||
case NineChess::GAME_PLACING:
|
||||
if (context.action == ACTION_PLACE) {
|
||||
if (context.turn == PLAYER1) {
|
||||
|
@ -1684,6 +1698,7 @@ void NineChess::setTips()
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NineChess::GAME_MOVING:
|
||||
if (context.action == ACTION_PLACE || context.action == ACTION_CHOOSE) {
|
||||
if (context.turn == PLAYER1) {
|
||||
|
@ -1699,6 +1714,7 @@ void NineChess::setTips()
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NineChess::GAME_OVER:
|
||||
if (winner == DRAW)
|
||||
tips = "超出限定步数,双方平局";
|
||||
|
@ -1714,6 +1730,7 @@ void NineChess::setTips()
|
|||
tips = "白方获胜!";
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1956,7 +1973,9 @@ void NineChess::turn(bool cmdChange /*= true*/)
|
|||
int args = 0;
|
||||
int mm = 0, ss = 0, mss = 0;
|
||||
|
||||
args = sscanf(cmdline, "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
|
||||
args = sscanf(cmdline, "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u",
|
||||
&c1, &p1, &c2, &p2, &mm, &ss, &mss);
|
||||
|
||||
if (args >= 4) {
|
||||
if (c1 == 1)
|
||||
c1 = N_RINGS;
|
||||
|
@ -1989,7 +2008,10 @@ void NineChess::turn(bool cmdChange /*= true*/)
|
|||
}
|
||||
|
||||
for (auto itor = cmdlist.begin(); itor != cmdlist.end(); itor++) {
|
||||
args = sscanf((*itor).c_str(), "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
|
||||
args = sscanf((*itor).c_str(),
|
||||
"(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u",
|
||||
&c1, &p1, &c2, &p2, &mm, &ss, &mss);
|
||||
|
||||
if (args >= 4) {
|
||||
if (c1 == 1)
|
||||
c1 = N_RINGS;
|
||||
|
@ -2028,6 +2050,7 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
|
|||
{
|
||||
// 将degrees转化为0~359之间的数
|
||||
degrees = degrees % 360;
|
||||
|
||||
if (degrees < 0)
|
||||
degrees += 360;
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ public:
|
|||
// 尚待去除的子数
|
||||
int nPiecesNeedRemove;
|
||||
|
||||
/*
|
||||
#if 0
|
||||
本打算用如下的结构体来表示“三连”
|
||||
struct Mill {
|
||||
char piece1; // “三连”中最小的棋子
|
||||
|
@ -184,7 +184,8 @@ public:
|
|||
但为了提高执行效率改用一个64位整数了,规则如下
|
||||
0x 00 00 00 00 00 00 00 00
|
||||
unused unused piece1 pos1 piece2 pos2 piece3 pos3
|
||||
*/
|
||||
#endif
|
||||
|
||||
// “三连列表”
|
||||
list <uint64_t> millList;
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <QScreen>
|
||||
#include <QDebug>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
#include "ninechesswindow.h"
|
||||
#include "gamecontroller.h"
|
||||
#include "gamescene.h"
|
||||
|
@ -37,17 +38,22 @@ NineChessWindow::NineChessWindow(QWidget * parent) :
|
|||
autoRunTimer(this)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
//去掉标题栏
|
||||
|
||||
// 去掉标题栏
|
||||
//setWindowFlags(Qt::FramelessWindowHint);
|
||||
//设置透明(窗体标题栏不透明,背景透明,如果不去掉标题栏,背景就变为黑色)
|
||||
|
||||
// 设置透明(窗体标题栏不透明,背景透明,如果不去掉标题栏,背景就变为黑色)
|
||||
//setAttribute(Qt::WA_TranslucentBackground);
|
||||
//设置全体透明度系数
|
||||
|
||||
// 设置全体透明度系数
|
||||
//setWindowOpacity(0.7);
|
||||
|
||||
// 设置场景
|
||||
scene = new GameScene(this);
|
||||
|
||||
// 设置场景尺寸大小为棋盘大小的1.08倍
|
||||
scene->setSceneRect(-BOARD_SIZE * 0.54, -BOARD_SIZE * 0.54, BOARD_SIZE * 1.08, BOARD_SIZE * 1.08);
|
||||
scene->setSceneRect(-BOARD_SIZE * 0.54, -BOARD_SIZE * 0.54,
|
||||
BOARD_SIZE * 1.08, BOARD_SIZE * 1.08);
|
||||
|
||||
// 初始化各个控件
|
||||
|
||||
|
@ -87,6 +93,7 @@ NineChessWindow::~NineChessWindow()
|
|||
game->disconnect();
|
||||
game->deleteLater();
|
||||
}
|
||||
|
||||
qDeleteAll(ruleActionList);
|
||||
}
|
||||
|
||||
|
@ -97,7 +104,9 @@ void NineChessWindow::closeEvent(QCloseEvent *event)
|
|||
|
||||
// 取消自动运行
|
||||
ui.actionAutoRun_A->setChecked(false);
|
||||
|
||||
//qDebug() << "closed";
|
||||
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
|
@ -116,6 +125,7 @@ bool NineChessWindow::eventFilter(QObject *watched, QEvent *event)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QMainWindow::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
|
@ -130,6 +140,7 @@ void NineChessWindow::initialize()
|
|||
|
||||
// 添加新菜单栏动作
|
||||
QMap <int, QStringList> actions = game->getActions();
|
||||
|
||||
for (auto i = actions.constBegin(); i != actions.constEnd(); i++) {
|
||||
// qDebug() << i.key() << i.value();
|
||||
// QMap的key存放int索引值,value存放规则名称和规则提示
|
||||
|
@ -151,31 +162,40 @@ void NineChessWindow::initialize()
|
|||
}
|
||||
|
||||
// 关联主窗口动作信号和控制器的槽
|
||||
|
||||
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)));
|
||||
|
||||
connect(ui.actionSound_S, SIGNAL(toggled(bool)),
|
||||
game, SLOT(setSound(bool)));
|
||||
|
||||
connect(ui.actionAnimation_A, SIGNAL(toggled(bool)),
|
||||
game, SLOT(setAnimation(bool)));
|
||||
|
||||
// 视图上下翻转
|
||||
connect(ui.actionFlip_F, &QAction::triggered,
|
||||
game, &GameController::flip);
|
||||
|
||||
// 视图左右镜像
|
||||
connect(ui.actionMirror_M, &QAction::triggered,
|
||||
game, &GameController::mirror);
|
||||
|
||||
// 视图须时针旋转90°
|
||||
connect(ui.actionTurnRight_R, &QAction::triggered,
|
||||
game, &GameController::turnRight);
|
||||
|
||||
// 视图逆时针旋转90°
|
||||
connect(ui.actionTurnLeftt_L, &QAction::triggered,
|
||||
game, &GameController::turnLeft);
|
||||
|
||||
// 关联控制器的信号和主窗口控件的槽
|
||||
|
||||
// 更新LCD1,显示玩家1用时
|
||||
connect(game, SIGNAL(time1Changed(QString)),
|
||||
ui.lcdNumber_1, SLOT(display(QString)));
|
||||
|
@ -211,22 +231,30 @@ void NineChessWindow::initialize()
|
|||
|
||||
// 关联列表视图和字符串列表模型
|
||||
ui.listView->setModel(game->getManualListModel());
|
||||
|
||||
// 因为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, &ManualListView::currentChangedSignal,
|
||||
this, &NineChessWindow::on_actionRowChange);
|
||||
|
||||
// 更新四个键的状态
|
||||
on_actionRowChange();
|
||||
}
|
||||
|
@ -235,8 +263,10 @@ 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)
|
||||
|
@ -244,22 +274,27 @@ void NineChessWindow::ruleInfo()
|
|||
|
||||
// 规则显示
|
||||
ui.labelRule->setText(tl + sl);
|
||||
|
||||
// 规则提示
|
||||
ui.labelInfo->setToolTip(QString(NineChess::RULES[ruleNo].name) + "\n" +
|
||||
NineChess::RULES[ruleNo].description);
|
||||
|
||||
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));
|
||||
#if 0
|
||||
QString tip_Rule = QString("%1\n%2").arg(tr(NineChess::RULES[ruleNo].name))
|
||||
.arg(tr(NineChess::RULES[ruleNo].info));
|
||||
#endif
|
||||
}
|
||||
|
||||
void NineChessWindow::on_actionLimited_T_triggered()
|
||||
{
|
||||
/* 其实本来可以用设计器做个ui,然后从QDialog派生个自己的对话框
|
||||
* 但我不想再派生新类了,又要多出一个类和两个文件
|
||||
* 还要写与主窗口的接口,费劲
|
||||
* 于是手写QDialog界面
|
||||
*/
|
||||
/*
|
||||
* 其实本来可以用设计器做个ui,然后从QDialog派生个自己的对话框
|
||||
* 但我不想再派生新类了,又要多出一个类和两个文件
|
||||
* 还要写与主窗口的接口,费劲
|
||||
* 于是手写QDialog界面
|
||||
*/
|
||||
int gStep = game->getStepsLimit();
|
||||
int gTime = game->getTimeLimit();
|
||||
|
||||
|
@ -270,6 +305,7 @@ void NineChessWindow::on_actionLimited_T_triggered()
|
|||
dialog->setWindowTitle(tr("步数和时间限制"));
|
||||
dialog->resize(256, 108);
|
||||
dialog->setModal(true);
|
||||
|
||||
// 生成各个控件
|
||||
QFormLayout *formLayout = new QFormLayout(dialog);
|
||||
QLabel *label_step = new QLabel(dialog);
|
||||
|
@ -277,13 +313,15 @@ void NineChessWindow::on_actionLimited_T_triggered()
|
|||
QComboBox *comboBox_step = new QComboBox(dialog);
|
||||
QComboBox *comboBox_time = new QComboBox(dialog);
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog);
|
||||
#if 0
|
||||
// 设置各个控件ObjectName,不设也没关系
|
||||
/*formLayout->setObjectName(QStringLiteral("formLayout"));
|
||||
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"));*/
|
||||
buttonBox->setObjectName(QStringLiteral("buttonBox"));
|
||||
#endif
|
||||
// 设置各个控件数据
|
||||
label_step->setText(tr("超出限制步数判和:"));
|
||||
label_time->setText(tr("任意一方超时判负:"));
|
||||
|
@ -357,6 +395,7 @@ void NineChessWindow::actionRules_triggered()
|
|||
|
||||
// 重置游戏规则
|
||||
game->setRule(ruleNo);
|
||||
|
||||
// 更新规则显示
|
||||
ruleInfo();
|
||||
}
|
||||
|
@ -365,11 +404,14 @@ void NineChessWindow::on_actionNew_N_triggered()
|
|||
{
|
||||
if (file.isOpen())
|
||||
file.close();
|
||||
|
||||
// 取消自动运行
|
||||
ui.actionAutoRun_A->setChecked(false);
|
||||
|
||||
// 取消AI设定
|
||||
ui.actionEngine1_T->setChecked(false);
|
||||
ui.actionEngine2_R->setChecked(false);
|
||||
|
||||
// 重置游戏规则
|
||||
game->gameReset();
|
||||
}
|
||||
|
@ -380,26 +422,32 @@ void NineChessWindow::on_actionOpen_O_triggered()
|
|||
if (path.isEmpty() == false) {
|
||||
if (file.isOpen())
|
||||
file.close();
|
||||
//文件对象
|
||||
|
||||
// 文件对象
|
||||
file.setFileName(path);
|
||||
|
||||
// 不支持1MB以上的文件
|
||||
if (file.size() > 0x100000) {
|
||||
// 定义新对话框
|
||||
QMessageBox msgBox(QMessageBox::Warning, tr("文件过大"), tr("不支持1MB以上文件"), QMessageBox::Ok);
|
||||
QMessageBox msgBox(QMessageBox::Warning,
|
||||
tr("文件过大"), tr("不支持1MB以上文件"), QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
//打开文件,只读方式打开
|
||||
// 打开文件,只读方式打开
|
||||
bool isok = file.open(QFileDevice::ReadOnly | QFileDevice::Text);
|
||||
|
||||
if (isok) {
|
||||
// 取消AI设定
|
||||
ui.actionEngine1_T->setChecked(false);
|
||||
ui.actionEngine2_R->setChecked(false);
|
||||
|
||||
// 读文件
|
||||
QTextStream textStream(&file);
|
||||
QString cmd;
|
||||
cmd = textStream.readLine();
|
||||
|
||||
// 读取并显示棋谱时,不必刷新棋局场景
|
||||
if (!(game->command(cmd, false))) {
|
||||
// 定义新对话框
|
||||
|
@ -407,10 +455,12 @@ void NineChessWindow::on_actionOpen_O_triggered()
|
|||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
while (!textStream.atEnd()) {
|
||||
cmd = textStream.readLine();
|
||||
game->command(cmd, false);
|
||||
}
|
||||
|
||||
// 最后刷新棋局场景
|
||||
game->updateScence();
|
||||
}
|
||||
|
@ -421,23 +471,28 @@ void NineChessWindow::on_actionSave_S_triggered()
|
|||
{
|
||||
if (file.isOpen()) {
|
||||
file.close();
|
||||
//打开文件,只写方式打开
|
||||
|
||||
// 打开文件,只写方式打开
|
||||
bool isok = file.open(QFileDevice::WriteOnly | QFileDevice::Text);
|
||||
|
||||
if (isok) {
|
||||
//写文件
|
||||
// 写文件
|
||||
QTextStream textStream(&file);
|
||||
QStringListModel *strlist = qobject_cast<QStringListModel *>(ui.listView->model());
|
||||
for (QString cmd : strlist->stringList())
|
||||
textStream << cmd << endl;
|
||||
file.flush();
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
on_actionSaveAs_A_triggered();
|
||||
}
|
||||
}
|
||||
|
||||
void NineChessWindow::on_actionSaveAs_A_triggered()
|
||||
{
|
||||
QString path = QFileDialog::getSaveFileName(this, tr("打开棋谱文件"), QDir::currentPath() + tr("棋谱.txt"), "TXT(*.txt)");
|
||||
QString path = QFileDialog::getSaveFileName(this,
|
||||
tr("打开棋谱文件"), QDir::currentPath() + tr("棋谱.txt"), "TXT(*.txt)");
|
||||
|
||||
if (path.isEmpty() == false) {
|
||||
if (file.isOpen())
|
||||
file.close();
|
||||
|
@ -447,8 +502,9 @@ void NineChessWindow::on_actionSaveAs_A_triggered()
|
|||
|
||||
// 打开文件,只写方式打开
|
||||
bool isok = file.open(QFileDevice::WriteOnly | QFileDevice::Text);
|
||||
|
||||
if (isok) {
|
||||
//写文件
|
||||
// 写文件
|
||||
QTextStream textStream(&file);
|
||||
QStringListModel *strlist = qobject_cast<QStringListModel *>(ui.listView->model());
|
||||
for (QString cmd : strlist->stringList())
|
||||
|
@ -456,7 +512,6 @@ void NineChessWindow::on_actionSaveAs_A_triggered()
|
|||
file.flush();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NineChessWindow::on_actionEdit_E_toggled(bool arg1)
|
||||
|
@ -480,6 +535,7 @@ void NineChessWindow::on_actionInvert_I_toggled(bool arg1)
|
|||
ui.picLabel1->setPixmap(QPixmap(":/icon/Resources/icon/Black.png"));
|
||||
ui.picLabel2->setPixmap(QPixmap(":/icon/Resources/icon/White.png"));
|
||||
}
|
||||
|
||||
// 让控制器改变棋子颜色
|
||||
game->setInvert(arg1);
|
||||
}
|
||||
|
@ -506,6 +562,7 @@ void NineChessWindow::on_actionRowChange()
|
|||
} else if (obsender == ui.actionEnd_E) {
|
||||
ui.listView->setCurrentIndex(model->index(rows - 1, 0));
|
||||
}
|
||||
|
||||
currentRow = ui.listView->currentIndex().row();
|
||||
}
|
||||
|
||||
|
@ -541,7 +598,8 @@ void NineChessWindow::on_actionRowChange()
|
|||
// 更新局面
|
||||
game->phaseChange(currentRow);
|
||||
|
||||
/* 下面的代码全部取消,改用QTimer的方式实现
|
||||
#if 0
|
||||
// 下面的代码全部取消,改用QTimer的方式实现
|
||||
// 更新局面
|
||||
bool changed = game->phaseChange(currentRow);
|
||||
// 处理自动播放时的动画
|
||||
|
@ -559,7 +617,7 @@ void NineChessWindow::on_actionRowChange()
|
|||
QTimer::singleShot(waitTime, &loop, SLOT(quit()));
|
||||
loop.exec();
|
||||
}
|
||||
*/
|
||||
#endif // 0
|
||||
}
|
||||
|
||||
void NineChessWindow::onAutoRunTimeOut(QPrivateSignal signal)
|
||||
|
@ -578,7 +636,9 @@ void NineChessWindow::onAutoRunTimeOut(QPrivateSignal signal)
|
|||
if (currentRow < rows - 1) {
|
||||
ui.listView->setCurrentIndex(ui.listView->model()->index(currentRow + 1, 0));
|
||||
}
|
||||
|
||||
currentRow = ui.listView->currentIndex().row();
|
||||
|
||||
// 更新动作状态
|
||||
if (currentRow <= 0) {
|
||||
ui.actionBegin_S->setEnabled(false);
|
||||
|
@ -614,11 +674,13 @@ void NineChessWindow::on_actionAutoRun_A_toggled(bool arg1)
|
|||
// 自动运行前禁用控件
|
||||
ui.dockWidget->setEnabled(false);
|
||||
ui.gameView->setEnabled(false);
|
||||
|
||||
// 启动定时器
|
||||
autoRunTimer.start(game->getDurationTime() + 50);
|
||||
} else {
|
||||
// 关闭定时器
|
||||
autoRunTimer.stop();
|
||||
|
||||
// 自动运行结束后启用控件
|
||||
ui.dockWidget->setEnabled(true);
|
||||
ui.gameView->setEnabled(true);
|
||||
|
@ -723,7 +785,10 @@ void NineChessWindow::on_actionEngine_E_triggered()
|
|||
time1_new = spinBox_time1->value();
|
||||
time2_new = spinBox_time2->value();
|
||||
|
||||
if (depth1 != depth1_new || depth2 != depth2_new || time1 != time1_new || time2 != time2_new) {
|
||||
if (depth1 != depth1_new ||
|
||||
depth2 != depth2_new ||
|
||||
time1 != time1_new ||
|
||||
time2 != time2_new) {
|
||||
// 重置AI
|
||||
game->setAiDepthTime(depth1_new, time1_new, depth2_new, time2_new);
|
||||
}
|
||||
|
@ -750,7 +815,7 @@ void NineChessWindow::on_actionAbout_A_triggered()
|
|||
|
||||
dialog->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
dialog->setObjectName(QStringLiteral("aboutDialog"));
|
||||
dialog->setWindowTitle(tr("九连棋"));
|
||||
dialog->setWindowTitle(tr("三棋"));
|
||||
dialog->setModal(true);
|
||||
|
||||
// 生成各个控件
|
||||
|
@ -771,7 +836,7 @@ void NineChessWindow::on_actionAbout_A_triggered()
|
|||
label_icon1->setScaledContents(true);
|
||||
label_icon2->setScaledContents(true);
|
||||
|
||||
label_text->setText(tr("支持开源,捐助作者,诚接软件开发项目 —— liuweilhy"));
|
||||
label_text->setText(tr("Donate"));
|
||||
label_text->setAlignment(Qt::AlignCenter);
|
||||
label_image->setPixmap(QPixmap(QString::fromUtf8(":/image/resources/image/donate.png")));
|
||||
label_image->setAlignment(Qt::AlignCenter);
|
||||
|
|
|
@ -10,6 +10,7 @@ class PieceItem : public QObject, public QGraphicsItem
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QGraphicsItem)
|
||||
|
||||
// 位置属性
|
||||
Q_PROPERTY(QPointF pos READ pos WRITE setPos)
|
||||
|
||||
|
@ -27,6 +28,7 @@ public:
|
|||
{
|
||||
Type = UserType + 2
|
||||
};
|
||||
|
||||
int type() const
|
||||
{
|
||||
return Type;
|
||||
|
@ -44,22 +46,27 @@ public:
|
|||
{
|
||||
return model_;
|
||||
}
|
||||
|
||||
void setModel(enum Models model)
|
||||
{
|
||||
this->model_ = model;
|
||||
}
|
||||
|
||||
int getNum()
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
void setNum(int n)
|
||||
{
|
||||
num = n;
|
||||
}
|
||||
|
||||
bool isDeleted()
|
||||
{
|
||||
return deleted_;
|
||||
}
|
||||
|
||||
void setDeleted(bool deleted = true)
|
||||
{
|
||||
this->deleted_ = deleted;
|
||||
|
@ -67,6 +74,7 @@ public:
|
|||
this->model_ = noPiece;
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void setShowNum(bool show = true)
|
||||
{
|
||||
this->showNum = show;
|
||||
|
|
Loading…
Reference in New Issue