diff --git a/programr.md b/programr.md index 1d1d683d..a7930d00 100644 --- a/programr.md +++ b/programr.md @@ -66,7 +66,7 @@ The entry point for a search is a routine called `Thread::search()`. This functi `search()` does some other special processing because it is at the top of the search tree. This function then calls `search()` to recursively process lower-depth nodes. -The first step in search() is to check if the current board position is drawn, due to a 3-fold repetition of moves, or the 50-move rule. +The first step in search() is to check if the current board position is drawn, due to a 3-fold repetition of moves, or the N-move rule. Sanmill will also terminate the search immediately if the absolute maximum ply depth is reached. This is quite unlikely. diff --git a/src/mills.cpp b/src/mills.cpp index c478dfd5..13ac7d89 100644 --- a/src/mills.cpp +++ b/src/mills.cpp @@ -28,7 +28,7 @@ const char *loseReasonNoWayStr = "Player%d no way to go. Player%d win!"; const char *loseReasonTimeOverStr = "Time over. Player%d win!"; const char *drawReasonThreefoldRepetitionStr = "Threefold Repetition. Draw!"; -const char *drawReasonRule50Str = "Fifty-move rule. Draw!"; +const char *drawReasonRule50Str = "N-move rule. Draw!"; const char *loseReasonBoardIsFullStr = "Full. Player2 win!"; const char *drawReasonBoardIsFullStr = "Full. In draw!"; const char *loseReasonlessThanThreeStr = "Player%d win!"; diff --git a/src/perfect/perfect_test.cpp b/src/perfect/perfect_test.cpp index fbb7b94a..2f1db08f 100644 --- a/src/perfect/perfect_test.cpp +++ b/src/perfect/perfect_test.cpp @@ -7,6 +7,7 @@ #include "perfectAI.h" #include "perfect.h" +#include "rule.h" #include "config.h" using namespace std; @@ -99,7 +100,7 @@ int perfect_main(void) #ifdef SELF_PLAY moveCount++; - if (moveCount > 99) { + if (moveCount > rule.maxStepsLedToDraw) { goto out; } #endif // SELF_PLAY diff --git a/src/position.cpp b/src/position.cpp index c4bd594f..36e64d60 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -208,7 +208,7 @@ Position &Position::set(const string &fenStr, Thread *th) 6) Halfmove clock. This is the number of halfmoves since the last capture. This is used to determine if a draw can be claimed under the - fifty-move rule. + N-move rule. 7) Fullmove number. The number of the full move. It starts at 1, and is incremented after White's move. diff --git a/src/rule.cpp b/src/rule.cpp index 42e33a1a..fb40d4cd 100644 --- a/src/rule.cpp +++ b/src/rule.cpp @@ -35,7 +35,7 @@ struct Rule rule = { true, // 摆棋满子(闷棋,只有12子棋才出现)算先手负 true, // 走棋阶段不能行动(被“闷”)算负 true, // 剩三子时可以飞棋 - 99 // 99半步即50回合 + 100 // 100着 }; const struct Rule RULES[N_RULES] = { @@ -60,7 +60,7 @@ const struct Rule RULES[N_RULES] = { true, // 摆棋满子(闷棋,只有12子棋才出现)算先手负 true, // 走棋阶段不能行动(被“闷”)算负 false, // 剩三子时不可以飞棋 - 99 // 99半步即50回合 + 100 // 100着 }, { "打三棋(12连棋)", // 打三棋 @@ -71,7 +71,7 @@ const struct Rule RULES[N_RULES] = { "4. 走棋阶段,后摆棋的一方先走;\n" "5. 同时出现两个“三连”只能提一子;\n" "6. 其它规则与成三棋基本相同。", - 12, // 双方各12子 + 12, // 双方各12子 3, // 飞子条件为剩余3颗子 3, // 赛点子数为3 true, // 有斜线 @@ -82,7 +82,7 @@ const struct Rule RULES[N_RULES] = { true, // 摆棋满子(闷棋,只有12子棋才出现)算先手负 true, // 走棋阶段不能行动(被“闷”)算负 false, // 剩三子时不可以飞棋 - 99 // 99半步即50回合 + 100 // 100着 }, { "Nine men's morris", // 莫里斯九子棋 @@ -99,7 +99,7 @@ const struct Rule RULES[N_RULES] = { true, // 摆棋满子(闷棋,只有12子棋才出现)算先手负 true, // 走棋阶段不能行动(被“闷”)算负 true, // 剩三子时可以飞棋 - 99 // 99半步即50回合 + 100 // 100着 }, { "Twelve men's morris", // 莫里斯十二子棋 @@ -120,8 +120,8 @@ const struct Rule RULES[N_RULES] = { false, // 不能提对手的“三连”子,除非无子可提; true, // 摆棋满子(闷棋,只有12子棋才出现)算先手负 true, // 走棋阶段不能行动(被“闷”)算负 - true, // 剩三子时可以飞棋 - 99 // 99半步即50回合 + true, // 剩三子时可以飞棋 + 100 // 100着 } }; diff --git a/src/search.cpp b/src/search.cpp index 13d2c556..acfe6094 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -219,7 +219,7 @@ Value search(Position *pos, Sanmill::Stack &ss, Depth depth, Depth ori Depth epsilon; #ifdef RULE_50 - if (pos->rule50_count() > 99) { + if (pos->rule50_count() > rule.maxStepsLedToDraw) { alpha = VALUE_DRAW; if (alpha >= beta) { return alpha; diff --git a/src/ucioption.cpp b/src/ucioption.cpp index a82bb49d..de3c68f5 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -202,7 +202,7 @@ void init(OptionsMap &o) o["IsWhiteLoseButNotDrawWhenBoardFull"] << Option(true, on_isWhiteLoseButNotDrawWhenBoardFull); o["IsLoseButNotChangeSideWhenNoWay"] << Option(true, on_isLoseButNotChangeSideWhenNoWay); o["MayFly"] << Option(true, on_mayFly); - o["MaxStepsLedToDraw"] << Option(50, 10, 200, on_maxStepsLedToDraw); + o["MaxStepsLedToDraw"] << Option(100, 10, 200, on_maxStepsLedToDraw); } diff --git a/src/ui/flutter_app/lib/common/config.dart b/src/ui/flutter_app/lib/common/config.dart index 3a3beeb0..c2bd2c44 100644 --- a/src/ui/flutter_app/lib/common/config.dart +++ b/src/ui/flutter_app/lib/common/config.dart @@ -76,7 +76,7 @@ class Config { static bool isWhiteLoseButNotDrawWhenBoardFull = true; static bool isLoseButNotChangeSideWhenNoWay = true; static bool mayFly = true; - static int maxStepsLedToDraw = 50; + static int maxStepsLedToDraw = 100; static Future loadSettings() async { print("[config] Loading settings..."); @@ -156,7 +156,7 @@ class Config { settings['IsLoseButNotChangeSideWhenNoWay'] ?? true; rule.mayFly = Config.mayFly = settings['MayFly'] ?? true; rule.maxStepsLedToDraw = - Config.maxStepsLedToDraw = settings['MaxStepsLedToDraw'] ?? 50; + Config.maxStepsLedToDraw = settings['MaxStepsLedToDraw'] ?? 100; settingsLoaded = true; print("[config] Loading settings done!"); diff --git a/src/ui/flutter_app/lib/mill/rule.dart b/src/ui/flutter_app/lib/mill/rule.dart index 37b52262..8f48e406 100644 --- a/src/ui/flutter_app/lib/mill/rule.dart +++ b/src/ui/flutter_app/lib/mill/rule.dart @@ -30,7 +30,7 @@ class Rule { bool isWhiteLoseButNotDrawWhenBoardFull = true; bool isLoseButNotChangeSideWhenNoWay = true; bool mayFly = true; - int maxStepsLedToDraw = 50; + int maxStepsLedToDraw = 100; } Rule rule = Rule(); diff --git a/src/ui/flutter_app/lib/widgets/rule_settings_page.dart b/src/ui/flutter_app/lib/widgets/rule_settings_page.dart index 3a147891..708a0a9b 100644 --- a/src/ui/flutter_app/lib/widgets/rule_settings_page.dart +++ b/src/ui/flutter_app/lib/widgets/rule_settings_page.dart @@ -247,7 +247,7 @@ class _RuleSettingsPageState extends State { setState(() { rule.maxStepsLedToDraw = - Config.maxStepsLedToDraw = maxStepsLedToDraw ?? 50; + Config.maxStepsLedToDraw = maxStepsLedToDraw ?? 100; }); print("[config] rule.maxStepsLedToDraw: ${rule.maxStepsLedToDraw}"); diff --git a/src/ui/qt/game.cpp b/src/ui/qt/game.cpp index c3baf2a5..27372796 100644 --- a/src/ui/qt/game.cpp +++ b/src/ui/qt/game.cpp @@ -65,7 +65,7 @@ Game::Game( timeID(0), ruleIndex(-1), timeLimit(gameOptions.getMoveTime()), - stepsLimit(50) + stepsLimit(100) { // The background has been added to the style sheet of view, but not to scene // The difference is that the background in view does not change with the view transformation, @@ -369,8 +369,12 @@ void Game::setInvert(bool arg) } } -void Game::setRule(int ruleNo, int stepLimited /*= -1*/, int timeLimited /*= 0*/) +void Game::setRule(int ruleNo, int stepLimited /*= -1*/, int timeLimited /*= 0 TODO: Unused */) { + rule.maxStepsLedToDraw = stepLimited; + + // TODO + // Update the rule, the original time limit and step limit remain unchanged if (ruleNo < 0 || ruleNo >= N_RULES) return; diff --git a/src/ui/qt/gamewindow.cpp b/src/ui/qt/gamewindow.cpp index 30c4a1ef..4a44c81f 100644 --- a/src/ui/qt/gamewindow.cpp +++ b/src/ui/qt/gamewindow.cpp @@ -507,11 +507,13 @@ void MillGameWindow::on_actionLimited_T_triggered() label_step->setText(tr("N-Move Rule:")); - // TODO: Implement N Moves Limit + // TODO: Save settings //comboBox_step->addItem(tr("Infinite"), 0); + comboBox_step->addItem(tr("10 Moves"), 10); + comboBox_step->addItem(tr("30 Moves"), 30); comboBox_step->addItem(tr("50 Moves"), 50); - //comboBox_step->addItem(tr("100 Moves"), 100); - //comboBox_step->addItem(tr("200 Moves"), 200); + comboBox_step->addItem(tr("100 Moves"), 100); + comboBox_step->addItem(tr("200 Moves"), 200); comboBox_step->setCurrentIndex(comboBox_step->findData(gStep)); label_time->setText(tr("Max. time:")); @@ -541,7 +543,7 @@ void MillGameWindow::on_actionLimited_T_triggered() int dStep = comboBox_step->currentData().toInt(); int dTime = comboBox_time->currentData().toInt(); if (gStep != dStep || gTime != dTime) { - game->setRule(ruleNo, static_cast(dStep), dTime); + game->setRule(ruleNo, static_cast(dStep), dTime); // TODO: Remove dTime game->setMoveTime(dTime); } }