# 古谱残局练习题:来源与核验报告 `app/src/main/assets/endgames.json` 里的 30 道残局练习题都取自古谱原局,没有自行编排或修改任何一个局面。这份报告说明每道题从哪里来、经过了哪些核验,以及哪些局没有入选、为什么。 ## 结果概览 题目按引擎核定的杀着步数分组: - easy 9 题,2 到 3 步杀; - medium 12 题,4 到 6 步杀; - hard 9 题,7 到 12 步杀。 按出处分:《适情雅趣》13 题,《烂柯神机》7 题,《梦入神机》5 题,《韬略元机》3 题,《橘中秘》2 题。 红方攻子的分布比较均衡:用到马的有 22 题,用到炮的 20 题,用到车的 20 题,用到兵的 19 题。既有双兵、炮双兵这样的实用残局,也有车马炮兵混合的连照杀局。 | 组 | 步数 | id | 局名 | 出处 | |---|---|---|---|---| | easy | 2 | jzm-096 | 双兵破单缺象 | 《橘中秘》卷下 残局着法 第九十六局 | | easy | 2 | jzm-084 | 炮双兵胜双象 | 《橘中秘》卷下 残局着法 第八十四局 | | easy | 2 | lksj-42373 | 善阵善战 | 《烂柯神机》 | | easy | 3 | mrsj-001 | 由中应外 | 《梦入神机》第1局 | | easy | 3 | mrsj-003 | 存没无累 | 《梦入神机》第3局 | | easy | 3 | sqyq-013 | 目视横流 | 《适情雅趣》第13局 | | easy | 3 | sqyq-066 | 见危致命 | 《适情雅趣》第66局 | | easy | 3 | sqyq-192 | 两地关心 | 《适情雅趣》第192局 | | easy | 3 | lksj-42520 | 运实于虚 | 《烂柯神机》 | | medium | 4 | sqyq-265 | 入穴取虎 | 《适情雅趣》第265局 | | medium | 4 | sqyq-084 | 双蜓点水 | 《适情雅趣》第84局 | | medium | 4 | lksj-42472 | 直捣中坚 | 《烂柯神机》 | | medium | 4 | mrsj-012 | 舍身无二 | 《梦入神机》第12局 | | medium | 5 | sqyq-075 | 豪帅心服 | 《适情雅趣》第75局 | | medium | 5 | sqyq-264 | 巅峰得路 | 《适情雅趣》第264局 | | medium | 5 | tlyj-136 | 二鬼把门 | 《韬略元机》残局谱 第136局 | | medium | 5 | lksj-42381 | 圆转如意 | 《烂柯神机》 | | medium | 6 | sqyq-252 | 二龙绕室 | 《适情雅趣》第252局 | | medium | 6 | sqyq-400 | 双马饮泉 | 《适情雅趣》第400局 | | medium | 6 | lksj-42367 | 反覆驰骤 | 《烂柯神机》 | | medium | 6 | tlyj-129 | 坐镇边陲 | 《韬略元机》残局谱 第129局 | | hard | 7 | mrsj-072 | 塞马嘶群 | 《梦入神机》第72局 | | hard | 7 | sqyq-291 | 丹山起凤 | 《适情雅趣》第291局 | | hard | 8 | tlyj-173 | 铁骑追风 | 《韬略元机》残局谱 第173局 | | hard | 8 | lksj-42376 | 四面楚歌 | 《烂柯神机》 | | hard | 8 | sqyq-014 | 独鹿鸣泽 | 《适情雅趣》第14局 | | hard | 9 | sqyq-188 | 载沉载浮 | 《适情雅趣》第188局 | | hard | 10 | sqyq-221 | 野马舞风 | 《适情雅趣》第221局 | | hard | 11 | mrsj-112 | 双燕争飞 | 《梦入神机》第112局 | | hard | 12 | lksj-42365 | 双狮滚球 | 《烂柯神机》 | App 里显示的出处统一写成「《书名》第N局」;《烂柯神机》没有局号,只写书名。 ## 数据来源 ### 主来源:东萍象棋网 每题的 `source_url` 都指向东萍象棋网「象棋谱大全-古谱残局」书架里的单局页面,形如 `http://www.dpxq.com/hldcg/search/view_u_.html`。页面内嵌 DhtmlXQ 数据,包括: - `binit`:32 个棋子的初始坐标; - `movelist`:原书解法主线; - `result`:原书结论(红胜、和棋或黑胜); - 局名、书名和卷次。 八部书按各自的「棋谱列表」逐页抓完,共 1906 页,每次请求间隔约一秒。失败的请求在第二轮补齐,最终每部书的抓取数都等于列表数: | 书 | 页面数 | 原书判红胜 | |---|---|---| | 适情雅趣 | 550 | 452 | | 烂柯神机 | 258 | 196(局名后缀为「红胜」的) | | 梦入神机 | 152 | 135 | | 心武残编 | 155 | 5 | | 竹香斋象戏谱 | 208 | 25 | | 百局象棋谱 | 105 | 9 | | 韬略元机 | 341(其中 124 页是全局谱,没有残局局面) | 136 | | 桔中秘(残局谱) | 137 | 42 | `binit` 换算成 FEN 的方法先拿《适情雅趣》第1局逐子核对过,32 个子全部吻合;批量换算的结果又和下面两个独立来源大面积一致。东萍只能用 HTTP 访问,所以 `source_url` 用的是 http 地址。 ### 第二来源(交叉核对) - **《适情雅趣》**:用 https://raw.githubusercontent.com/kuiba1949/xiangqi-tools/master/fen/shiqingyaqu551.fen 核对(李浭 551 局新版,BSD-3 许可)。 - 550 局里 519 局与东萍逐字相同,有出入的 31 局一律不用。 - 李浭本在第227局补了一张复原图,所以两边局号从第227局起错开一位。按局面和局名配对,JSON 里的局号沿用东萍的 550 局本。 - **《烂柯神机》**:用 GitHub weiyinfu/xqp 仓库 `残局/烂柯神机/` 目录下的 258 个 XQF 文件核对(版本 10,未加密)。257 局与东萍相同,唯一不同的「一鼓成功」没有选。 - **《梦入神机》《韬略元机》《橘中秘》**:没找到第二个机器可读来源。只选原书解法的半步数正好等于 2N−1 的局,用原书解法和引擎结论互相印证。 - 例外是 jzm-084:东萍只记了第一步「帅四平五」,这步与引擎一致,后面没有记录。要更严格可以去掉这一题,easy 组仍有 8 题。 - 《橘中秘》这两题出自东萍注明的「卷下 第五编 残局着法」。这个分编方式像是后世整理本的体例,是否对应明刻本原卷,线上无法确认。 ### 看过但没采用 - 象棋巫师(xqbase.com)在线只有现代棋谱和残局库,没有古谱数据。 - soui4/soui 的 endgames.json 等应用自带的列表是二手汇编,没有逐局出处。 - brianhliou/mistboard 只参考了它对东萍页面结构的说明,没有用它的数据。 ## 核验方法 引擎用 Pikafish 与官方网络文件 `pikafish.nnue`。每个局面单独起一个新进程,读到 EOF 或超时都判为失败。 1. **合法性**:先用独立写的规则检查,包括: - 将帅在九宫内,仕和相只在能到达的点上; - 兵卒不在不可能到达的格子上,各兵种数量不超限; - 将帅不照面,轮到红走时黑方没有被将军。 之后 Pikafish 也必须能正常接受这个局面。 2. **初筛**:`go movetime 1000`,只保留红方 `mate N`(0 < N ≤ 13)的局面。 3. **正式核验**: - 先 `go depth 24`(3 线程),再 `go movetime 8000`,两次必须给出同一个 N; - 解法取引擎主变,被截短的从末端续补,再用独立的着法生成器从头重放; - 确认每步合法、总长正好 2N−1 个半步,最后一步是将死而不是困毙。 4. **入选 30 题的追加检查**: - 第三次搜索 `go movetime 20000`(4 线程),30 题全部给出同一个 N; - 防守穷举:在解法里黑方的每一步,把黑方所有其他合法应着都走一遍,红方都仍能在剩余步数内杀。30 题全部通过。 5. **红方着法唯一性**:对解法里 164 个红方着法逐一用 MultiPV 4 搜 3 秒,没有一处存在同样步数的替代杀法。黑方按解法里的应着走即可,那是引擎选的最顽强防守。 6. **App 规则**:单元测试 `RulesAndDataTest.everyEndgameSolutionMatesUnderTheAppsRules` 用 App 自己的走法规则把每道题的答案从头走到将死,并核对 `mate_in`。 分组按 N 划分:1 至 3 为 easy,4 至 6 为 medium,7 至 12 为 hard。 ## 排除情况与原因 1. **原书判和或判黑胜的局一律不选**: - 《百局象棋谱》的七星聚会、千里独行、蚯蚓降龙、双龙戏珠、八虎征西,《竹香斋》的七星拱斗、尺蚓降龙、策杖独行,《心武残编》的七星同庆、蚯蚓降龙、独行千里,结论都是和棋。 - 《竹香斋》的野马操田有两个版本标黑胜,一个标和棋。 - 心武残编 155 局里 146 局和,竹香斋 208 局里 171 局和,百局 105 局里 93 局和,所以这三部书都没有入选的题。 2. **原书判和或判黑胜、引擎却能找到红方杀着的局**,共 47 个,排除。这类局要么已被后人破解,要么转录有误。其中《烂柯神机》的 27 个里有一部分带「红胜(1)」「红胜(2)」之类的版本后缀,从严没有算作红胜。 3. **主变以困毙而不是将死收尾的局**,共 19 个,例如《橘中秘》第三十一局「车兵闷车士」。 4. **两次搜索给出的杀着步数不一致的局**,共 55 个。 5. **原书判红胜、但引擎 1 秒内找不到杀着,或杀着超过 13 步的局**,没有进入核验。 6. **两个来源对不上的局**:适情雅趣 31 局,烂柯神机 1 局。 7. **《韬略元机》**:124 页是全局谱,没有局面。第13局「既安且闲」红兵在 a2,是非法局面。 8. **《梦入神机》第42局「黄鹂出谷」**:引擎两步即杀,原书解法要四步,属于被破的局,没有选。紧接着的第43局「黄鹂出谷(2)」是修订版,引擎 7 步杀,与原书一致,可以作为后备题。 ## 其他说明 1. **局名**:用东萍页面上的简体写法。《橘中秘》两题取自页面注释里转录的原书标题;东萍自己的页面标题分别作「双低兵胜单缺象096」和「炮双兵胜双象084」。 2. **同名与异名**: - 《适情雅趣》第291局在东萍本叫「丹山起凤」,与第107局同名,李浭本改称「凤起丹山」。 - 第188局东萍作「载沉载浮」,李浭本作「载浮载沉」。 - 两个版本里这两局的局面完全一致。 3. **id 规则**:《烂柯神机》在东萍和 XQF 文件里都没有局号,所以 id 用东萍页面编号(例如 lksj-42373)。其余各书用书中局号。 4. 抓取的原始记录、全部核验结果和挑题脚本没有放进仓库。