必败时自动认输
This commit is contained in:
parent
d2df0c1c13
commit
8fd1303cc3
|
@ -291,6 +291,7 @@
|
|||
<addaction name="actionSound_S"/>
|
||||
<addaction name="actionAnimation_A"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionGiveUpIfMostLose_G"/>
|
||||
<addaction name="actionAutoRestart_A"/>
|
||||
<addaction name="actionRandomMove_R"/>
|
||||
</widget>
|
||||
|
@ -1113,6 +1114,17 @@
|
|||
<string>电脑着法随机(&R)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGiveUpIfMostLose_G">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>必败时认输(&G)</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
|
|
@ -831,6 +831,7 @@ const char* MillGameAi_ab::bestMove()
|
|||
{
|
||||
vector<Node*> bestMoves;
|
||||
size_t bestMovesSize = 0;
|
||||
bool isMostLose = true; // 是否必败
|
||||
|
||||
if ((rootNode->children).empty()) {
|
||||
return "error!";
|
||||
|
@ -867,6 +868,30 @@ const char* MillGameAi_ab::bestMove()
|
|||
i++;
|
||||
}
|
||||
|
||||
// 检查是否必败
|
||||
|
||||
MillGame::Player whosTurn = chess_.whosTurn();
|
||||
|
||||
for (auto child : rootNode->children) {
|
||||
// TODO: 使用常量代替
|
||||
if (whosTurn == MillGame::PLAYER1 && child->value > -10000 ||
|
||||
whosTurn == MillGame::PLAYER2 && child->value < 10000) {
|
||||
isMostLose = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 自动认输
|
||||
if (isMostLose) {
|
||||
if (whosTurn == MillGame::PLAYER1) {
|
||||
sprintf(cmdline, "Player1 give up!");
|
||||
} else if (whosTurn == MillGame::PLAYER2) {
|
||||
sprintf(cmdline, "Player2 give up!");
|
||||
}
|
||||
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
for (auto child : rootNode->children) {
|
||||
if (child->value == rootNode->value) {
|
||||
bestMoves.push_back(child);
|
||||
|
|
|
@ -168,6 +168,7 @@ MillGame &MillGame::operator = (const MillGame &chess)
|
|||
currentStep = chess.currentStep;
|
||||
moveStep = chess.moveStep;
|
||||
randomMove_ = chess.randomMove_;
|
||||
giveUpIfMostLose_ = chess.giveUpIfMostLose_;
|
||||
board_ = context.board;
|
||||
currentPos = chess.currentPos;
|
||||
winner = chess.winner;
|
||||
|
@ -663,8 +664,11 @@ void MillGame::createMillTable()
|
|||
}
|
||||
|
||||
// 设置配置
|
||||
bool MillGame::configure(bool randomMove)
|
||||
bool MillGame::configure(bool giveUpIfMostLose, bool randomMove)
|
||||
{
|
||||
// 设置是否必败时认输
|
||||
this->giveUpIfMostLose_ = giveUpIfMostLose;
|
||||
|
||||
// 设置是否随机走子
|
||||
this->randomMove_ = randomMove;
|
||||
|
||||
|
@ -1398,10 +1402,12 @@ bool MillGame::giveup(Player loser)
|
|||
winner = PLAYER2;
|
||||
tips = "玩家1投子认负。";
|
||||
sprintf(cmdline, "Player1 give up!");
|
||||
score_2++;
|
||||
} else if (loser == PLAYER2) {
|
||||
winner = PLAYER1;
|
||||
tips = "玩家2投子认负。";
|
||||
sprintf(cmdline, "Player2 give up!");
|
||||
score_1++;
|
||||
}
|
||||
|
||||
cmdlist.emplace_back(string(cmdline));
|
||||
|
@ -1465,7 +1471,7 @@ bool MillGame::command(const char *cmd)
|
|||
}
|
||||
|
||||
// 认输
|
||||
args = sscanf(cmd, "Players%1u give up!", &t);
|
||||
args = sscanf(cmd, "Player%1u give up!", &t);
|
||||
|
||||
if (args == 1) {
|
||||
if (t == 1) {
|
||||
|
|
|
@ -304,7 +304,7 @@ public:
|
|||
MillGame &operator=(const MillGame &);
|
||||
|
||||
// 设置配置
|
||||
bool configure(bool randomMove);
|
||||
bool configure(bool giveUpIfMostLose, bool randomMove);
|
||||
|
||||
// 设置棋局状态和棋盘上下文,用于初始化
|
||||
bool setContext(const struct Rule *rule,
|
||||
|
@ -362,6 +362,12 @@ public:
|
|||
int getMoveStep() const
|
||||
{
|
||||
return moveStep;
|
||||
}
|
||||
|
||||
// 获取是否必败时认输
|
||||
bool getGiveUpIfMostLose() const
|
||||
{
|
||||
return giveUpIfMostLose_;
|
||||
}
|
||||
|
||||
// 获取 AI 是否随机走子
|
||||
|
@ -575,6 +581,9 @@ private:
|
|||
// 从走子阶段开始或上次吃子起的步数
|
||||
int moveStep {};
|
||||
|
||||
// 是否必败时认输
|
||||
bool giveUpIfMostLose_ {true};
|
||||
|
||||
// AI 是否随机走子
|
||||
bool randomMove_ {true};
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ GameController::GameController(GameScene & scene, QObject * parent) :
|
|||
ruleNo_(-1),
|
||||
timeLimit(0),
|
||||
stepsLimit(50),
|
||||
giveUpIfMostLose_(true),
|
||||
randomMove_(true)
|
||||
{
|
||||
// 已在view的样式表中添加背景,scene中不用添加背景
|
||||
|
@ -116,7 +117,7 @@ const QMap<int, QStringList> GameController::getActions()
|
|||
|
||||
void GameController::gameStart()
|
||||
{
|
||||
chess_.configure(randomMove_);
|
||||
chess_.configure(giveUpIfMostLose_, randomMove_);
|
||||
chess_.start();
|
||||
chessTemp = chess_;
|
||||
|
||||
|
@ -142,7 +143,7 @@ void GameController::gameReset()
|
|||
}
|
||||
|
||||
// 重置游戏
|
||||
chess_.configure(randomMove_);
|
||||
chess_.configure(giveUpIfMostLose_, randomMove_);
|
||||
chess_.reset();
|
||||
chessTemp = chess_;
|
||||
|
||||
|
@ -283,7 +284,7 @@ void GameController::setRule(int ruleNo, MillGame::step_t stepLimited /*= -1*/,
|
|||
|
||||
void GameController::setEngine1(bool arg)
|
||||
{
|
||||
chess_.configure(randomMove_);
|
||||
chess_.configure(giveUpIfMostLose_, randomMove_);
|
||||
|
||||
isAiPlayer1 = arg;
|
||||
if (arg) {
|
||||
|
@ -299,7 +300,7 @@ void GameController::setEngine1(bool arg)
|
|||
|
||||
void GameController::setEngine2(bool arg)
|
||||
{
|
||||
chess_.configure(randomMove_);
|
||||
chess_.configure(giveUpIfMostLose_, randomMove_);
|
||||
|
||||
isAiPlayer2 = arg;
|
||||
if (arg) {
|
||||
|
@ -370,6 +371,11 @@ void GameController::playSound(const QString &soundPath)
|
|||
#endif /* ! DONOT_PLAY_SOUND */
|
||||
}
|
||||
|
||||
void GameController::setGiveUpIfMostLose(bool arg)
|
||||
{
|
||||
giveUpIfMostLose_ = arg;
|
||||
}
|
||||
|
||||
void GameController::setAutoRestart(bool arg)
|
||||
{
|
||||
isAutoRestart = arg;
|
||||
|
@ -778,11 +784,9 @@ bool GameController::giveUp()
|
|||
|
||||
if (chess_.whosTurn() == MillGame::PLAYER1) {
|
||||
result = chess_.giveup(MillGame::PLAYER1);
|
||||
chess_.score_2++;
|
||||
}
|
||||
else if (chess_.whosTurn() == MillGame::PLAYER2) {
|
||||
result = chess_.giveup(MillGame::PLAYER2);
|
||||
chess_.score_1++;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
|
|
|
@ -70,6 +70,11 @@ public:
|
|||
return stepsLimit;
|
||||
}
|
||||
|
||||
bool getGiveUpIfMostLose()
|
||||
{
|
||||
return giveUpIfMostLose_;
|
||||
}
|
||||
|
||||
bool getRandomMove()
|
||||
{
|
||||
return randomMove_;
|
||||
|
@ -150,6 +155,9 @@ public slots:
|
|||
// 播放声音
|
||||
void playSound(const QString &soundPath);
|
||||
|
||||
// 是否必败时认输
|
||||
void setGiveUpIfMostLose(bool arg);
|
||||
|
||||
// 是否自动开局
|
||||
void setAutoRestart(bool arg = false);
|
||||
|
||||
|
@ -240,6 +248,9 @@ private:
|
|||
// 是否有落子音效
|
||||
bool hasSound;
|
||||
|
||||
// 是否必败时认输
|
||||
bool giveUpIfMostLose_;
|
||||
|
||||
// 是否棋局结束后自动重新开局
|
||||
bool isAutoRestart;
|
||||
|
||||
|
|
|
@ -204,6 +204,9 @@ void MillGameWindow::initialize()
|
|||
connect(ui.actionAnimation_A, SIGNAL(toggled(bool)),
|
||||
game, SLOT(setAnimation(bool)));
|
||||
|
||||
connect(ui.actionGiveUpIfMostLose_G, SIGNAL(toggled(bool)),
|
||||
game, SLOT(setGiveUpIfMostLose(bool)));
|
||||
|
||||
connect(ui.actionAutoRestart_A, SIGNAL(toggled(bool)),
|
||||
game, SLOT(setAutoRestart(bool)));
|
||||
|
||||
|
|
Loading…
Reference in New Issue