New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Xiangqi chasing rules #55
Comments
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: What is a chasing move? Perpetual chase
1v1 chasing is illegal, unless:
Caveats 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. |
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. |
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 (#55 (comment)), 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 Issue 5 peteryuanpan commented on 30 Mar 2017 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. peteryuanpan commented on 4 Apr 2017 auntyellow commented on 4 Apr 2017 peteryuanpan commented on 4 Apr 2017 auntyellow commented on 5 Apr 2017 peteryuanpan commented on 6 Apr 2017 |
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.
|
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)
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.
This is certainly not a chase to me. This ambiguity does not exist in the longer CXA rules:
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?
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.
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. |
Can you provide an example of such position? |
A few minimal examples(Added the third strongest engine Alphacat) chessdb=Cy→draw. Bugchess=cat→red violation: chessdb=Cy→red violation. Bugchess=cat→draw: And there is still a problem: Another problem: |
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.) |
I corrected mine.I mentioned |
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 (#55 (comment)), 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
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. 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. |
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
<#55 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AXTR5WRN6SZX743APXKPKQTVE4UJLANCNFSM4JNS2HGQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
I have summarized perpetual chasing rules supported by eleeye in #55 (comment) . These will cover most cases. |
你好,以下是我对亚规的个人理解,不过我不太懂英语,没法以英文形式写出。 1.有根、无根的判断: |
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.)
|
看见加我qq1272220882 |
Add basic support for AXF chasing rules. Some of the more complex cases are not handled yet. Closes #55.
Add basic support for AXF chasing rules. Some of the more complex cases are not handled yet. Closes #55.
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.
The text was updated successfully, but these errors were encountered: