Open jacksonthall22 opened 3 months ago
Bishop moves can be impossible. An example is Ba1c3+ The bishop can't make a discovery attack because it started off in the corner I'm sorry I can't do much else to help, but I can try and filter out the impossible moves manually
I think I got everything. I triple checked it and it looks good, but please check it yourself. Here is every invalid move that should be removed:
"Ba1b2+", "Ba1b2#", "Ba1c3+", "Ba1c3#", "Ba1d4+", "Ba1d4#", "Ba8b7+", "Ba8b7#", "Ba8c6+", "Ba8c6#", "Ba8d5+", "Ba8d5#", "Bh1e4+", "Bh1e4#", "Bh1f3+", "Bh1f3#", "Bh1g2+", "Bh1g2#", "Bh8e5+", "Bh8e5#", "Bh8f6+", "Bh8f6#", "Bh8g7+", "Bh8g7#", "Qa1h8+", "Qa1h8#", "Qa8h1+", "Qa8h1#", "Qb2a1+", "Qb2a1#", "Qb2h8+", "Qb2h8#", "Qb7a8+", "Qb7a8#", "Qb7h1+", "Qb7h1#", "Qc3a1+", "Qc3a1#", "Qc3h8+", "Qc3h8#", "Qc4a2+", "Qc4a2#", "Qc5a7+", "Qc5a7#", "Qc6a8+", "Qc6a8#", "Qc6h1+", "Qc6h1#", "Qd3b1+", "Qd3b1#", "Qd4a1+", "Qd4a1#", "Qd4b2+", "Qd4b2#", "Qd4h8+", "Qd4h8#", "Qd5a8+", "Qd5a8#", "Qd5b7+", "Qd5b7#", "Qd5h1+", "Qd5h1#", "Qd6b8+", "Qd6b8#", "Qe3g1+", "Qe3g1#", "Qe4a8+", "Qe4a8#", "Qe4g2+", "Qe4g2#", "Qe4h1+", "Qe4h1#", "Qe5a1+", "Qe5a1#", "Qe5g7+", "Qe5g7#", "Qe5h8+", "Qe5h8#", "Qe6g8+", "Qe6g8#", "Qf3a8+", "Qf3a8#", "Qf3h1+", "Qf3h1#", "Qf4h2+", "Qf4h2#", "Qf5h7+", "Qf5h7#", "Qf6a1+", "Qf6a1#", "Qf6h8+", "Qf6h8#", "Qg2a8+", "Qg2a8#", "Qg2h1+", "Qg2h1#", "Qg7a1+", "Qg7a1#", "Qg7h8+", "Qg7h8#", "Qh1a8+", "Qh1a8#", "Qh8a1+", "Qh8a1#"
Looks like I forgot the moves with captures, here's actually everything:
"Ba1b2+", "Ba1b2#", "Ba1c3+", "Ba1c3#", "Ba1d4+", "Ba1d4#", "Ba8b7+", "Ba8b7#", "Ba8c6+", "Ba8c6#", "Ba8d5+", "Ba8d5#", "Bh1e4+", "Bh1e4#", "Bh1f3+", "Bh1f3#", "Bh1g2+", "Bh1g2#", "Bh8e5+", "Bh8e5#", "Bh8f6+", "Bh8f6#", "Bh8g7+", "Bh8g7#", "Qa1h8+", "Qa1h8#", "Qa8h1+", "Qa8h1#", "Qb2a1+", "Qb2a1#", "Qb2h8+", "Qb2h8#", "Qb7a8+", "Qb7a8#", "Qb7h1+", "Qb7h1#", "Qc3a1+", "Qc3a1#", "Qc3h8+", "Qc3h8#", "Qc4a2+", "Qc4a2#", "Qc5a7+", "Qc5a7#", "Qc6a8+", "Qc6a8#", "Qc6h1+", "Qc6h1#", "Qd3b1+", "Qd3b1#", "Qd4a1+", "Qd4a1#", "Qd4b2+", "Qd4b2#", "Qd4h8+", "Qd4h8#", "Qd5a8+", "Qd5a8#", "Qd5b7+", "Qd5b7#", "Qd5h1+", "Qd5h1#", "Qd6b8+", "Qd6b8#", "Qe3g1+", "Qe3g1#", "Qe4a8+", "Qe4a8#", "Qe4g2+", "Qe4g2#", "Qe4h1+", "Qe4h1#", "Qe5a1+", "Qe5a1#", "Qe5g7+", "Qe5g7#", "Qe5h8+", "Qe5h8#", "Qe6g8+", "Qe6g8#", "Qf3a8+", "Qf3a8#", "Qf3h1+", "Qf3h1#", "Qf4h2+", "Qf4h2#", "Qf5h7+", "Qf5h7#", "Qf6a1+", "Qf6a1#", "Qf6h8+", "Qf6h8#", "Qg2a8+", "Qg2a8#", "Qg2h1+", "Qg2h1#", "Qg7a1+", "Qg7a1#", "Qg7h8+", "Qg7h8#", "Qh1a8+", "Qh1a8#", "Qh8a1+", "Qh8a1#", "Ba1xb2+", "Ba1xb2#", "Ba1xc3+", "Ba1xc3#", "Ba1xd4+", "Ba1xd4#", "Ba8xb7+", "Ba8xb7#", "Ba8xc6+", "Ba8xc6#", "Ba8xd5+", "Ba8xd5#", "Bh1xe4+", "Bh1xe4#", "Bh1xf3+", "Bh1xf3#", "Bh1xg2+", "Bh1xg2#", "Bh8xe5+", "Bh8xe5#", "Bh8xf6+", "Bh8xf6#", "Bh8xg7+", "Bh8xg7#", "Qa1xh8+", "Qa1xh8#", "Qa8xh1+", "Qa8xh1#", "Qb2xa1+", "Qb2xa1#", "Qb2xh8+", "Qb2xh8#", "Qb7xa8+", "Qb7xa8#", "Qb7xh1+", "Qb7xh1#", "Qc3xa1+", "Qc3xa1#", "Qc3xh8+", "Qc3xh8#", "Qc4xa2+", "Qc4xa2#", "Qc5xa7+", "Qc5xa7#", "Qc6xa8+", "Qc6xa8#", "Qc6xh1+", "Qc6xh1#", "Qd3xb1+", "Qd3xb1#", "Qd4xa1+", "Qd4xa1#", "Qd4xb2+", "Qd4xb2#", "Qd4xh8+", "Qd4xh8#", "Qd5xa8+", "Qd5xa8#", "Qd5xb7+", "Qd5xb7#", "Qd5xh1+", "Qd5xh1#", "Qd6xb8+", "Qd6xb8#", "Qe3xg1+", "Qe3xg1#", "Qe4xa8+", "Qe4xa8#", "Qe4xg2+", "Qe4xg2#", "Qe4xh1+", "Qe4xh1#", "Qe5xa1+", "Qe5xa1#", "Qe5xg7+", "Qe5xg7#", "Qe5xh8+", "Qe5xh8#", "Qe6xg8+", "Qe6xg8#", "Qf3xa8+", "Qf3xa8#", "Qf3xh1+", "Qf3xh1#", "Qf4xh2+", "Qf4xh2#", "Qf5xh7+", "Qf5xh7#", "Qf6xa1+", "Qf6xa1#", "Qf6xh8+", "Qf6xh8#", "Qg2xa8+", "Qg2xa8#", "Qg2xh1+", "Qg2xh1#", "Qg7xa1+", "Qg7xa1#", "Qg7xh8+", "Qg7xh8#", "Qh1xa8+", "Qh1xa8#", "Qh8xa1+", "Qh8xa1#"
Hey, thanks! Can you share the code you used to generate this? That logic is ultimately how we should decide if the list is right. Or feel free to fork and submit a PR.
Ok im actually completely new to github and don't know how to write programs. I did this all manually. Also i discovered that i messed it up once again, because i found out that captures can allow for a piece to block, and then be captured to reveal a check, making some moves that i listed actually possible. I am very sorry, as you probably expected actual solid proof and all you got was this
anyways here's the updated list:
"Ba1b2+", "Ba1b2#", "Ba1c3+", "Ba1c3#", "Ba1d4+", "Ba1d4#", "Ba8b7+", "Ba8b7#", "Ba8c6+", "Ba8c6#", "Ba8d5+", "Ba8d5#", "Bh1e4+", "Bh1e4#", "Bh1f3+", "Bh1f3#", "Bh1g2+", "Bh1g2#", "Bh8e5+", "Bh8e5#", "Bh8f6+", "Bh8f6#", "Bh8g7+", "Bh8g7#", "Qa1h8+", "Qa1h8#", "Qa8h1+", "Qa8h1#", "Qb2a1+", "Qb2a1#", "Qb2h8+", "Qb2h8#", "Qb7a8+", "Qb7a8#", "Qb7h1+", "Qb7h1#", "Qc3a1+", "Qc3a1#", "Qc3h8+", "Qc3h8#", "Qc4a2+", "Qc4a2#", "Qc5a7+", "Qc5a7#", "Qc6a8+", "Qc6a8#", "Qc6h1+", "Qc6h1#", "Qd3b1+", "Qd3b1#", "Qd4a1+", "Qd4a1#", "Qd4b2+", "Qd4b2#", "Qd4h8+", "Qd4h8#", "Qd5a8+", "Qd5a8#", "Qd5b7+", "Qd5b7#", "Qd5h1+", "Qd5h1#", "Qd6b8+", "Qd6b8#", "Qe3g1+", "Qe3g1#", "Qe4a8+", "Qe4a8#", "Qe4g2+", "Qe4g2#", "Qe4h1+", "Qe4h1#", "Qe5a1+", "Qe5a1#", "Qe5g7+", "Qe5g7#", "Qe5h8+", "Qe5h8#", "Qe6g8+", "Qe6g8#", "Qf3a8+", "Qf3a8#", "Qf3h1+", "Qf3h1#", "Qf4h2+", "Qf4h2#", "Qf5h7+", "Qf5h7#", "Qf6a1+", "Qf6a1#", "Qf6h8+", "Qf6h8#", "Qg2a8+", "Qg2a8#", "Qg2h1+", "Qg2h1#", "Qg7a1+", "Qg7a1#", "Qg7h8+", "Qg7h8#", "Qh1a8+", "Qh1a8#", "Qh8a1+", "Qh8a1#", "Qa1xh8+", "Qa1xh8#", "Qa8xh1+", "Qa8xh1#", "Qb2xa1+", "Qb2xa1#", "Qb2xh8+", "Qb2xh8#", "Qb7xa8+", "Qb7xa8#", "Qb7xh1+", "Qb7xh1#", "Qc3xa1+", "Qc3xa1#", "Qc3xh8+", "Qc3xh8#", "Qc6xa8+", "Qc6xa8#", "Qc6xh1+", "Qc6xh1#", "Qd4xa1+", "Qd4xa1#", "Qd4xh8+", "Qd4xh8#", "Qd5xa8+", "Qd5xa8#", "Qd5xh1+", "Qd5xh1#", "Qe4xa8+", "Qe4xa8#", "Qe4xh1+", "Qe4xh1#", "Qe5xa1+", "Qe5xa1#", "Qe5xh8+", "Qe5xh8#", "Qf3xa8+", "Qf3xa8#", "Qf3xh1+", "Qf3xh1#", "Qf6xa1+", "Qf6xa1#", "Qf6xh8+", "Qf6xh8#", "Qg2xa8+", "Qg2xa8#", "Qg2xh1+", "Qg2xh1#", "Qg7xa1+", "Qg7xa1#", "Qg7xh8+", "Qg7xh8#", "Qh1xa8+", "Qh1xa8#", "Qh8xa1+", "Qh8xa1#"
I can at least show you my logic if that helps
I discovered that moves like Raa1+ and Raa1# are also impossible, so I added them to my list. Yeah im really sorry and this probably isn't helpful. Im just making a fool of myself at this point, but i'll keep updating my list and posting it here when i inevitably find something new i missed:
"Raa1+", "Raa1#", "Raa2+", "Raa2#", "Raa3+", "Raa3#", "Raa4+", "Raa4#", "Raa5+", "Raa5#", "Raa6+", "Raa6#", "Raa7+", "Raa7#", "Raa8+", "Raa8#", "Rah1+", "Rah1#", "Rah2+", "Rah2#", "Rah3+", "Rah3#", "Rah4+", "Rah4#", "Rah5+", "Rah5#", "Rah6+", "Rah6#", "Rah7+", "Rah7#", "Rah8+", "Rah8#", "Rha1+", "Rha1#", "Rha2+", "Rha2#", "Rha3+", "Rha3#", "Rha4+", "Rha4#", "Rha5+", "Rha5#", "Rha6+", "Rha6#", "Rha7+", "Rha7#", "Rha8+", "Rha8#", "Rhh1+", "Rhh1#", "Rhh2+", "Rhh2#", "Rhh3+", "Rhh3#", "Rhh4+", "Rhh4#", "Rhh5+", "Rhh5#", "Rhh6+", "Rhh6#", "Rhh7+", "Rhh7#", "Rhh8+", "Rhh8#", "Ba1b2+", "Ba1b2#", "Ba1c3+", "Ba1c3#", "Ba1d4+", "Ba1d4#", "Ba8b7+", "Ba8b7#", "Ba8c6+", "Ba8c6#", "Ba8d5+", "Ba8d5#", "Bh1e4+", "Bh1e4#", "Bh1f3+", "Bh1f3#", "Bh1g2+", "Bh1g2#", "Bh8e5+", "Bh8e5#", "Bh8f6+", "Bh8f6#", "Bh8g7+", "Bh8g7#", "Qa1h8+", "Qa1h8#", "Qa8h1+", "Qa8h1#", "Qb2a1+", "Qb2a1#", "Qb2h8+", "Qb2h8#", "Qb7a8+", "Qb7a8#", "Qb7h1+", "Qb7h1#", "Qc3a1+", "Qc3a1#", "Qc3h8+", "Qc3h8#", "Qc4a2+", "Qc4a2#", "Qc5a7+", "Qc5a7#", "Qc6a8+", "Qc6a8#", "Qc6h1+", "Qc6h1#", "Qd3b1+", "Qd3b1#", "Qd4a1+", "Qd4a1#", "Qd4b2+", "Qd4b2#", "Qd4h8+", "Qd4h8#", "Qd5a8+", "Qd5a8#", "Qd5b7+", "Qd5b7#", "Qd5h1+", "Qd5h1#", "Qd6b8+", "Qd6b8#", "Qe3g1+", "Qe3g1#", "Qe4a8+", "Qe4a8#", "Qe4g2+", "Qe4g2#", "Qe4h1+", "Qe4h1#", "Qe5a1+", "Qe5a1#", "Qe5g7+", "Qe5g7#", "Qe5h8+", "Qe5h8#", "Qe6g8+", "Qe6g8#", "Qf3a8+", "Qf3a8#", "Qf3h1+", "Qf3h1#", "Qf4h2+", "Qf4h2#", "Qf5h7+", "Qf5h7#", "Qf6a1+", "Qf6a1#", "Qf6h8+", "Qf6h8#", "Qg2a8+", "Qg2a8#", "Qg2h1+", "Qg2h1#", "Qg7a1+", "Qg7a1#", "Qg7h8+", "Qg7h8#", "Qh1a8+", "Qh1a8#", "Qh8a1+", "Qh8a1#", "Raxa1+", "Raxa1#", "Raxa8+", "Raxa8#", "Raxh1+", "Raxh1#", "Raxh8+", "Raxh8#", "Rhxa1+", "Rhxa1#", "Rhxa8+", "Rhxa8#", "Rhxh1+", "Rhxh1#", "Rhxh8+", "Rhxh8#", "Qa1xh8+", "Qa1xh8#", "Qa8xh1+", "Qa8xh1#", "Qb2xa1+", "Qb2xa1#", "Qb2xh8+", "Qb2xh8#", "Qb7xa8+", "Qb7xa8#", "Qb7xh1+", "Qb7xh1#", "Qc3xa1+", "Qc3xa1#", "Qc3xh8+", "Qc3xh8#", "Qc6xa8+", "Qc6xa8#", "Qc6xh1+", "Qc6xh1#", "Qd4xa1+", "Qd4xa1#", "Qd4xh8+", "Qd4xh8#", "Qd5xa8+", "Qd5xa8#", "Qd5xh1+", "Qd5xh1#", "Qe4xa8+", "Qe4xa8#", "Qe4xh1+", "Qe4xh1#", "Qe5xa1+", "Qe5xa1#", "Qe5xh8+", "Qe5xh8#", "Qf3xa8+", "Qf3xa8#", "Qf3xh1+", "Qf3xh1#", "Qf6xa1+", "Qf6xa1#", "Qf6xh8+", "Qf6xh8#", "Qg2xa8+", "Qg2xa8#", "Qg2xh1+", "Qg2xh1#", "Qg7xa1+", "Qg7xa1#", "Qg7xh8+", "Qg7xh8#", "Qh1xa8+", "Qh1xa8#", "Qh8xa1+", "Qh8xa1#"
Wow, that's very diligent of you, but unfortunately I will need code/pseudocode example to make changes. I just haven't had time to get back into this repo yet, but it should be something along the lines of:
Then either:
3a. Brute force solution (easy):
a. Generate all possible piece configurations with pairs/triplets of that piece type that would cause the SAN to require the observed disambiguation
b. Check if, in any of these configurations, making the given SAN move causes new squares to be attacked (note that a capture could make this true instead of false, at least for file-disambiguated moves, ex. Baxc3
as opposed to Bac3
with bishops on a1
and e1
). If so, we need to add this SAN with both + and # appended.
or:
3b. Logical solution (harder): a. Come up with some logic to understand what must be true of any configuration causing the SAN to require the observed disambiguation. My intuition (which can't be trusted) says any configuration requiring the observed disambiguation is "equivalent" to any other (if any configuration causes new squares to be attacked, they all will - this will either need solid logic to be convincing or a counterexample). If that's the case, generate a single configuration that causes this disambiguation. b. Check if making the given SAN move in this configuration causes new squares to be attacked. If so, add this SAN with both + and # appended.
I tried to come up with some sort of logic, it's not very good but it's the best I have for now.
This issue happens when the disambiguations force the pieces into an orientation where no new pieces are attacked by the move. For a capture to also have this problem, I found that the only way is for the move to land on a corner, which will become obvious as I explain.
For pawns: Pawns can only be single disambiguated by file, and for them to be disambiguated, a capture is required. Pawns only attack the squares on the rank one ahead of them. Every time a pawn moves, it moves forward one rank, so a pawn will always attack new squares. Promotion will always attack new squares. Therefore, disambiguation for pawns can always result in a check or checkmate.
For knights: For a knight to not attack any new squares, they must all be either off of the board or occupied by another knight. Double disambiguation requires the knights to be arranged in a 5x3 rectangle, which forces the destination square to not be on the edge of the board, allowing for newly attacked squares:
Single disambiguation is a little promising, because the corners block all but two squares:
However, this is easily countered with a discovered check:
So all the cases are covered: knight moves can always cause check or checkmate.
The other pieces (rooks, bishops, and queens) can have this issue. However, captures must be treated seperately.
Rooks: Rooks have this problem every time they start on an edge AND both rooks are on different ranks and files. they don't start on the edge of the board, they can reveal a discovered check:
If the rooks can occupy the same rank or file, they can attack new squares:
But if they start on an edge, and they are forced to lie on different ranks and files, then the other rook already covers the squares that the moved rook tries to attack:
Edit: so while making this and trying to figure out what exactly can cause both issues, i found more moves that don't work, and i must extend my list again :(
Rank disambiguation never causes this issue as it lets the rooks lie on the same file.
The move must end on the a or h file because otherwise the other rook can lie on the same rank.
So you can just check for both requirements: if both rooks MUST lie on different ranks and files, and if the moving rook MUST start on an edge.
For captures: the same restrictions apply, but the move must also end on a corner. Otherwise, a piece can be captured to reveal a check:
Bishops: The move must start on a corner to have this problem. That's it.
For this to happen, the move must be doubly disambiguated. If it isn't, it allows for the bishop to not start on the corner:
And if it doesn't start on a corner, then discovered check is always possible.
Also, none of the bishop captures have this problem, because they can just capture and reveal a check:
So, simply search for all the bishop moves that start in the corner and don't capture a piece.
Queens: there are a couple ways this can happen, but both ways require double disambiguation. The simplest is if the queen moves diagonally into a corner:
The edge of the board forces the other queens to be in spots that block/cover the moved queen. The diagonal is always attacked. Also, the corner also blocks potential new directions the queen would attack. Here's an example of how the queen could attack new squares if it doesn't land on a corner:
The blue lines are always covered, but the red lines that were blocked by the corner are now exposed. Therefore, it must land on a corner, except for ONE SINGLE random edge case I found (but for a good reason):
The other queens just so happen to cover the exposed red lines. If they were one square further away from the corner, the queen could move to a spot that doesn't block the moved queen:
And if the queens were further apart, they don't cover the red lines:
Also, this square can be shifted around a bit:
If it is fully pushed against the corner, that's just the first case of the queen landing in the corner. For captures, most of the cases still apply, except for the outlier that i just described. Because the queen no longer lands on the corner, it can reveal a check by capturing a piece:
Queens are a little complicated, and I can't really come up with a rigid proof for these. However, the basic idea is that single disambiguation gives too much wiggle room, and the edge of the board must be used to force the queens into awkward positions that block the moving queen.
I'm just gonna paste the ones that I missed, instead of everything again. I'm almost positive that this is everything, because I solidified my logic, but then again I have made changes like 5 times so
"Rbxa1+", "Rbxa1#", "Rbxa8+", "Rbxa8#", "Rbxh1+", "Rbxh1#", "Rbxh8+", "Rbxh8#", "Rcxa1+", "Rcxa1#", "Rcxa8+", "Rcxa8#", "Rcxh1+", "Rcxh1#", "Rcxh8+", "Rcxh8#", "Rdxa1+", "Rdxa1#", "Rdxa8+", "Rdxa8#", "Rdxh1+", "Rdxh1#", "Rdxh8+", "Rdxh8#", "Rexa1+", "Rexa1#", "Rexa8+", "Rexa8#", "Rexh1+", "Rexh1#", "Rexh8+", "Rexh8#", "Rfxa1+", "Rfxa1#", "Rfxa8+", "Rfxa8#", "Rfxh1+", "Rfxh1#", "Rfxh8+", "Rfxh8#", "Rgxa1+", "Rgxa1#", "Rgxa8+", "Rgxa8#", "Rgxh1+", "Rgxh1#", "Rgxh8+", "Rgxh8#"
From https://chess.stackexchange.com/a/45638/19286: