1 Star 1 Fork 0

modory/中国象棋

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
dialog.cpp 28.71 KB
一键复制 编辑 原始数据 按行查看 历史
PikaCat 提交于 4年前 . 优化代码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
#include "dialog.h"
#include "pikachess.hpp"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) {
ui->setupUi(this);
this->initDialog();
this->initChess();
}
void Dialog::initDialog() {
//安装标题栏按钮事件监控
ui->CloseButton->installEventFilter(this);
ui->MinButton->installEventFilter(this);
//设置无边框窗口
setWindowFlag(Qt::FramelessWindowHint);
//设置窗口透明
setAttribute(Qt::WA_TranslucentBackground);
//设置窗口在屏幕正中央显示
auto desk = QApplication::primaryScreen()->geometry();
move((desk.width() - this->width()) / 2,
(desk.height() - this->height()) / 2);
//窗口启动动画
QPropertyAnimation *ani = new QPropertyAnimation(this, "windowOpacity");
ani->setDuration(600);
ani->setStartValue(0);
ani->setEndValue(0.94);
ani->setEasingCurve(QEasingCurve::InOutSine);
ani->start(QPropertyAnimation::DeleteWhenStopped);
//设置窗口阴影
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect;
shadow->setOffset(0, 0);
shadow->setColor(QColor(0, 0, 0, 50));
shadow->setBlurRadius(10);
ui->frame->setGraphicsEffect(shadow);
}
void Dialog::initChess() {
//安装棋盘事件监控
ui->ChessBoard->installEventFilter(this);
//安装mask2事件监控
ui->Mask2->installEventFilter(this);
//安装所有的棋子事件监控
ui->RedChe1->installEventFilter(this);
ui->RedChe2->installEventFilter(this);
ui->RedMa1->installEventFilter(this);
ui->RedMa2->installEventFilter(this);
ui->RedPao1->installEventFilter(this);
ui->RedPao2->installEventFilter(this);
ui->RedBing1->installEventFilter(this);
ui->RedBing2->installEventFilter(this);
ui->RedBing3->installEventFilter(this);
ui->RedBing4->installEventFilter(this);
ui->RedBing5->installEventFilter(this);
ui->RedShi1->installEventFilter(this);
ui->RedShi2->installEventFilter(this);
ui->RedXiang1->installEventFilter(this);
ui->RedXiang2->installEventFilter(this);
ui->RedJiang->installEventFilter(this);
ui->BlackJiang->installEventFilter(this);
ui->BlackChe1->installEventFilter(this);
ui->BlackChe2->installEventFilter(this);
ui->BlackMa1->installEventFilter(this);
ui->BlackMa2->installEventFilter(this);
ui->BlackPao1->installEventFilter(this);
ui->BlackPao2->installEventFilter(this);
ui->BlackBing1->installEventFilter(this);
ui->BlackBing2->installEventFilter(this);
ui->BlackBing3->installEventFilter(this);
ui->BlackBing4->installEventFilter(this);
ui->BlackBing5->installEventFilter(this);
ui->BlackShi1->installEventFilter(this);
ui->BlackShi2->installEventFilter(this);
ui->BlackXiang1->installEventFilter(this);
ui->BlackXiang2->installEventFilter(this);
//不可视化mask
ui->Mask1->setVisible(false);
ui->Mask2->setVisible(false);
ui->Mask3->setVisible(false);
//初始化指针数组
mLabelPointers = {
{ui->BlackChe1, ui->BlackMa1, ui->BlackXiang1, ui->BlackShi1,
ui->BlackJiang, ui->BlackShi2, ui->BlackXiang2, ui->BlackMa2,
ui->BlackChe2},
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr},
{nullptr, ui->BlackPao1, nullptr, nullptr, nullptr, nullptr, nullptr,
ui->BlackPao2, nullptr},
{ui->BlackBing1, nullptr, ui->BlackBing2, nullptr, ui->BlackBing3,
nullptr, ui->BlackBing4, nullptr, ui->BlackBing5},
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr},
{ui->RedBing1, nullptr, ui->RedBing2, nullptr, ui->RedBing3, nullptr,
ui->RedBing4, nullptr, ui->RedBing5},
{nullptr, ui->RedPao1, nullptr, nullptr, nullptr, nullptr, nullptr,
ui->RedPao2, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr},
{ui->RedChe1, ui->RedMa1, ui->RedXiang1, ui->RedShi1, ui->RedJiang,
ui->RedShi2, ui->RedXiang2, ui->RedMa2, ui->RedChe2}};
//设置走棋动画的部分参数
mChessMoveAni->setEasingCurve(QEasingCurve::InOutCubic);
mChessEatAni->setEasingCurve(QEasingCurve::InOutCubic);
mComputerMoveAni->setEasingCurve(QEasingCurve::InOutCubic);
mMaskAni->setTargetObject(ui->Mask3);
mMaskAni->setEasingCurve(QEasingCurve::InOutCubic);
//注册类型
qRegisterMetaType<uint16_t>("uint16_t");
//走棋动画走完要清空已经选中的子并让电脑走子
connect(mChessMoveAni, &QPropertyAnimation::finished, [&] {
mSelected = nullptr;
computerMove();
});
//吃子吃完要将被吃的子力设置为不可见
connect(mChessEatAni, &QPropertyAnimation::finished, [&] {
mSelected = nullptr;
mTarget->setVisible(false);
mTarget = nullptr;
computerMove();
});
//连接电脑计算完成信号和走子槽函数
connect(this, &Dialog::threadOK, this, &Dialog::makeMove);
//连接电脑走子后的处理槽函数
connect(mComputerMoveAni, &QPropertyAnimation::finished, [&] {
//如果是吃子走法,要将对方的子力设置为不可见
if (mTarget) {
mTarget->setVisible(false);
}
mSelected = nullptr;
mTarget = nullptr;
// 走完了,解锁
this->setMoving(false);
});
// 初始化引擎
init();
}
Dialog::~Dialog() { delete ui; }
//重写关闭事件实现窗口关闭动画
void Dialog::closeEvent(QCloseEvent *event) {
if (this->mCloseCheck == false) {
this->mCloseCheck = true;
event->ignore();
//窗口关闭动画
QPropertyAnimation *ani = new QPropertyAnimation(this, "windowOpacity");
ani->setDuration(600);
ani->setStartValue(0.94);
ani->setEndValue(0);
ani->setEasingCurve(QEasingCurve::InOutSine);
ani->start(QPropertyAnimation::DeleteWhenStopped);
connect(ani, &QPropertyAnimation::finished, this, &Dialog::close);
} else {
event->accept();
}
}
//重写鼠标移动事件,实现点击窗口任意处移动窗口的功能
void Dialog::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
this->mOnDialog = true;
this->mMouseStartPoint = event->globalPosition().toPoint();
this->mDialogStartPoint = this->frameGeometry().topLeft();
}
}
void Dialog::mouseMoveEvent(QMouseEvent *event) {
if (event->buttons() == Qt::LeftButton && this->mOnDialog) {
QPoint MouseMoveDelta =
event->globalPosition().toPoint() - this->mMouseStartPoint;
this->move(this->mDialogStartPoint + MouseMoveDelta);
} else {
//单击按住按钮后离开按钮区域,按钮回复原样
this->mColorClose = QColor(212, 64, 39, 0);
QString qssClose = QString("#CloseButton{border-image:url(:/Images/"
"close.ico);border-radius:5px;background: "
"rgba(212,64,39,0);}#CloseButton:pressed{border-"
"image:url(:/Images/close_press.ico);}");
ui->CloseButton->setStyleSheet(qssClose);
this->mColorMin = QColor(38, 169, 218, 0);
QString qssMin = QString("#MinButton{border-image:url(:/Images/"
"min.ico);border-radius:5px;background: "
"rgba(38,169,218,0);}#MinButton:pressed{border-"
"image:url(:/Images/min_press.bmp);}");
ui->MinButton->setStyleSheet(qssMin);
}
}
void Dialog::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
this->mOnDialog = false;
}
}
//实现按Esc键关闭窗口时也能播放动画
void Dialog::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_Escape) {
this->close();
}
}
//标题栏按钮动画
bool Dialog::eventFilter(QObject *watched, QEvent *event) {
//关闭按钮点燃效果
if (watched == ui->CloseButton) {
if (event->type() == QEvent::Enter) {
QPropertyAnimation *ani = new QPropertyAnimation(this, "ColorClose");
ani->setDuration(100);
ani->setStartValue(getColorClose());
ani->setEndValue(QColor(212, 64, 39, 230));
ani->start(QPropertyAnimation::DeleteWhenStopped);
return true;
}
if (event->type() == QEvent::Leave) {
QPropertyAnimation *ani = new QPropertyAnimation(this, "ColorClose");
ani->setDuration(100);
ani->setStartValue(getColorClose());
ani->setEndValue(QColor(212, 64, 39, 0));
ani->start(QPropertyAnimation::DeleteWhenStopped);
return true;
}
}
//最小化按钮点燃效果
if (watched == ui->MinButton) {
if (event->type() == QEvent::Enter) {
QPropertyAnimation *ani = new QPropertyAnimation(this, "ColorMin");
ani->setDuration(100);
ani->setStartValue(getColorMin());
ani->setEndValue(QColor(38, 169, 218, 230));
ani->start(QPropertyAnimation::DeleteWhenStopped);
return true;
}
if (event->type() == QEvent::Leave) {
QPropertyAnimation *ani = new QPropertyAnimation(this, "ColorMin");
ani->setDuration(100);
ani->setStartValue(getColorMin());
ani->setEndValue(QColor(38, 169, 218, 0));
ani->start(QPropertyAnimation::DeleteWhenStopped);
return true;
}
}
//将棋子和操作连接起来
if (!this->mOnMoving and event->type() == QEvent::MouseButtonPress and
this->isChess(watched)) {
mTarget = dynamic_cast<QLabel *>(watched);
if (mSelected != nullptr and mSelected->text() != mTarget->text()) {
//吃子时要改动指针数组和棋盘
uint16_t nowRow = (mSelected->y() - ui->ChessBoard->y() - 10) / 80,
nowCol = (mSelected->x() - ui->ChessBoard->x() - 10) / 80,
destRow = (mTarget->y() - ui->ChessBoard->y() - 10) / 80,
destCol = (mTarget->x() - ui->ChessBoard->x() - 10) / 80;
if (this->mIsFliped) {
nowRow = 9 - nowRow;
nowCol = 8 - nowCol;
destRow = 9 - destRow;
destCol = 8 - destCol;
}
if (not this->canMove(mapTo256({nowRow, nowCol, destRow, destCol}))) {
event->ignore();
return true;
}
// 可以走,先把棋子锁上
this->setMoving(true);
// 走子
this->playerMakeMove({nowRow, nowCol, destRow, destCol});
//隐藏mask
ui->Mask1->setVisible(false);
ui->Mask2->setVisible(false);
ui->Mask3->setVisible(false);
//移动mask
ui->Mask2->move(mSelected->x(), mSelected->y());
ui->Mask3->move(mSelected->x(), mSelected->y());
ui->Mask2->setVisible(true);
ui->Mask3->setVisible(true);
// Mask3动画
mMaskAni->setStartValue(QRect(ui->Mask3->x(), ui->Mask3->y(),
ui->Mask3->width(), ui->Mask3->height()));
mMaskAni->setEndValue(QRect(mTarget->x(), mTarget->y(),
ui->Mask3->width(), ui->Mask3->height()));
mMaskAni->start();
//吃子做动画
mChessEatAni->setTargetObject(mSelected);
mChessEatAni->setStartValue(QRect(mSelected->x(), mSelected->y(),
mSelected->width(),
mSelected->height()));
mChessEatAni->setEndValue(QRect(mTarget->x(), mTarget->y(),
mSelected->width(), mSelected->height()));
mChessEatAni->start();
} else {
//在选棋时不是自己方的不让选
if (mTarget->text() == (COMPUTER_SIDE ? "r" : "b")) {
mSelected = mTarget;
mSelected->raise();
if (ui->Mask1->isVisible()) {
QPropertyAnimation *maskAni =
new QPropertyAnimation(ui->Mask1, "geometry");
maskAni->setEasingCurve(QEasingCurve::InOutCubic);
maskAni->setStartValue(QRect(ui->Mask1->x(), ui->Mask1->y(),
ui->Mask1->width(),
ui->Mask1->height()));
maskAni->setEndValue(QRect(mSelected->x(), mSelected->y(),
ui->Mask1->width(), ui->Mask1->height()));
maskAni->start(QPropertyAnimation::DeleteWhenStopped);
} else {
ui->Mask1->move(mSelected->x(), mSelected->y());
ui->Mask1->setVisible(true);
}
}
}
return true;
}
//走棋
if (!this->mOnMoving and mSelected != nullptr and
event->type() == QEvent::MouseButtonPress and
(watched == ui->ChessBoard or watched == ui->Mask2)) {
//获取棋盘左上角的坐标
QPoint global = ui->ChessBoard->mapToGlobal(QPoint(0, 0));
//加上10等于第一个黑车左上角的位置,用该位置来获取要走到哪里去
global.setX(global.x() + 10);
global.setY(global.y() + 10);
//获取要去的位置相对第一个黑车坐标
QPoint relativePos{QCursor::pos() - global};
//走棋时要改动指针数组和棋盘
uint16_t nowRow = (mSelected->y() - ui->ChessBoard->y() - 10) / 80,
nowCol = (mSelected->x() - ui->ChessBoard->x() - 10) / 80,
destRow = relativePos.y() / 80, destCol = relativePos.x() / 80;
if (this->mIsFliped) {
nowRow = 9 - nowRow;
nowCol = 8 - nowCol;
destRow = 9 - destRow;
destCol = 8 - destCol;
}
if (not this->canMove(mapTo256({nowRow, nowCol, destRow, destCol}))) {
event->ignore();
return true;
}
// 可以走,先把棋子锁上
this->setMoving(true);
// 走子后不能再改变边
ui->PlayerSide->setDisabled(true);
this->playerMakeMove({nowRow, nowCol, destRow, destCol});
// 计算精确的相对黑车的坐标
QPoint destPos{relativePos.x() / 80 * 80, relativePos.y() / 80 * 80};
// 算出相对棋盘第一个黑车位置的相对坐标后
// 加上第一个黑车相对窗口左上角的坐标就可以得到要去的位置了
destPos.setX(ui->ChessBoard->x() + 10 + destPos.x());
destPos.setY(ui->ChessBoard->y() + 10 + destPos.y());
// 隐藏mask
ui->Mask1->setVisible(false);
ui->Mask2->setVisible(false);
ui->Mask3->setVisible(false);
// 移动mask
ui->Mask2->move(mSelected->x(), mSelected->y());
ui->Mask3->move(mSelected->x(), mSelected->y());
ui->Mask2->setVisible(true);
ui->Mask3->setVisible(true);
// Mask3动画
mMaskAni->setStartValue(QRect(ui->Mask3->x(), ui->Mask3->y(),
ui->Mask3->width(), ui->Mask3->height()));
mMaskAni->setEndValue(QRect(destPos.x(), destPos.y(), ui->Mask3->width(),
ui->Mask3->height()));
mMaskAni->start();
// 做动画
mChessMoveAni->setTargetObject(mSelected);
mChessMoveAni->setStartValue(QRect(mSelected->x(), mSelected->y(),
mSelected->width(),
mSelected->height()));
mChessMoveAni->setEndValue(QRect(destPos.x(), destPos.y(),
mSelected->width(), mSelected->height()));
mChessMoveAni->start();
return true;
}
return false;
}
// 获取关闭按钮颜色
QColor Dialog::getColorClose() const { return this->mColorClose; }
// 设置关闭按钮颜色
void Dialog::setColorClose(const QColor color) {
this->mColorClose = color;
QString qss =
QString("#CloseButton{border-image:url(:/Images/"
"close.ico);border-radius:5px;background: rgba(%1, %2, %3, "
"%4);}#CloseButton:pressed{border-image:url(:/Images/"
"close_press.ico);}")
.arg(color.red())
.arg(color.green())
.arg(color.blue())
.arg(color.alpha());
ui->CloseButton->setStyleSheet(qss);
}
//获得最小化按钮颜色
QColor Dialog::getColorMin() const { return this->mColorMin; }
//设置最小化按钮颜色
void Dialog::setColorMin(const QColor color) {
this->mColorMin = color;
QString qss =
QString(
"#MinButton{border-image:url(:/Images/"
"min.ico);border-radius:5px;background: rgba(%1, %2, %3, "
"%4);}#MinButton:pressed{border-image:url(:/Images/min_press.bmp);}")
.arg(color.red())
.arg(color.green())
.arg(color.blue())
.arg(color.alpha());
ui->MinButton->setStyleSheet(qss);
}
//窗口按钮事件
void Dialog::on_CloseButton_clicked() { this->close(); }
void Dialog::on_MinButton_clicked() { this->showMinimized(); }
//选择红黑槽
void Dialog::on_PlayerSide_currentIndexChanged(int index) {
ui->PlayerSide->setDisabled(true);
COMPUTER_SIDE = index ? RED : BLACK;
//电脑红子
if (COMPUTER_SIDE == RED) {
//如果棋盘没翻转,那么翻转一下
if (!this->mIsFliped) {
on_Flip_clicked();
QEventLoop eventLoop;
QTimer::singleShot(600, &eventLoop, &QEventLoop::quit);
eventLoop.exec();
}
//电脑走红子,先行棋
computerMove();
}
}
// 电脑难度选择
void Dialog::on_ComputerHard_currentIndexChanged(int index) {
// 电脑每一步至少搜索多长时间(单位:毫秒)
switch (index) {
case 0:
SEARCH_TIME = 1000;
break;
case 1:
SEARCH_TIME = 3000;
break;
default:
SEARCH_TIME = 6000;
}
}
// 翻转按钮点击槽函数
void Dialog::on_Flip_clicked() {
this->setMoving(true);
// 翻转不需要锁难度按钮
ui->HardSelectionBox->setDisabled(false);
for (uint16_t row = 0; row < 10; ++row)
for (uint16_t col = 0; col < 9; ++col) {
QLabel *target = mLabelPointers[row][col];
if (target) {
QPropertyAnimation *moveAni = new QPropertyAnimation(this, "geometry");
moveAni->setTargetObject(target);
moveAni->setEasingCurve(QEasingCurve::InOutCubic);
moveAni->setDuration(600);
moveAni->setStartValue(
QRect(target->x(), target->y(), target->width(), target->height()));
if (this->mIsFliped) {
//已经翻转了,现在要翻回去
moveAni->setEndValue(QRect(30 + 80 * col, 90 + 80 * row,
target->width(), target->height()));
} else {
//还没有翻转,现在翻转
moveAni->setEndValue(QRect(670 - 80 * col, 810 - 80 * row,
target->width(), target->height()));
}
moveAni->start(QPropertyAnimation::DeleteWhenStopped);
}
}
QPropertyAnimation *moveAni1 = new QPropertyAnimation(this, "geometry");
QPropertyAnimation *moveAni2 = new QPropertyAnimation(this, "geometry");
QPropertyAnimation *moveAni3 = new QPropertyAnimation(this, "geometry");
moveAni1->setTargetObject(ui->Mask1);
moveAni1->setEasingCurve(QEasingCurve::InOutCubic);
moveAni1->setDuration(600);
moveAni1->setStartValue(QRect(ui->Mask1->x(), ui->Mask1->y(),
ui->Mask1->width(), ui->Mask1->height()));
moveAni2->setTargetObject(ui->Mask2);
moveAni2->setEasingCurve(QEasingCurve::InOutCubic);
moveAni2->setDuration(600);
moveAni2->setStartValue(QRect(ui->Mask2->x(), ui->Mask2->y(),
ui->Mask2->width(), ui->Mask2->height()));
moveAni3->setTargetObject(ui->Mask3);
moveAni3->setEasingCurve(QEasingCurve::InOutCubic);
moveAni3->setDuration(600);
moveAni3->setStartValue(QRect(ui->Mask3->x(), ui->Mask3->y(),
ui->Mask3->width(), ui->Mask3->height()));
if (this->mIsFliped) {
//已经翻转了,现在要翻回去
moveAni1->setEndValue(QRect(700 - ui->Mask1->x(), 900 - ui->Mask1->y(),
ui->Mask1->width(), ui->Mask1->height()));
moveAni2->setEndValue(QRect(700 - ui->Mask2->x(), 900 - ui->Mask2->y(),
ui->Mask2->width(), ui->Mask2->height()));
moveAni3->setEndValue(QRect(700 - ui->Mask3->x(), 900 - ui->Mask3->y(),
ui->Mask3->width(), ui->Mask3->height()));
} else {
//还没有翻转,现在翻转
moveAni1->setEndValue(QRect(700 - ui->Mask1->x(), 900 - ui->Mask1->y(),
ui->Mask1->width(), ui->Mask1->height()));
moveAni2->setEndValue(QRect(700 - ui->Mask2->x(), 900 - ui->Mask2->y(),
ui->Mask2->width(), ui->Mask2->height()));
moveAni3->setEndValue(QRect(700 - ui->Mask3->x(), 900 - ui->Mask3->y(),
ui->Mask3->width(), ui->Mask3->height()));
}
connect(moveAni3, &QPropertyAnimation::finished,
[&] { this->setMoving(false); });
moveAni1->start(QPropertyAnimation::DeleteWhenStopped);
moveAni2->start(QPropertyAnimation::DeleteWhenStopped);
moveAni3->start(QPropertyAnimation::DeleteWhenStopped);
this->mIsFliped = !this->mIsFliped;
}
// 重置棋盘槽函数
void Dialog::on_Reset_clicked() {
this->setMoving(true);
// 重置不需要锁难度
ui->HardSelectionBox->setDisabled(false);
// 重置局面信息
::init();
// 重启边选择器
ui->PlayerSide->setCurrentIndex(0);
ui->PlayerSide->setDisabled(false);
// 重置云开局库标志
ui->ComputerScore->setText(QString::fromLocal8Bit("云库出步"));
ui->ComputerScore->setStyleSheet("font:40px;color:green;");
ui->ComputerScoreBox->setTitle(QString::fromLocal8Bit("中国象棋云库"));
// 重置isFliped标志
this->mIsFliped = false;
// 设置mask为不可见
ui->Mask1->setVisible(false);
ui->Mask2->setVisible(false);
ui->Mask3->setVisible(false);
// 重置指针数组
mLabelPointers = {
{ui->BlackChe1, ui->BlackMa1, ui->BlackXiang1, ui->BlackShi1,
ui->BlackJiang, ui->BlackShi2, ui->BlackXiang2, ui->BlackMa2,
ui->BlackChe2},
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr},
{nullptr, ui->BlackPao1, nullptr, nullptr, nullptr, nullptr, nullptr,
ui->BlackPao2, nullptr},
{ui->BlackBing1, nullptr, ui->BlackBing2, nullptr, ui->BlackBing3,
nullptr, ui->BlackBing4, nullptr, ui->BlackBing5},
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr},
{ui->RedBing1, nullptr, ui->RedBing2, nullptr, ui->RedBing3, nullptr,
ui->RedBing4, nullptr, ui->RedBing5},
{nullptr, ui->RedPao1, nullptr, nullptr, nullptr, nullptr, nullptr,
ui->RedPao2, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr},
{ui->RedChe1, ui->RedMa1, ui->RedXiang1, ui->RedShi1, ui->RedJiang,
ui->RedShi2, ui->RedXiang2, ui->RedMa2, ui->RedChe2}};
QVector<QPropertyAnimation *> tempVector;
for (uint16_t row = 0; row < 10; ++row) {
for (uint16_t col = 0; col < 9; ++col) {
QLabel *target = mLabelPointers[row][col];
if (target) {
target->setVisible(true);
QPropertyAnimation *moveAni = new QPropertyAnimation(this, "geometry");
moveAni->setTargetObject(target);
moveAni->setEasingCurve(QEasingCurve::InOutCubic);
moveAni->setDuration(600);
moveAni->setStartValue(
QRect(target->x(), target->y(), target->width(), target->height()));
moveAni->setEndValue(QRect(30 + 80 * col, 90 + 80 * row,
target->width(), target->height()));
moveAni->start(QPropertyAnimation::DeleteWhenStopped);
tempVector.emplaceBack(moveAni);
}
}
}
connect(tempVector.last(), &QPropertyAnimation::finished,
[&] { this->setMoving(false); });
}
void Dialog::makeMove(Step step) {
auto [nowRow, nowCol, destRow, destCol] = step;
//隐藏所有mask
ui->Mask1->setVisible(false);
ui->Mask2->setVisible(false);
ui->Mask3->setVisible(false);
mLabelPointers[nowRow][nowCol]->raise();
mTarget = mLabelPointers[destRow][destCol];
mSelected = mLabelPointers[nowRow][nowCol];
//移动mask
ui->Mask2->move(mSelected->x(), mSelected->y());
ui->Mask3->move(mSelected->x(), mSelected->y());
ui->Mask2->setVisible(true);
ui->Mask3->setVisible(true);
// Mask3动画
mMaskAni->setStartValue(QRect(ui->Mask3->x(), ui->Mask3->y(),
ui->Mask3->width(), ui->Mask3->height()));
//做动画
mComputerMoveAni->setTargetObject(mSelected);
mComputerMoveAni->setStartValue(QRect(
mSelected->x(), mSelected->y(), mSelected->width(), mSelected->height()));
if (this->mIsFliped) {
mComputerMoveAni->setEndValue(
QRect(ui->ChessBoard->x() + 10 + (8 - destCol) * 80,
ui->ChessBoard->y() + 10 + (9 - destRow) * 80, mSelected->width(),
mSelected->height()));
mMaskAni->setEndValue(QRect(ui->ChessBoard->x() + 10 + (8 - destCol) * 80,
ui->ChessBoard->y() + 10 + (9 - destRow) * 80,
ui->Mask3->width(), ui->Mask3->height()));
} else {
mComputerMoveAni->setEndValue(QRect(ui->ChessBoard->x() + 10 + destCol * 80,
ui->ChessBoard->y() + 10 + destRow * 80,
mSelected->width(),
mSelected->height()));
mMaskAni->setEndValue(QRect(ui->ChessBoard->x() + 10 + destCol * 80,
ui->ChessBoard->y() + 10 + destRow * 80,
ui->Mask3->width(), ui->Mask3->height()));
}
mMaskAni->start();
mComputerMoveAni->start();
mLabelPointers[destRow][destCol] = mLabelPointers[nowRow][nowCol];
mLabelPointers[nowRow][nowCol] = nullptr;
}
void Dialog::computerMove() {
QFuture future{QtConcurrent::run([&] {
const auto &[bookOK, step] = POSITION_INFO.searchBook();
if (bookOK == QString::fromLocal8Bit("云库出步")) {
ui->ComputerScoreBox->setTitle(QString::fromLocal8Bit("中国象棋云库"));
ui->ComputerScore->setStyleSheet("font:40px;color:green;");
ui->ComputerScore->setText(bookOK);
POSITION_INFO.makeMove(mapTo256(step), COMPUTER_SIDE);
emit threadOK(step);
} else {
Score score = searchMain();
// 显示MetaInfo
ui->ComputerScoreBox->setTitle(QString::fromLocal8Bit("电脑局面分"));
// 根据情况设置字体颜色
if (score > 0) {
ui->ComputerScore->setStyleSheet("font:40px;color:green;");
} else if (score < 0) {
ui->ComputerScore->setStyleSheet("font:40px;color:red;");
} else {
ui->ComputerScore->setStyleSheet("font:40px;");
}
// 根据分数写提示
if (score == 999) {
// 提示电脑胜利
ui->ComputerScore->setText(QString::fromLocal8Bit("电脑获胜"));
// 电脑赢了
} else if (score == -999) {
// 提示玩家胜利
ui->ComputerScore->setText(QString::fromLocal8Bit("玩家获胜"));
// 电脑输了,禁止玩家下棋,并且电脑不能再走了
return;
} else if (score > WIN_SCORE) {
// 如果电脑快赢了
ui->ComputerScore->setText(
QString::number((MATE_SCORE - score - 1) / 2) +
QString::fromLocal8Bit("步获胜"));
} else if (score < LOST_SCORE) {
// 如果电脑快输了
ui->ComputerScore->setText(QString::number((score - LOSS_SCORE) / 2) +
QString::fromLocal8Bit("步落败"));
} else {
ui->ComputerScore->setText(
QString::fromLocal8Bit("[") + QString::number(CURRENT_DEPTH - 1) +
QString::fromLocal8Bit("层]") + QString::number(score));
}
emit threadOK(mapToStep(POSITION_INFO.mBestMove));
}
})};
}
inline bool Dialog::isChess(const QObject *object) {
return object == ui->RedChe1 or object == ui->RedChe2 or
object == ui->RedMa1 or object == ui->RedMa2 or
object == ui->RedPao1 or object == ui->RedPao2 or
object == ui->RedBing1 or object == ui->RedBing2 or
object == ui->RedBing3 or object == ui->RedBing4 or
object == ui->RedBing5 or object == ui->RedXiang1 or
object == ui->RedXiang2 or object == ui->RedShi1 or
object == ui->RedShi2 or object == ui->RedJiang or
object == ui->BlackJiang or object == ui->BlackShi1 or
object == ui->BlackShi2 or object == ui->BlackXiang1 or
object == ui->BlackXiang2 or object == ui->BlackBing1 or
object == ui->BlackBing2 or object == ui->BlackBing3 or
object == ui->BlackBing4 or object == ui->BlackBing5 or
object == ui->BlackPao1 or object == ui->BlackPao2 or
object == ui->BlackMa1 or object == ui->BlackMa2 or
object == ui->BlackChe1 or object == ui->BlackChe2;
}
inline bool Dialog::canMove(const Move move) {
bool canMove{false};
// 如果不是合法的步,就不给走
if (POSITION_INFO.isLegalMove(move, getOppSide(COMPUTER_SIDE))) {
// 试着走一下,看是否被将军
canMove = POSITION_INFO.makeMove(move, getOppSide(COMPUTER_SIDE));
if (canMove) {
// 如果能走就还原,不能走的话已经在makeMove函数里面还原了,没必要再还原
POSITION_INFO.unMakeMove(move, getOppSide(COMPUTER_SIDE));
}
}
return canMove;
}
inline void Dialog::playerMakeMove(const Step &step) {
auto &[nowRow, nowCol, destRow, destCol] = step;
POSITION_INFO.makeMove(this->mapTo256(step), getOppSide(COMPUTER_SIDE));
// 标签也要跟着走
this->mLabelPointers[destRow][destCol] = this->mLabelPointers[nowRow][nowCol];
this->mLabelPointers[nowRow][nowCol] = nullptr;
}
inline Move Dialog::mapTo256(const Step &step) {
const auto &[fromX, fromY, toX, toY] = step;
// 算出具体的位置
return toMove(51 + fromX * 16 + fromY, 51 + toX * 16 + toY);
}
inline Step Dialog::mapToStep(const Move move) {
return {getSrc(move) / 16 - 3, getSrc(move) % 16 - 3, getDest(move) / 16 - 3,
getDest(move) % 16 - 3};
}
inline void Dialog::setMoving(const bool isMoving) {
this->mOnMoving = isMoving;
if (isMoving) {
// 如果GUI正在播放动画或电脑正在思考,界面三个按钮禁止点击
ui->HardSelectionBox->setDisabled(true);
ui->Reset->setDisabled(true);
ui->Flip->setDisabled(true);
} else {
// 否则恢复界面三个按钮的点击
ui->HardSelectionBox->setDisabled(false);
ui->Reset->setDisabled(false);
ui->Flip->setDisabled(false);
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/modory/ChineseChess.git
git@gitee.com:modory/ChineseChess.git
modory
ChineseChess
中国象棋
master

搜索帮助