From d5a8a398e3afb73934c3134e6e4b62a9b151afa1 Mon Sep 17 00:00:00 2001 From: PikaCat <760758491@qq.com> Date: Sat, 14 Aug 2021 15:58:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChineseChess.pro.user | 2 +- dialog.cpp | 32 ++++++++++++++++++++++---------- dialog.h | 7 ++++++- pikachess.hpp | 6 ++++-- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ChineseChess.pro.user b/ChineseChess.pro.user index 74344aa..fb69c64 100644 --- a/ChineseChess.pro.user +++ b/ChineseChess.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/dialog.cpp b/dialog.cpp index c61a8a8..d0d679e 100644 --- a/dialog.cpp +++ b/dialog.cpp @@ -130,8 +130,14 @@ void Dialog::initChess() { } mSelected = nullptr; mTarget = nullptr; - // 走完了,解锁 - this->setMoving(false); + // 走完了,看电脑是否已经胜利 + if (this->mComputerWin) { + // 电脑赢了,注意此时isMoving保持为true,这样可以使得棋子不响应玩家的操作 + this->setButtonDisabled(false); + } else { + // 否则就正常回复按钮和isMoving的状态 + this->setMoving(false); + } }); // 初始化引擎 init(); @@ -522,6 +528,8 @@ void Dialog::on_Reset_clicked() { ui->HardSelectionBox->setDisabled(false); // 重置局面信息 ::init(); + // 重置电脑胜利标志 + this->mComputerWin = false; // 重启边选择器 ui->PlayerSide->setCurrentIndex(0); ui->PlayerSide->setDisabled(false); @@ -650,14 +658,14 @@ void Dialog::computerMove() { if (score == MATE_SCORE - 1) { // 提示电脑胜利 ui->ComputerScore->setText(QString::fromLocal8Bit("电脑获胜")); - // 电脑赢了,这时玩家已经无法下棋了,因为有canMove函数的判断,走任何子都是被将军的 + // 设置电脑胜利标志 + this->mComputerWin = true; } else if (score == LOSS_SCORE) { // 提示玩家胜利 ui->ComputerScore->setText(QString::fromLocal8Bit("玩家获胜")); - // 电脑输了,禁止玩家下棋,并且电脑不能再走了,恢复界面三个按钮的点击 - ui->HardSelectionBox->setDisabled(false); - ui->Reset->setDisabled(false); - ui->Flip->setDisabled(false); + // 玩家获胜,电脑无法走棋,直接解锁按钮并返回 + // 注意此时isMoving保持为true,这样可以使得棋子不响应玩家的操作 + this->setButtonDisabled(false); return; } else if (score > BAN_SCORE_MATE) { // 如果电脑快赢了 @@ -730,9 +738,8 @@ inline Step Dialog::mapToStep(const Move move) { getDest(move) % 16 - 3}; } -inline void Dialog::setMoving(const bool isMoving) { - this->mOnMoving = isMoving; - if (isMoving) { +inline void Dialog::setButtonDisabled(const bool disabled) { + if (disabled) { // 如果GUI正在播放动画或电脑正在思考,界面三个按钮禁止点击 ui->HardSelectionBox->setDisabled(true); ui->Reset->setDisabled(true); @@ -744,3 +751,8 @@ inline void Dialog::setMoving(const bool isMoving) { ui->Flip->setDisabled(false); } } + +inline void Dialog::setMoving(const bool isMoving) { + this->mOnMoving = isMoving; + this->setButtonDisabled(isMoving); +} diff --git a/dialog.h b/dialog.h index 97547cc..c90412f 100644 --- a/dialog.h +++ b/dialog.h @@ -40,6 +40,8 @@ class Dialog : public QDialog { inline Move mapTo256(const Step &step); // 将一个256表示法的走法转换为10x9表示法 inline Step mapToStep(const Move move); + // 设置按钮状态,可点击/不可点击 + inline void setButtonDisabled(const bool disable); // 设置走棋状态 inline void setMoving(const bool isMoving); @@ -94,9 +96,12 @@ private slots: new QPropertyAnimation(mSelected, "geometry")}; QPropertyAnimation *mMaskAni{new QPropertyAnimation(this, "geometry")}; - //走棋时不给用户乱动 + // 走棋时不给用户乱动 bool mOnMoving{false}; + // 电脑是否胜利 + bool mComputerWin{false}; + //这个是提供给电脑走子的对象指针二维数组 QVector> mLabelPointers; bool mIsFliped{false}; diff --git a/pikachess.hpp b/pikachess.hpp index 612e6cb..a377535 100644 --- a/pikachess.hpp +++ b/pikachess.hpp @@ -678,7 +678,7 @@ inline bool isSameColumn(const Move move) { // 用于计分的翻转 inline Position flipPosition(const Position pos) { return 254 - pos; } -// 重置置换表与深度信息 +// 重置置换表与深度信息,清空默认最佳走法 inline void resetCache(PositionInfo &positionInfo) { // 重置深度信息 positionInfo.mDistance = 0; @@ -690,6 +690,8 @@ inline void resetCache(PositionInfo &positionInfo) { hashItem.mMove = 0; hashItem.mScore = 0; } + // 重置最佳走法 + positionInfo.mBestMove = INVALID_MOVE; } // 局面信息的构造函数 @@ -1744,7 +1746,7 @@ Score PositionInfo::searchRoot(const Depth depth) { // 当前走法 Move move; // 搜索有限状态机 - SearchMachine search{*this, INVALID_MOVE, COMPUTER_SIDE}; + SearchMachine search{*this, this->mBestMove, COMPUTER_SIDE}; Score bestScore{LOSS_SCORE}; // 遍历所有走法 while ((move = search.nextMove())) {