I ran 32 basic xiangqi endgame verdicts against Pikafish at depth 26 and against chessdb.cn, which is a lookup rather than a search and covered 27 of them exactly. Final sweep is 31 of 32 agreeing, one leaning.
Two things in here that don't have chess analogues and that I'd expect to matter for anyone writing a xiangqi engine.
Perpetual check is a loss, not a draw. The side giving check has to vary or forfeit. So the standard chess resource for saving a lost position inverts, and a defence built on repeated checks hands over the point.
The natural limit (自然限着) draws the game after 60 moves by each side with no capture, whatever the evaluation says. A book win needing 70 moves of technique is not a win you can play. I let Pikafish play the one unresolved row out against itself and it broke through on move 34, with 26 to spare, which is the only reason that verdict stands.
Both are easy to read past in an English summary and expensive to read past at the board. Positions and the checker are in the repo, on my own site.
https://brianhliou.com/posts/xiangqi-basic-endgames/
Xiangqi endgame verdicts vs Pikafish: where an engine and a rules corpus disagree
Moderator: Ras
-
brianhliou
- Posts: 2
- Joined: Thu Aug 27, 2026 1:09 am
- Full name: Brian Liou
-
hgm
- Posts: 28524
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Xiangqi endgame verdicts vs Pikafish: where an engine and a rules corpus disagree
Is this 60-move rule a new one, or only something that applies in computer games? I thought classical Xiangqi did not have such a rule. 60 moves does not seem very generous, if the weak side still has attacking pieces. After every move that made progress, it could start a perpetual check sequence, and continue that until it reaches the maximum number of repetitions (4?) it can afford with being declared a loss. So it can safely gp through 3 check cycles of 4 ply each (wasting 12 ply), after which the forced mate progresses 2 ply, and he can start another 12-ply delaying tactic. WIth less than 1/6 of the moves actually progressing the game, you would only have 10 moves to force the mate.
In the H+C vs H case, I am not surprised that search cannot find it. It might sound impressive that an engine searches 40 moves or more, but it can only do that by aggressive pruning of the search tree. To search the full tree it would probably only reach depth 8-10 ply. The problem is that the pruning is not really sensible unless the evaluation already knows which positions are likely to be closer to the mate than others. A comparable case is the KBN-K end-game in Chess, where practically every position with the strong side on move is a guaranteed win. But even the most advanced search, such as that of Stockfish, will not be able to find the mate (which can take 34 moves = 67 ply) unless the evaluation knows that progress can be approximately measured by the distance of the bare King to the corner of the color of the Bishop. With that knowledge the search can start pruning all branches where the bare King 'escapes', focusing it towards the mate.
I am not sure whether similar heuristics in the case of the Xiangqi KCHAAEE-KHAAEE end-game exist, and, if so, whether the Pikafish evaluation is aware of it. If not it might consider 40-move lines that are completely pointless, and do not make any progress at all. It will probably discover at some depth that it can force the weak side to a position that its evaluation, for this piece composition, considers most unfavorable. But if that means whether it is also closer to a mate remains to be seen.
Are the defensive pieces of the strong side really significant in this end-game? I.e., what is the rule for KCH-KHAAEE? A lone Horse is harmless even for a defenseless King, so from that perspecctive no defenders are needed, and they might only be in the way. But I suppose the Cannon can benefit from a mount, so an extra A could be essential.
Is this really out of reach for retrograde analysis? If I calculated right KCH-KHAAEE contains some 12G board positions, which sounds doable. Often an end-game can be simplified by putting restrictions on the strong side; if he can then still win with this restriction, he could certainly win without it. E.g. in KR-KAAEE you can restrict the Rook to be on the enemy half, as there should be no need to ever retreat it to your own half. (For lateral movement, the 7th rank should do, as it is always unobstructed.) Extra A or E of the strong side can be ignored when they are all on ranks behind their King (as they cannot obstruct a Rook that is not allowed to go there). This can strongly reduce the size of the table 6you need to prove a win.
In the H+C vs H case, I am not surprised that search cannot find it. It might sound impressive that an engine searches 40 moves or more, but it can only do that by aggressive pruning of the search tree. To search the full tree it would probably only reach depth 8-10 ply. The problem is that the pruning is not really sensible unless the evaluation already knows which positions are likely to be closer to the mate than others. A comparable case is the KBN-K end-game in Chess, where practically every position with the strong side on move is a guaranteed win. But even the most advanced search, such as that of Stockfish, will not be able to find the mate (which can take 34 moves = 67 ply) unless the evaluation knows that progress can be approximately measured by the distance of the bare King to the corner of the color of the Bishop. With that knowledge the search can start pruning all branches where the bare King 'escapes', focusing it towards the mate.
I am not sure whether similar heuristics in the case of the Xiangqi KCHAAEE-KHAAEE end-game exist, and, if so, whether the Pikafish evaluation is aware of it. If not it might consider 40-move lines that are completely pointless, and do not make any progress at all. It will probably discover at some depth that it can force the weak side to a position that its evaluation, for this piece composition, considers most unfavorable. But if that means whether it is also closer to a mate remains to be seen.
Are the defensive pieces of the strong side really significant in this end-game? I.e., what is the rule for KCH-KHAAEE? A lone Horse is harmless even for a defenseless King, so from that perspecctive no defenders are needed, and they might only be in the way. But I suppose the Cannon can benefit from a mount, so an extra A could be essential.
Is this really out of reach for retrograde analysis? If I calculated right KCH-KHAAEE contains some 12G board positions, which sounds doable. Often an end-game can be simplified by putting restrictions on the strong side; if he can then still win with this restriction, he could certainly win without it. E.g. in KR-KAAEE you can restrict the Rook to be on the enemy half, as there should be no need to ever retreat it to your own half. (For lateral movement, the 7th rank should do, as it is always unobstructed.) Extra A or E of the strong side can be ignored when they are all on ranks behind their King (as they cannot obstruct a Rook that is not allowed to go there). This can strongly reduce the size of the table 6you need to prove a win.
-
brianhliou
- Posts: 2
- Joined: Thu Aug 27, 2026 1:09 am
- Full name: Brian Liou
Re: Xiangqi endgame verdicts vs Pikafish: where an engine and a rules corpus disagree
The 60 move rule is modern, so your instinct is right. Nothing in the classical sources carries a move count: not 事林广记, not 薛丙's 1800 manual, not 屠景明's 1950 Shanghai rules. A general 限着 idea enters the PRC national rules in 1959, and 60 回合自然限着 specifically was proposed in the 1984 trial rules and formalised in 1987, then carried through 1999, 2011 and 2020 unchanged. It is a human tournament rule, not a computer convention. One 回合 is a move by each side, so 60 回合 is 120 plies, and only a capture resets it.
The delaying tactic does not work, for a reason I did not know about until I went looking. CXA 2020 article 22.2: when the natural limit is audited, the claiming side's checks count for at most 10 plies, and everything past that is deducted. Pikafish implements this and goes one step further, excluding the opponent's forced reply to an over quota check:
So checks do not burn the counter. Past ten plies of them they stop advancing it at all.
There is a second bar. 长将 is three repetitions of the cycle (24.9), and 23.5.1 makes it an immediate loss, which is unusual in that rulebook: 23.5.2 gives every other pending position two 回合 to vary first. The budget is three, and you cannot spend it.
Your general point survives by another route. Non repeating shuffling, no checks and no chases, is legal, triggers no adjudication, and draws at the limit, so the strong side does have to force a capture inside 120 plies. In this ending it is not close. Pikafish self play from the post's position gave six captures with a longest run of 37 plies without one.
One thing you may want for Fairy-Stockfish: its xiangqi variant inherits the chess 50 move default and draws at 100 plies rather than 120, with no check quota. That differs from both CXA and the Asian rules.
On the pruning you are right, and there is now a number for it. The nine man ending is solved. chessdb.cn has it as KNCKAABBN (filename order is K,A,B,R,N,C,P, so cannon plus horse sorts as NC, and searching for KCN finds nothing, which is how I nearly concluded it did not exist). 5,492,247,706 positions, longest DTC 163, longest DTM 229. Both are complete tables rather than WDL, and it downloads without an account:
A longest DTM of 229 plies is over three times the 67 you quote for KBN-K. No search finds that without an evaluation that already knows what progress looks like. The 229 ply position is 2ba5/4a4/4k3b/9/9/9/8C/9/9/3KN3n w, if you want to poke at it.
Your count was close. I make it 7,254,923,760 raw placements against your 12.4 billion. The difference is that the black king can stand on an advisor point or on the elephant point at the palace mouth, and the three free pieces have 84 squares rather than 90. The defender group of king, two advisors and two elephants enumerates to 1,410, which agrees with Wu and Beal's published kaa = 70 for the king and advisors alone. chessdb's index is 5.49 billion, 76% of my raw count. I assume the balance is legality, but their indexing convention is undocumented, so I would not swear to that split.
The restriction argument does not hold here, because the strong side's defenders are not optional:
All against K+H+A+A+B+B. One advisor is worth 63 points of win rate, one elephant is worth 7, and the second advisor adds one. Your reading that the elephants are mostly in the way is right, and the mount idea points at the correct piece, but stripping to KCH turns a won ending into a 78% draw. I ran the same ladder through Pikafish at depth 30 before finding the tables and got the same ordering, which was reassuring in both directions.
So the correctly reduced problem is the ten man KANCKAABBN, and that is built too: 24,251,768,055 positions.
The thirteen man version in my post, KAABBNCKAABBN, is in none of the 8,705 tables, and a live probe returns unknown. So the 例胜 claim in the manual is about material nobody has solved, and the reduction of it that has been solved is mostly a draw. My "search or nothing" line was too strong. I will fix it.
The delaying tactic does not work, for a reason I did not know about until I went looking. CXA 2020 article 22.2: when the natural limit is audited, the claiming side's checks count for at most 10 plies, and everything past that is deducted. Pikafish implements this and goes one step further, excluding the opponent's forced reply to an over quota check:
Code: Select all
if (!givesCheck || ++st->check10[stm] <= 10) { ... ++st->rule60; }There is a second bar. 长将 is three repetitions of the cycle (24.9), and 23.5.1 makes it an immediate loss, which is unusual in that rulebook: 23.5.2 gives every other pending position two 回合 to vary first. The budget is three, and you cannot spend it.
Your general point survives by another route. Non repeating shuffling, no checks and no chases, is legal, triggers no adjudication, and draws at the limit, so the strong side does have to force a capture inside 120 plies. In this ending it is not close. Pikafish self play from the post's position gave six captures with a longest run of 37 plies without one.
One thing you may want for Fairy-Stockfish: its xiangqi variant inherits the chess 50 move default and draws at 100 plies rather than 120, with no check quota. That differs from both CXA and the Asian rules.
On the pruning you are right, and there is now a number for it. The nine man ending is solved. chessdb.cn has it as KNCKAABBN (filename order is K,A,B,R,N,C,P, so cannon plus horse sorts as NC, and searching for KCN finds nothing, which is how I nearly concluded it did not exist). 5,492,247,706 positions, longest DTC 163, longest DTM 229. Both are complete tables rather than WDL, and it downloads without an account:
Code: Select all
ftp://chessdb:chessdb@ftp.chessdb.cn/pub/EGTB_DTC/KNCKAABBN.lzdtc (446 MiB)
ftp://chessdb:chessdb@ftp.chessdb.cn/pub/EGTB_DTM/KNCKAABBN.lzdtm (643 MiB)Your count was close. I make it 7,254,923,760 raw placements against your 12.4 billion. The difference is that the black king can stand on an advisor point or on the elephant point at the palace mouth, and the three free pieces have 84 squares rather than 90. The defender group of king, two advisors and two elephants enumerates to 1,410, which agrees with Wu and Beal's published kaa = 70 for the king and advisors alone. chessdb's index is 5.49 billion, 76% of my raw count. I assume the balance is legality, but their indexing convention is undocumented, so I would not swear to that split.
The restriction argument does not hold here, because the strong side's defenders are not optional:
Code: Select all
Red win% draw% positions
K+C+H 22.31 77.58 5,492,247,706
K+C+H+A 85.48 14.40 24,251,768,055
K+C+H+A+A 86.51 13.23 42,171,693,251
K+C+H+B 28.94 71.03 36,818,495,747
K+C+H+A+B 85.87 14.09 160,900,560,283So the correctly reduced problem is the ten man KANCKAABBN, and that is built too: 24,251,768,055 positions.
The thirteen man version in my post, KAABBNCKAABBN, is in none of the 8,705 tables, and a live probe returns unknown. So the 例胜 claim in the manual is about material nobody has solved, and the reduction of it that has been solved is mostly a draw. My "search or nothing" line was too strong. I will fix it.