I think you would have to remove all those triples from list 1 which have a beProtected that is _better_ or equal in list 1 than list 2, not just equal (when the other two are equal). If in list 1 (after the move) the victim is protected, it is not a chase, even if before the move, or after the evasion it is unprotected. Of course you could do that afterwards, by running through the loop again after you have restricted the number of potentially chased pieces, but when you have the beProtected information available on every move, it is more efficient to do it immediately. I guess you could decide to even not put protected pieces in the list after the chasing move.phhnguyen wrote:- Subtract(list1, list2): remove from list 1 all items which are also in the list 2. This function is used to remove all static attacks which have the same attacker-victim-beProtected.
I also think that you should make the exception of C and H attacks on R straight away. If a static attack of C on R exists, but the R is periodically protected and unprotected, I don't think it should be chase. Protecting a Rook should not count as escaping a H or C attack, and subverting the protection of an already attacked (by C or H) Rook should not count as making a chase. So I think it would be better to use a variabel 'beChased' as the third member of the triplet, rather than 'beProtected', which would not only take account of the protected status, but take immediate account of the CxR, HxR cases on the one hand, and PxAny, KxAny on the other hand. And of the cases RxR, HxH and CxC where a pre-emptive capture is possible. That would save a lot of effort, because you would not have to figure out if the piece is protected in any of these special cases, while testing for the cases is very cheap. (Even in case of the pre-emptive capture between equals, you at least know which piece has to make the capture, making it much cheaper than a test for protection, where you have to search for a protector.)
The in-check case is very tricky. I agree that counting all the pieces of the side that is in check as unprotected leads to counter-intuitive rulings. But I think you are over-doing it by defining them all as protected (when a pseudo-legal recapture exists). It looks very unnatural to count a false protector, that could not really recapture before the check because it was pinned, as a true protector during the check, when it is still pinned. If you really want to treat the in-check case special, I think the furthest yo should go is make a distinction between pseudo-legal recaptures that are illegal because they did not resolve the _existing_ check, and pseudo-legal recaptures that (apart from resolving the existing check or not) create a _new_ check on their own King.
Question: if the back rank looks like
. . . . k . C . c
and white now plays a second Cannon to that rank, attacking both the black King and Cannon:
. . . . k . C C c
Would you want to count this as a chase on the black Cannon? If this situation was not a check (i.e. if the black King was elsewhere), the new attack on the black C would not be considered chase, despite the fact that it is unprotected, because it protects itself by 'self-defence', pre-emptively capturing its attacker. But in the given situation it cannot do that, because it would not resolve the existing check. But if you would not require solving the existing check for a recapture, why would you require it for this self-defence? A complication here is that if the black Cannon is protected by another piece, the recapture would actually be legal despite of the check, because the capture itself resolves the check!
The philosophy of not paying attention to the existing check is based on the idea that before white can actually capture, black must have resolved the check somehow, so he would indeed be free to recapture. But this is very tricky reasoning: it all depends on how black will resolve the check. It could for instnce be that the only way to resolve the check automatically unprotects the piece:
Code: Select all
. . . . k . e . . (before)
r . . . . . h C R
. . . . k . e C . (after)
r . . . . . h . R
Code: Select all
. . . . . . e C . (after evasion)
r . . . k . h . R