Closed ianfab closed 2 years ago
The AXF rule is relatively easy compared to Chinese Xiangqi Federation Rule(in mainland china) though it is still very difficult to understand
My summary of the AXF rules (extrapolated from all the examples, diagram numbers provided with #D)
Executive summary: Perpetual check loses (unless both sides check perpetually, #D4) Perpetual chase usually* loses (see clarifications) Perpetual check+chase is acceptable. (e.g. #D12)
What is a chasing move? An attack on an unprotected piece, or an attack on a chariot by a weaker piece (#D25). Pinned pieces do not protect other pieces (#D83-85). Pinned pieces do not attack other pieces (even if they can legally capture said piece!) (#D63, #D39-41)
Perpetual chase Multiple pieces involved:
1v1 chasing is illegal, unless:
Caveats Chasing suicidal pieces is not really chasing (additional position #D2) ?????? (additional position #D3) I also remember talking to the person who wrote the rules and attempting to point out some uncovered/contradictory cases, but lost my notes on those. These rules should cover most situations though.
Rules used: AXF_rules_Eng.pdf
This issue seems to be closed, but is still advertized as 'help wanted'. So the help might be too late. Let me nevertheless comment on your summary:
I assume that with "even if it can legally captured said piece" you mean "even if it can legally capture its pinner". This has nothing to do with it, however. The issue is whether the attack is new or not; attacks that existed before never count as chases, even when they temporarily were not legal because a check has to be resolved first. It doesn't matter whether you are pinned, but whether the capture is legal, and pinned pieces can have legal captures. It is just that illegal moves should be considered non-existent (except when they are illegal for no other reason than that they do not resolve an existing check).
When you say "bullying is still illegal" it also seems to miss the point. It is perfectly allowed to bully a piece (say a Cannon) with Pawns. Say black has a Cannon on c9, and white Pawns on b8 and d8. Then 1. bc8 Ce9 2. de8 Cb9 3. cb8 Cd9 4. ed8 Cc9 {repeat} 'bullies' the Cannon, but would force a draw if the Cannon for some reason was trapped in the range b9-e9. Because the attacks were made by Pawns, and thus should be ignored. In the examples you quote red is at fault, because even when the attacks by the King are ignored, this King discovers attacks by other pieces. And those attacks do count.
I would summarize the rules as follows:
Logically one would expect that attacks by A or E on a protected R are also chases. The rules do not mention this, though. This could be for 'never-happens' reasons. Although in theory a Rook can be chased by an Elephant through discovered attacks.
@HGMuller this issue is definitely open (green!). Only #179 is closed (as duplicate). :)
I should also have pointed out that 'attacks' should be interpreted as (attacker, victim) pairs rather than as (fromSquare, toSquare) pairs. So an attack by the same piece in another location does not constitute a new attack.
The CXA rule allows fewer draws to be forced by the losing side, but it is significantly harder to program, so most (if not all) engines and computer tournaments, even if they are from/held in China, use the AXF (WXF) rule. The latest version of the AXF rule is named World Xiangqi Rule, published in 2018. There might be some small changes from the AXF rule provided above, but I cannot confirm it, and this tournament held in 2020 still uses the old version (as a Chinese I confirm the 35 rules in the pages are rules 6-40 in the AXF rulebook), so I think it is OK to just use the old pdf provided above. The AXF rules are long partially because the guys who wrote the rules didn't generalize/summarize the rules enough. Perhaps they wanted to make the rules easier to understand using concrete examples instead of longer definitions of e.g. chase, of which I doubt the effectiveness. For example, in CXA rules, "chase" is defined in a way that only if you can gain a piece value advantage after a series of moves are you chasing. Piece value: R = 2H = 2C, H > A = E, R > passed P > any other piece combination because passed P has floating value, unpassed P = 0. If this definition is used, some rules of AXF can be eliminated, and of course attacks by A or E on a protected R are also chases, as HGM pointed out above. I noticed this issue is pinned, so if you have questions about Xiangqi rules feel free to ask :-)
Thanks for the clarification.
I am still struggling to algorithmically define the requirements. E.g., intuitively I would like to write it in a way that I loop through the last moves and check for each pair of position and move whether it qualifies for any criterion (check, chase, kill, etc.) and if so assign that value to it. Given a sequence of position+moves with assigned (potential) violations it would then be relatively easy to evaluate whether the game needs to be adjudicated and how. However, it is unclear to me whether the rules can be represented in such a way, and if so, how fine grained the distinction between different violations needs to be, i.e., whether/how to distinguish different kinds of chases.
Basically I need a way to break down the rules into clear abstractions/interfaces so that the basic concepts (essentially chapters 2 and 3) are understandable on a high level without needing to read through every single rule.
The engine probably already detects check in every position, for reasons other than repetitions (like extending the search). I usually store the in-check flag for every level of the tree, like one stores Zobrist keys for detecting repetitions. When a repetition is detected, I then run through that stack from the repetition to the current position, ANDing the flags of each player, to determine if that player was perpetually checked. From that it follows whether one of the players wins due to perpetual checking, it is a draw (mutual perpetual checking), or that we have to go to the next stage of verification (chasing). Determining whether a piece is being chased is a pain, because it involves legal moves, as well as protection (where checks are defined by pseudo-legal moves, and protecting the King doesn't help). So I only do that when an actual repetition occurs. Which means I have to reconstruct all positions in the loop, to judge them. But since the current position is a repetition in this case, this can be done by replaying the moves in the repeat loop from the current position. For this purpose I also stack the moves played at each level of the tree. (I do that anyway in all my engines, for debugging purposes.) On each position that is thus reconstructed one can do the necessary tests, and keep track of newly attacked defenseless pieces in a set (one bit per piece). By ANDing such sets for all positions in the loop with a specific player on move, you can learn whether any of the pieces of that player was perpetually chased. You can break from the loop as soon as the word gets zero, as then there is no perpetual chase. Again the chase result for both players must be combined to determine the result of the repeat. Sometimes you can skip doing one of the players, because the draw score is out of the search window. Op do., okt. 28, 2021 om 13:50, Fabian Fichter schreef: Thanks for the clarification. I am still struggling to algorithmically define the requirements. E.g., intuitively I would like to write it in a way that I loop through the last moves and check for each pair of position and move whether it qualifies for any criterion (check, chase, kill, etc.) and if so assign that value to it. Given a sequence of position+moves with assigned (potential) violations it would then be relatively easy to evaluate whether the game needs to be adjudicated and how. However, it is unclear to me whether the rules can be represented in such a way, and if so, how fine grained the distinction between different violations needs to be, i.e., whether/how to distinguish different kinds of chases. Basically I need a way to break down the rules into clear abstractions/interfaces so that the basic concepts are understandable on a high level without needing to read through every single rule. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub (https://github.com/ianfab/Fairy-Stockfish/issues/55#issuecomment-953770574), or unsubscribe (https://github.com/notifications/unsubscribe-auth/AFJXANRG3KR3LCBJLYHL2C3UJFBKRANCNFSM4JNS2HGQ). Triage notifications on the go with GitHub Mobile for iOS (https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675) or Android (https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub).
I don't know much about chess engine programming, but I did some research and found out that it is harder than I expected.
First I want to fix a mistake in my last post. You don't need to check piece value loss "after a series of moves" in AXF rules (D#23). That is only required by CXA rules. To lower the difficulty of adjudication the AXF rule doesn't require much calculation (lookahead) to check which side's move is illegal, so both kill(杀) and threat-to-capture-after-check(要抽吃) (D#14) is considered idle(闲) in AXF rules.
Next I want to point out that you can't assign tags like check or chase to moves, and then use just the tags to adjudicate the game, because of the 1vN/Nv1 issue mentioned above by Marken-Foo (see also D#24). So even if both sides have a move sequence tagged [chase, chase], it is still possible that one side's move is legal and the other illegal. (For an imprecise implementation this can be enough; see below)
I checked other Xiangqi engines for rule implementation (eleeye, NewGG). At a glance it seems that both implementations are simple and imprecise and only use the algorithm I described above. You can read their code for detail, although they use Chinese comments that can be hard to understand even if you use Google translate because their contain Xiangqi terms.
The chapter 4 (四、规则) of README.md and issue #5 of eleeye repo contain some valuable information, I'd like to provide a translation below:
README.md
4 Rule Starting from version 2.0, ElephantEye supports "perpetual threat loses", "threat"(打) contains "check" and "chase", in addition to "perpetual check loses". Due to restrictions of programming complexity, only the following three cases is identified as "chase": A. H chases R, or unprotected C or P B. R chases unprotected H or C or P C. C chases R, or unprotected H or P (oringial is "protected", according to the code this is a typo, also the pawns must be across the river) Although ElephantEye may not correctly identify perpetual threat in complicated situations, but since UCCI command "banmoves ..." is supported, once users considers the engine's move illegal, they can use XQWizard's "set banned moves" feature to force the engine to change move.
Issue 5
peteryuanpan commented on 30 Mar 2017 I read the CXA rules for 2 days and read your code. I found that eleeye doesn't analyse for illegal moves, right? It reads the banmoves from the GUI to exclude banned moves. Can the latest XQWizard analyse illegal moves? I remember xqbase.com says it does not support this feature. I read int PositionStruct::ChasedBy(int mv) const function from genmoves.cpp for detection of chase. The function only checks for chase if the last move is R or H or C. According to CXA rule, of cource chase contains more cases. I also notice that eleeye has checks for perpetual checks and perpetual chases, once perpetual checks and perpetual chases occur during searching, it will be pruned. I wonder if it is OK not to add the full set of complicated CXA rule to the engine. Thanks.
auntyellow commented on 30 Mar 2017
README mentions eleeye identifies only perpetual checks but not perpetual chases, but in fact perpetual chases are partially supported later. As you see, it only checks for the most common cases in the AXF rule, there are no checks for other cases such as chasing A or E or P, because it is very complicated. In additional, there are many bugs in ChasedBy, the most typical of which is R chases two cannons on the same time, R will be considered a cannon mount, so the two cannons will be consider protected, so perpetual chase (lose) will be adjudicated as chase of protected piece (draw).
peteryuanpan commented on 4 Apr 2017 Did you fix this bug in paid version of XQWizard engine? I think this is important. I want to ask one more question, Xiangqi Cyclone currently is the strongest engine, does it uses ML?
auntyellow commented on 4 Apr 2017 The bug was fixed in the paid version.
peteryuanpan commented on 4 Apr 2017 I think in theory you can write a program to check for illegal moves, alghough it can be very complicated (I read the 2011 CXA rules and think it is not very clear). Can you publish algorithm/code about the adjudication, or are there publicly available ones? I'm writing a small engine and need to consider this. Thank you very much.
auntyellow commented on 5 Apr 2017 There is no completely precise algorithm for neither AXF or CXA rule, since the rule itself is not very well-defined. Eleeye only contains very simple checks for AXF rule, and can identify more than 90% of perpetual threats. Paid version is more precise for AXF rules, but it is impossible to be 100% precise.
peteryuanpan commented on 6 Apr 2017 I see, thanks. The root cause is the rule itself is not very well-defined.
Op do., okt. 28, 2021 om 17:46, cloudfish schreef: Next I want to point out that you can't assign tags like check or chase to moves, and then use just the tags to adjudicate the game, because of the 1vN/Nv1 issue mentioned above by Marken-Foo (see also D#24). So even if both sides have a move sequence tagged [chase, chase], it is still possible that one side's move is legal and the other illegal. (For an imprecise implementation this can be enough; see below) This is why I said you have to attach such tags to specific pieces, rather than to the position. Which can be conveniently done by reserving a bit for each piece in a word, and setting it in the word associated with a position when it got chased in that position. (I.e. became attacked by a piece that did not attack it in the previous position, while it cannot capture its attacker, or the attacker cannot be recaptured when it would capture, or is a Rook attacked by a lower-valued piece., etc.) Then ANDing all the words for positions with the same player on move in the repeat loop will only leave a bit set when the corresponding piece was attacked on every move in the loop. What makes it costly is that all the moves will have to be tested for legality, also the possible recaptures, which amounts basically to a 3-ply tree (capture, recapture, attempted King capture). And there is the complication for pre-existing checks. It is true the AXF rules are not fully specifying all cases. But I am only aware of two ambiguities. One is the mentioned case of a pre-existing check: piece A attacks defenseless piece B, but cannot legally capture it, because its King is in check, and the capture would not resolve that. Resolving the check in an independent way now would make this AxB capture legal. Yet every Xiangqi player I ever spoke was of the opinion that this should not count as a chase of B. It should be treated as if B was already under attack by A. So this is the implementation XBoard now uses to adjudicate games. The second ambiguity appears in the appendix examples. This appendix introduces the new concept of 'chasing by subverting protection'. As far as I am concerned this is a can of worms, and some of the presented examples are even wrong, because they rule in favor of a player that makes a normal chase in defending against the subversion-of-protection. So I did not implement that kind of chasing, neither in WinBoard nor in HaQiKi D.
There is no completely precise algorithm for neither AXF or CXA rule
I'm starting to believe that there is 100% precise algorithm for the AXF rules now, because I found that chessdb.cn has very good understanding of the AXF rules, perhaps it has already fully implemented the AXF rules. For example, it correctly adjudicates the 1vN/Nv1 situation, and the "chasing by subverting protection" case. You can play with it to test its understanding. (If you place too many pieces, it will say "position not analysed", just ignore it and make moves, it will adjudicate as usual) The rules are crucial to the result of some of the endgames in Xiangqi, so you may want to fully implement it before training an NNUE net, or it might affect the strength of the net once you change the rule :-(
It is true the AXF rules are not fully specifying all cases.
I'm starting to believe that we should not generalize the AXF rules now, because I think they wrote chapter 3 trying to list as few cases as possible, while covering the most common situations. chessdb.cn adjudicates discovered attack of E against protected R to lose, though.
One is the mentioned case of a pre-existing check
This is certainly not a chase to me. This ambiguity does not exist in the longer CXA rules: 26.1.2走动帅(将)应将而产生的“捉”“杀”,按“闲”处理;走动其他子应将后产生新的“捉”或“杀”,按“捉”或“杀”处理。 26.1.2 "Chase" or "kill" generated by moving the general to answer a check should be regarded as "idle"; New "chase" or "kill" generated by moving other pieces to answer a check should be regarded as "chase" or "kill".
The second ambiguity appears in the appendix examples
The first diagram in the "additional illustrations" chapter is a chase both to me and by the CXA rule. Could you give a example in the AXF rule that contradicts the appendix? This result is consistent with the algorithm you proposed, because threatening to capture a protected piece is not a chase (unlessed the attacker is a horse or a cannon and the victim is a chariot), the protection status check should be added to chase detection. So sabotaging protection will generate a new chase for the previously protected piece, and this piece should be marked victim.
I usually store the in-check flag for every level of the tree
Or can we store the chase detection results in the hash table? The data structure of a position should be like [position,[lastMove1,victims1],[lastMove2,victims2],...]. We should consider both the time cost and the extent of changes to Stockfish code when choosing the place to store the chase calculation results, since one of the aims of the project is the ability to easily merge upstream code, although we need a place to store the last moves anyway because last moves are not needed in chess repetition detection. Additionally, if you detect chases only after detecting 3-fold repetitions, you can save some computation. By the way, AXF rule does not specify how many folds of repetitons are needed before you can call the arbiter, but chessdb.cn uses 2, xboard uses 3, CXA uses 3 (technically there is a difference in CXA rule from 3-fold repetition, the explanation is long so I would skip here). And I feel even 3 is not enough because I got a lot of "sudden deaths" or draws when playing on xboard :-( In Xiangqi OTB games at least you are given the chance to change moves when arbiter is called, unlike chess where 3-fold repetition is an immediate draw. But for simplicity we can just use 3 now so we don't need to modify Stockfish's repetition detection code.
Basically I need a way to break down the rules into clear abstractions/interfaces so that the basic concepts are understandable on a high level without needing to read through every single rule.
I think if you have chapter 3 in mind when reading the examples there won't be many examples that surprise you, unlike the CXA rules where most examples are hard... And the rules in chapter 3 fit well in HGM's algorithm.
chessdb.cn adjudicates discovered attack of E against protected R to lose, though.
Can you provide an example of such position?
chessdb.cn adjudicates discovered attack of E against protected R to lose, though.
Can you provide an example of such position?
Hello! Are you the webmaster of chessdb.cn? Thank you for making this fantastic website!
A minimal example would consist of only KCB vs. KRR:
4k4/9/9/9/9/r1r6/3C5/4B4/9/5K3 w moves d3f3 c4g4 f3d3 g4c4 d3f3
Of course the moves here are ridiculous and nowhere near the principle variation. So I spent a little time making the following example, where red can indeed make his situation better if he is allowed to perpetual chase the protected black rook:
3ak4/4a4/9/9/2b6/nnrp2B2/1C1p5/B3N3C/3pA4/pp1A1K3 w moves b3b1 c4c0 b1b3 c0c4 b3b1
Both chessdb and Tiantian Xiangqi adjudicates to black in this situation. I think the AXF rules are to be taken literally and would consider this a bug.
Please refer to "http://www.asianxiangqi.org/English/AXF_rules_Eng.pdf", page 25, section 26 for the description of this particular rule. As I understand it, discovered attacks of cannons and knights do not care about whether the moving piece is a blocker or not, as long as the outcome results in a perpetual chase on a rook, it is a perpetual chase in violation of rules if no other situations(pinned/opponent chases/checks) apply.
The examples I provided are not discovered attacks of cannons; they are discovered attacks of elephants. In fact the term "discovered attack" is not relevant here; programmatically speaking (see also HGMuller's comment above), you only need to consider the new (attacker, victim) pair in the resulting position, which is (red elephant, black rook) in my examples. The mover's type or the blocker's type are not relevant. Per rule 3.(6) on page 4,
"Perpetual chase on a piece with real root will be declared a draw. It is a draw if the protector is a fake root (Translation mistake? Should be 'a loss'). However, perpetual chase on a chariot by a horse or a cannon is prohibited."
if the victim has a real root, it's a perpetual chase only if the (attacker, victim) pair is (horse/cannon, rook).
quanghuy2309 posted this link on Fairy Discord, it may be useful here. https://sci-hub.se/10.3233/icg-180054
The two strongest engines in Xiangqi(cyclone/bugchess) disagree on chase rules
The two strongest engines in Xiangqi(cyclone/bugchess) disagree on chase rules Can you give an example where they disagree?
The two strongest engines in Xiangqi(cyclone/bugchess) disagree on chase rules Can you give an example where they disagree?
A few minimal examples(Added the third strongest engine Alphacat) Chessdb=Bugchess→draw. Cyclone=Alphacat→red violation: 4k4/4a4/4bn3/9/5R3/5C3/9/9/9/4K4 w moves f4e4 e9f9 e4f4 f9e9 chessdb=bugchess=alphacat→draw,Cy→red violation 1RC1k4/9/4n4/9/9/9/9/4B4/9/4K4 w moves b9b7 e7f9 b7b9 f9e7
chessdb=Cy→draw. Bugchess=cat→red violation: 3k5/9/9/9/3nR1p1C/9/9/9/9/4K4 w moves e5e9 d9d8 e9e5 d8d9
chessdb=Cy→red violation. Bugchess=cat→draw: 4k4/9/4n4/9/3c5/9/4N4/9/9/3K5 w moves d0e0 e7c8 e0d0 c8e7 d0e0
And there is still a problem: engine and AXF disagree on chase rules. red violation on diagram 38~41 in AFX,but Cy bugchess chessdb show draw,because both sides chase perpetually.
Another problem: AXF didn't mention of A or B chasing the protected R(engines show violation). There is no mention of A or B chasing the protected N or C.(engines draw)
The first three are what comes out when you open the can of worms I mentioned before. The first position involves subversion of the Advisor protector of the Horse against capture by the Cannon, either by pinning it, or by combining the capture with a discovered check. The second has a plain attack on the Horse, plus a subversion of the protection of that same Horse by its King. In AXF rules it is never an issue whether a piece is protected enough; a single protector makes it free game, even when there are multiple attackers. But with a King as protector a second attacker would make the recapture illegal (rather than ineffective), and thus subverts the protection. Had there would be a Rook instead of a King on e9 moving the Rook to b9 as a second (x-ray) attacker of the Horse would be an 'idle'. The third position involves a chase of the Cannon by subverting its protection by pinning the protector, plus a chase by activating the attacker by unpinning it. This is the one that I am least sure how to handle, because unpinning an attacker seems very similar to 'activating' the existing pseudo-legal attack by resolving pre-existing check: in both cases the attack was temporarily disabled because making the capture would leave your King in check. The fourth perpetual seems a draw to me. The Horse is alternately exposed to an attack by the Rook and the Cannon. (I think that the fact that the Rook checks is irrelevant; moving it to e7 instead of e9 should lead to the same verdict.) But I think the crux here is that black makes no attempt to rescue the Horse in any way after the Rook attacks it. That also makes it a bit unrealistic: normally a piece would be captured on the next move when no attempt is made to solve the threat. I suppose there could be tactical reasons that tie the Rook to the e-file, so that RxH, although legal, is no good. (E.g. another red rook on e2, and a black one on a2, and something between the Horse and King to prevent the capture is accompanied by check, such as an Advisor on d7.) Perhaps the description of chasing that I gave is not complete, and should be accompanied by the rule that a new attack that is not resolved immediately by the opponent is never a chase. essage ID:
the fourth position, N is alternately exposed to an attack by the R and the C,Most CXF refereewill think it's Perpetual chase(AXF should be written in imitation of CXF,CXF has more definitions very bad and is infinitely more complicated than AXF.,CXF referee treats it as legal study.)
The first three are what comes out when you open the can of worms I mentioned before. The first position involves subversion of the Advisor protector of the Horse against capture by the Cannon, either by pinning it, or by combining the capture with a discovered check. The second has a plain attack on the Horse, plus a subversion of the protection of that same Horse by its King. In AXF rules it is never an issue whether a piece is protected enough; a single protector makes it free game, even when there are multiple attackers. But with a King as protector a second attacker would make the recapture illegal (rather than ineffective), and thus subverts the protection. Had there would be a Rook instead of a King on e9 moving the Rook to b9 as a second (x-ray) attacker of the Horse would be an 'idle'. The third position involves a chase of the Cannon by subverting its protection by pinning the protector, plus a chase by activating the attacker by unpinning it. This is the one that I am least sure how to handle, because unpinning an attacker seems very similar to 'activating' the existing pseudo-legal attack by resolving pre-existing check: in both cases the attack was temporarily disabled because making the capture would leave your King in check. The fourth perpetual seems a draw to me. The Horse is alternately exposed to an attack by the Rook and the Cannon. (I think that the fact that the Rook checks is irrelevant; moving it to e7 instead of e9 should lead to the same verdict.) But I think the crux here is that black makes no attempt to rescue the Horse in any way after the Rook attacks it. That also makes it a bit unrealistic: normally a piece would be captured on the next move when no attempt is made to solve the threat. I suppose there could be tactical reasons that tie the Rook to the e-file, so that RxH, although legal, is no good. (E.g. another red rook on e2, and a black one on a2, and something between the Horse and King to prevent the capture is accompanied by check, such as an Advisor on d7.) Perhaps the description of chasing that I gave is not complete, and should be accompanied by the rule that a new attack that is not resolved immediately by the opponent is never a chase. essage ID:
I corrected mine.I mentioned "engine and AXF disagree on chase rules. red violation on diagram 38-41 in AFX,but Cy bugchess chessdb show draw,because both sides chase perpetually" Actually Bugchess→red violation,chessdb=Cy→draw. D38-41 seems to contradict that D81. AFX has been renamed WXF,no change in the chase rules,But the cannon b2 in the D61 has been deleted,Maybe they think D61 is wrong: black side is also chasing the red b2 cannon.
The intent of the Chinese Chess chasing rules is to not allow a repetition. While in “normal” international Chess a repetition is a draw, making it a draw in Chinese Chess would make that game too drawish, so they have implemented a version of the “Ko” rule in Chinese chess, to forbid repetition of position.
Of course, while it’s trivial for a computer to implement “Ko” (e.g. Zillions’ implementation of Chinese Chess makes the third repetition of a given position a lost for the player who repeats a position too many times), doing so in a human game is non-trivial, so instead we have a very subjective series of rules which amount to the same thing. Since the rules are designed for human and not computer play, and since, as I understand it, two different referees can come up with different judgments for a given position, it just isn’t going to be possible to get these rules exactly right in a computer implementation of Chinese Chess.
This we cannot get 100% right because the rules are subjective, not objective. I personally would allow various ways to implement these rules, including a simple “Ko” implementation (not allow one to make a move that results in a position already seen).
(EDIT: A simple "Ko" rule will sometimes punish the chased, not the chaser. See discussion below using Fischer-Tal Leipzig 1960 as an example)
Declaring a loss for the first player that repeats (too many times) completely changes the spirit of the rule. Which is that the player who forces the repetition should be punished. It would dramatically change the character of the game, shifting focus to gaining material by forcing the opponent to break off being chased, and surrender the chased material. Chasing plays a significant rule in xiangqi; when I played an engine that implemented the full chasing rules against one that scored all chases as a draw, 18% of the games were forfeited by chasing. A more sensible approximate algorithm would be to determine who has the better score on his best opportunity for leaving the loop, and declare that side to lose. But that ignores the fact that 1-chases-many (or on check, one chase) is considered a valid way to force a draw. But at least it would not alter the character of the game much. This is all a bit off topic; the issue here is how to implement the rules for the game as official game organizations decided they should be. Not to specify better or more convenient rules. Op ma., mrt. 28, 2022 om 01:23, Sam Trenholme schreef: The intent of the Chinese Chess chasing rules is to not allow a repetition. While in “normal” international Chess a repetition is a draw, making it a draw in Chinese Chess would make that game too drawish, so they have implemented a version of the “Ko” rule in Chinese chess, to forbid repetition of position. Of course, while it’s trivial for a computer to implement “Ko” (e.g. Zillions’ implementation of Chinese Chess makes the third repetition of a given position a lost for the player who repeats a position too many times), doing so in a human game is non-trivial, so instead we have a very subjective series of rules which amount to the same thing. Since the rules are designed for human and not computer play, and since, as I understand it, two different referees can come up with different judgments for a given position, it just isn’t going to be possible to get these rules exactly right in a computer implementation of Chinese Chess. This we can get 100% right because the rules are subjective, not objective. I personally would allow various ways to implement these rules, including a simple “Ko” implementation (not allow one to make a move that results in a position already seen). — Reply to this email directly, view it on GitHub (https://github.com/ianfab/Fairy-Stockfish/issues/55#issuecomment-1080042619), or unsubscribe (https://github.com/notifications/unsubscribe-auth/AFJXANSPYCSIO5KTHWOZJA3VCDUVVANCNFSM4JNS2HGQ). You are receiving this because you were mentioned.Message ID:
@H.G. Huller Thank you for the reply.
I have looked at a famous Chess game to show if implementing Ko would stop a piece from being needlessly chased (a perpetual check); I’m using Chess so the example is more clear since it’s a more well known game.
In this 1960 game played at Leipzig, Fischer was White and Tal was Black:
And we now have this position with Black to play:
-+ are empty squares, upper case is Black, lower case is White
-+K+-+-+
PP+-N-+q
-+-+Q+-+
p-+P+-+-
-+-+-+-+
p-P-+-+-
-+p+-pkp
+-+-+r+-
For people who want to see it on a graphic chessboard, check out https://www.chessgames.com/perl/chessgame?gid=1008399 or https://lichess.org/AOw7cUIn#41
Now, let’s start the chase; White (Fischer) is ahead, but Black (Tal) can force a draw by chasing White’s king:
21... Qg4+ (Draw was declared in the played game at this point, but let’s play it out) The Black Queen is on g4, and the White King is on g2; I will note that as Q@g4 K@g2 to keep things compact as we continue this perpetual check
OK, so I think we can agree that Black started the chase to draw a lost position, and that White was being chased. That in mind, let us imagine a Chess variant with a “Ko” rule.
Tal looks at the position and plays Qg4+. Fisher plays the only legal move, Kh1. Tal now plays Qf3+ Fisher has to play Kg1 Tal then plays Qg4+ -- a position not seen yet. Now, Fischer is forced to, in this chase, repeat a previous position, but it’s Tal, not Fischer who started the chase.
In Chess variant with Chinese chess’s chasing rules, since it’s Tal who started the chase, Tal needs to make a different move to stop the repetition of moves, even though it’s Fischer who first repeats a position seen before.
OK, so we agree Tal should be the one to stop the chase; that’s easy for a human to see. Now, how to make objective rules so a computer sees it? That’s why this discussion is so long.
(Edit: Fix numbering, no other changes)
Your example is not really relevant, because the discussion is about chasing, not about checking. Bot in any case you can see that the simple Ko rule does not work: it is white that repeats first here, because his King was on g2 during the first check, rather than g1. While it is obvious that black is the player that forces the repeat. Not only to a human, but also to a computer: on every move of the repeat loop white is in check. The point is that determining whether a player is in check or not is an absolutely objective task, as easily performed by a human as by a computer. And that the rules of the game guarantee the attack on the King can never have been pre-existing, and that it does not matter whether the checking piece is pinned to its own King, or whether the King is protected. So adjudicating perpetual checks is always trivial. But to outlaw perpetually renewing attacks on any other piece you somehow have to define what a chase is: unlike a check, the concept of a chase is not defined in the basic (FIDE-like) rules. Not every pseudo-legal attack on a non-royal piece can be considered a threat that has to be acted on in order to prevent significant loss of material. (It is even subjective what 'significant' means here; apparently loss of an unpassed Pawn was not considered significant by those who drew up the rules.) The attack might not be legal, the attack can be futile because the attacked piece is protected and of equal or lower value than the attacker, the attack might have been pre-existing. To judge this requires a judgement on piece values, which also have no basis in the game rules.
Checking is a form a chasing. But, yes, this has become a side show and not relevant to the Xiangqi situation. While I myself have just come up with a rigorous way of defining who the attacker is in a loop of moves for my current Chess variant invention, discussion of that is off topic for this bug; that said, I have appreciated the discussion because it has allowed me to come up with a better Ko rule to stop an attacker who tries to draw a lost position with repetition of move for my current variant.
作者你好,对于Fairy-Stockfish-nnue存在的长久追逐规则问题,我查找了一些资料,在附件中有我上传的两个文档,这两个文档来源于2020年中国象棋竞赛规则电子版,它们包含长久追逐的一些术语解释,以及一些象棋追逐局面的具体示例,希望能对弥补Fairy-Stockfish-nnue的规则缺陷起到帮助! 2020中国象棋追逐规则.pdf 象棋追逐规则具体实例.pdf
Both documents are about CXA rules, not AXF rules. CXA rules are much harder to implement and afaik there are no mainstream Xiangqi engine that obey the CXA rules, and the CXA rules are rarely used outside of China. So the AXF rules should perhaps take precedence here. 这两个文档都是中国规则,不是亚洲规则。中国规则非常难以编程实现,而且目前应该没有象棋引擎支持中国规则(如果你知道支持中国规则的棋软,欢迎补充信息),而且国外也基本不用中国规则,所以应该是先实现亚洲规则比较合适。
亚规都已经讨论过了,存在模糊分歧的一些概念,似乎没有什么统一意见。而国规太主观不可能编程的。 我以前测试过,旋风小虫猫的棋规都不一样,在一些特定循环下。
Thanks. Could someone please give a brief summary of which are the most frequently occurring cases of chasing, i.e., which ones are most important to implement?
I never took statistics of that. Virtually all chasing is through 4-ply loops, though. Pretty common is chasing of H or C by R, presumably because R is the most powerful piece, H is pretty clumsy, and C has the misfortune of moving the same as R, which limits the choice for getting out of its path. Chases by C through moving the mounts are also pretty common. I am not sure whether ther will be any solace in a partial implementation. Because even to recognize the most common cases you still have to do all the tests. Chasing of R by C or H is relatively easy, because it doesn't matter whether the R is protected. But you would still have to ascertain the attacker is not pinned. (And it is more difficult for a H to chase a Rook than vice versa, so presumably it will occur not so frequently.) For attacks on other pieces you would still have to test whether the piece is protected, and whether that recapture would be legal rather than just pseudo-legal. It is presumably not very common that pieces are pinned, so a simplification would be to forego the legality tests, and count all pseudo-legal attackers and protectors.
You’re probably going to think I’m having a high fever, but… I think chasing should be left to third-party human adjudication. The rules are simply too nuanced for a computer.
On Wed, Apr 13, 2022 at 3:22 PM Fabian Fichter @.***> wrote:
Thanks. Could someone please give a brief summary of which are the most frequently occurring cases of chasing, i.e., which ones are most important to implement?
— Reply to this email directly, view it on GitHub https://github.com/ianfab/Fairy-Stockfish/issues/55#issuecomment-1098450814, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXTR5WRN6SZX743APXKPKQTVE4UJLANCNFSM4JNS2HGQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>
Thanks. Could someone please give a brief summary of which are the most frequently occurring cases of chasing, i.e., which ones are most important to implement?
I have summarized perpetual chasing rules supported by eleeye in https://github.com/ianfab/Fairy-Stockfish/issues/55#issuecomment-953972294 . These will cover most cases. Although the infrastructures of fairy-sf and eleeye are completely different, the source code of eleeye's perpetual checking detection can be useful. It's at https://github.com/xqbase/eleeye/blob/master/eleeye/genmoves.cpp (the PositionStruct::Protected and PositionStruct::ChasedBy functions)
你好,以下是我对亚规的个人理解,不过我不太懂英语,没法以英文形式写出。 亚规中的一些没说清楚的地方,我就按可能的我认为的编写者本意精确了,可能存在疏漏谬误。 亚规图39到41我是圆不回来,黑不算捉的理由和图105矛盾了,我个人理解抛弃图39到41。 以下大写RCNKP分别为车炮马帅(将) 兵(卒)
1.有根、无根的判断: 一方的x子如果吃了另一方的除了K和未过河P外的y子,如果另一方有其他子可以立刻合法地吃了x,则y是有根子。如果另一方没有子能立刻合法地吃了x,则y是无根子。 2.吃子关系: 其中一方对另一方的吃子关系为:视同轮到这一方走棋(如果这一方已经造成将军,暂且无视之),这一方任意一个除了K和P外的x子可以合法地吃掉对方的无根子y(包含无根R)和有根R,则吃子关系为x→y或x→有根R。如果有更多的x/y/有根R,则分别形成一对一的吃子关系,比如x→y,x→有根R,x2→y,x2→y2....,但是R→有根R的关系是不存在的。 同时R→无根R/N→N/C→C的吃子关系必须再判断:轮另一方走棋,另一方的无根R/N/C能否合法地吃掉这一方的R/N/C,如果能,则相关的吃子关系不成立。 (上述吃子关系的每个子都是独一无二的,并不是兵种) 3.长将、长捉的判断: 3.1 长将:循环局面中,如果一方每步都是将军,则该方为长将。 3.2 长捉:循环局面中,把一方走子后对另一方的吃子关系和其走子前对另一方的吃子关系进行比较,是否存在新增的吃子关系。 如果该方每一步都有新增的吃子关系,则比较吃子关系中的被吃子,所有新增吃子关系中均存在至少一个相同的被吃子,则该方为长捉。 4.循环一方违规或者和棋的判断: 三个级别按严重度:长将>长捉>非长将或长捉。 双方均为相同级别的着法则和棋。(若一方同时存在长将和长捉,视为长将)
If you want to make a partial implementation that catches many cases, and don't care whether the wrong calls it makes are overlooking chases or seeing false chases, the obvious (and huge) simplification would be to omit legality checking of the moves. Most pseudo-legal moves are also legal, so the majority of the calls would be correct. For efficiency:
only start classifying moves as chases along the repeat loop when you reach a repetition, since repetitions are rare.
diversify the chases per target. A check is a check, but a chase of a Rook is not the same as a chase of another Rook. There are 15 different pieces that could be chased. If you record this with 16 bit-flags packed in a word, (which could be a bitboard, if you correct for displacement of the moving pieces) you can AND all words for the positions in the loop with the same side to move to see if he was being chased. You can abort this loop whenever the word reaches 0.
at the core of the algorithm is a routine that determines new (pseudo-legal) attacks: direct attacks by the moved piece from its new location, discovered attacks by Rooks, Cannons, Horses or Elephants over the evacuated square, and Cannon moves over the destination square. Note that sliders only have new direct attacks in the direction perpendicular to their move.
any new pseudo-legal attack on the King is a check.
other direct attacks by P or K don't need to be recorded, as P and K are allowed to chase. (But P is not allowed to perpetually check!) The discovered or activated attacks made by their moves should be counted, though.
attacks on an unpassed P can be ignored. You could clear their bits in the chase-flag word to start with, to make it reach 0 as quickly as possible.
testing for protection is expensive; better leave it for a second iteration through the repeat loop, in the hope that no pieces were newly attacked on every move of the repeat loop. Only after the first iteration leaves us with such 'chase candidates' (and the King is not one of those) we have to do iteration 2.
If a chase candidate is a Rook, and there is a Horse or Cannon amongst the new attackers, there is no need to test for protection, and the chase stands.
Attackers that are of equal type as the chase candidate can be ignored, except in the case H->H where the reverse attack is blocked. If there were no other attackers the chase is discarded. In an algorithm purely based on pseudo-legal moves this could already have been done in iteration 1, but in a full algorithm it would also have to be tested whether the reverse capture is legal. Which is expensive, and therefore better deferred to iteration 2, in the hope it doesn't have to be done at all.
For the remaining attacks we have to determine whether the chase candidate was protected. This has to be done for each attack separately, as pieces can be protected against capture by one attacker, but not of the other. In particular, one of the attackers could block an X-ray protector. (In a full algorithm the capture with one of the attackers could discover a pin of the protector that would be good against other captures.) So you have to judge whether recapture is possible after the capture by the new attacker is made. In the pseudo-legal algorithm: if a protector exists in the position before any capture, the chase is discarded. If no protector exist, and there are E, or H amongst the attackers, the chase stands. In the remaining cases all A, C and R attacks have to be tested for an X-ray protector. (A can discover a H!)
Discarded chases are masked out of the chase-flags word, and when it reaches 0 that playerw as not chased. If at the end of the loop a non-zero remains, that player was chased. This algorithm can be easily upgraded to one based on legal moves, by inserting legality testing for all of the pseudo-legal moves. First test whether recaptures or self-defense captures are legal, as usually they are, and that would then rule out the chase without further testing. Only for defenseless pieces you would have to test whether the attack itself was legal. (Which has only a low probability to rule out the chase.)
原来如此,我刚才找了关于亚洲规则的简单介绍(http://www.dpxq.com/hldcg/AXFRules/)。 另外一方面就是,如果你的Fairy-Stockfish-NNUE缺少训练量的话,象棋程序的水平提高会比较缓慢,我建议可以弄一个分布式训练程序,让大家能利用自己的电脑一起参与训练,这样Fairy-Stockfish-NNUE的水平会飞速进步,有一个叫ggzero的象棋程序使用过这种方法(http://www.ggzero.cn/forum.php),当然,因为ggzero的作者并没有投入很多精力去优化程序的算法,所以即使有很多人参与跑谱训练,ggzero的水平也仅仅是免费最强,难以抗衡商业象棋软件。 … ------------------ 原始邮件 ------------------ 发件人: "ianfab/Fairy-Stockfish" @.>; 发送时间: 2022年4月6日(星期三) 凌晨0:06 @.>; @.**@.>; 主题: Re: [ianfab/Fairy-Stockfish] Xiangqi chasing rules (#55) 作者你好,对于Fairy-Stockfish-nnue存在的长久追逐规则问题,我查找了一些资料,在附件中有我上传的两个文档,这两个文档来源于2020年中国象棋竞赛规则电子版,它们包含长久追逐的一些术语解释,以及一些象棋追逐局面的具体示例,希望能对弥补Fairy-Stockfish-nnue的规则缺陷起到帮助! 2020中国象棋追逐规则.pdf 象棋追逐规则具体实例.pdf Both documents are about CXA rules, not AXF rules. CXA rules are much harder to implement and afaik there are no mainstream Xiangqi engine that obey the CXA rules, and the CXA rules are rarely used outside of China. So the AXF rules should perhaps take precedence here. 这两个文档都是中国规则,不是亚洲规则。中国规则非常难以编程实现,而且目前应该没有象棋引擎支持中国规则(如果你知道支持中国规则的棋软,欢迎补充信息),而且国外也基本不用中国规则,所以应该是先实现亚洲规则比较合适。 — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
看见加我qq1272220882
Support more chasing rules besides perpetual check. The exact set of chasing rules to be supported is an open question.
References: http://wxf.ca/wxf/doc/book/WXF_rules_Eng.pdf http://www.xqinenglish.com/images/Downloads/ChineseChessRules.pdf http://www.asianxiangqi.org/English/AXF_rules_Eng.pdf http://www.talkchess.com/forum3/viewtopic.php?t=35403
An eventual implementation could potentially also be used for Janggi #142.