Checking TT move for legality

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
AAce3
Posts: 80
Joined: Fri Jul 29, 2022 1:30 am
Full name: Aaron Li

Checking TT move for legality

Post by AAce3 »

Hi all,

I'm currently working on staged movegen for my rewrite of ShenYu and I wanted to hear what other people have done for determining whether a TT move is valid/legal. I read on the chess programming something about using "in-between squares" but I'm not sure what that has to do with checking TT move for legality.
syzygy
Posts: 5690
Joined: Tue Feb 28, 2012 11:56 pm

Re: Checking TT move for legality

Post by syzygy »

AAce3 wrote: Sat Aug 19, 2023 7:28 pm I'm currently working on staged movegen for my rewrite of ShenYu and I wanted to hear what other people have done for determining whether a TT move is valid/legal. I read on the chess programming something about using "in-between squares" but I'm not sure what that has to do with checking TT move for legality.
Sliding pieces (bishops, rooks and queens) are not allowed to jump over other pieces on the squares "in-between" the from and to squares. So a legality check will typically check that the in-between squares are not occupied if the piece being moved is a sliding piece.

As the bare minimum you should make sure your engine does not crash on the tt move. But you should probably just make sure that the tt move is a legal move (or at least pseudo-legal depending on whether you anyway do a test for check) because parts of your engine may contain hidden assumptions that the move is legal.

Your tt move verification routine probably may assume that the tt move is at least a move that your move generator can output for some legal position, i.e. it is not a random bit pattern. There will be a from square and a to square, and perhaps other bits that encode information. But the tt move may have been generated for a position that has nothing to do with your current position (e.g. because of hash collisions).

So you should check the from square contains a piece of the side to move, the to square does not contain a piece of the side to move, the to square is a square that can be reached by the piece on the from square (without jumping over other occupied in-between squares in case of a sliding piece), etc. You will probably have to treat special moves (castling, en passant, promotion) separately.
syzygy
Posts: 5690
Joined: Tue Feb 28, 2012 11:56 pm

Re: Checking TT move for legality

Post by syzygy »

Alternatively, you could generate the list of all pseudo-legal or even all legal moves and verify that the tt move is in the list. This will be less efficient, but you could decide to worry about efficiency later.
User avatar
j.t.
Posts: 263
Joined: Wed Jun 16, 2021 2:08 am
Location: Berlin
Full name: Jost Triller

Re: Checking TT move for legality

Post by j.t. »

I have a special "perft" function where I test a lot of the utilities I also use in my search. For checking if the isPseudoLegal(move) function works, I a) assert that each move from the movegen isPseudoLegal(move) is true for the given position. I also check if isPsuedoLegal(move) returns correctly on a bunch of "random" moves (see here for more details).

Having such a test method for making sure that your isPseudoLegal function works correctly is pretty important as it can be quite easy to forget some small thing.

I agree with what syzygy wrote, except, depending on your engine, you may need to assume that the move you get does not describe any legal move. This is because you may get garbage data from threading race conditions, if you use an unprotected shared hash table.
JoAnnP38
Posts: 253
Joined: Mon Aug 26, 2019 4:34 pm
Location: Clearwater, Florida USA
Full name: JoAnn Peeler

Re: Checking TT move for legality

Post by JoAnnP38 »

I do not check the TT move for legality. If it was legal going in, I expect that 99.99999%+ of the time it will be legal coming out. I do, however, store the full Zobrist key of the position in the hash table item and make sure it matches the current position before accepting that as a TT match. Someday, this may prove to be a poor decision, but that day is not today.
User avatar
j.t.
Posts: 263
Joined: Wed Jun 16, 2021 2:08 am
Location: Berlin
Full name: Jost Triller

Re: Checking TT move for legality

Post by j.t. »

JoAnnP38 wrote: Mon Aug 21, 2023 11:18 am Someday, this may prove to be a poor decision, but that day is not today.
It may become an issue when you start to use multothreadin. Because of race conditions, you may end up with a totally garbled move object. I think I got like 20-30 Elo fixing it for multithreaded search. And also fixed some nasty out of bounds issues.
User avatar
Fabio Gobbato
Posts: 219
Joined: Fri Apr 11, 2014 10:45 am
Full name: Fabio Gobbato

Re: Checking TT move for legality

Post by Fabio Gobbato »

JoAnnP38 wrote: Mon Aug 21, 2023 11:18 am I do not check the TT move for legality. If it was legal going in, I expect that 99.99999%+ of the time it will be legal coming out. I do, however, store the full Zobrist key of the position in the hash table item and make sure it matches the current position before accepting that as a TT match. Someday, this may prove to be a poor decision, but that day is not today.
Even with a single thread search and a 64 bit zobrist key you can get collisions with long time control. The engine with an illegal move could crash or search on wrong boards. You should fix it even if at short time control you won't get elo from this patch.
chrisw
Posts: 4624
Joined: Tue Apr 03, 2012 4:28 pm
Location: Midi-Pyrénées
Full name: Christopher Whittington

Re: Checking TT move for legality

Post by chrisw »

j.t. wrote: Mon Aug 21, 2023 12:11 pm
JoAnnP38 wrote: Mon Aug 21, 2023 11:18 am Someday, this may prove to be a poor decision, but that day is not today.
It may become an issue when you start to use multothreadin. Because of race conditions, you may end up with a totally garbled move object. I think I got like 20-30 Elo fixing it for multithreaded search. And also fixed some nasty out of bounds issues.
if the hash is zero-ed out on initialisation, then it ought never to contain random trash in the move field. From/to will always be 0 <= x < 64, and will always be either nullmove or a move valid in some universe.
User avatar
j.t.
Posts: 263
Joined: Wed Jun 16, 2021 2:08 am
Location: Berlin
Full name: Jost Triller

Re: Checking TT move for legality

Post by j.t. »

chrisw wrote: Mon Aug 21, 2023 1:09 pm if the hash is zero-ed out on initialisation, then it ought never to contain random trash in the move field. From/to will always be 0 <= x < 64, and will always be either nullmove or a move valid in some universe.
“Random trash” is probably overselling the problem, but for example, two valid moves, written by two threads at the same time, could result in a non-move, by combining these two moves in some undefined way (e.g., promotion when moving a rook). Or, what I assume happened in my case, the special “no-move” move object, that I was checking against in my “isPseudoLegal” function, was partly overwritten by another thread with a legal move, but when another thread reads this move, it might again get a nonsensical move, that is not exactly equal to the special “no-move” object, but also doesn't describe a valid piece that gets moved with this move.
spinosarus123
Posts: 4
Joined: Tue Jun 20, 2023 12:46 pm
Full name: Isak Ellmer

Re: Checking TT move for legality

Post by spinosarus123 »

chrisw wrote: Mon Aug 21, 2023 1:09 pm
j.t. wrote: Mon Aug 21, 2023 12:11 pm
JoAnnP38 wrote: Mon Aug 21, 2023 11:18 am Someday, this may prove to be a poor decision, but that day is not today.
It may become an issue when you start to use multothreadin. Because of race conditions, you may end up with a totally garbled move object. I think I got like 20-30 Elo fixing it for multithreaded search. And also fixed some nasty out of bounds issues.
if the hash is zero-ed out on initialisation, then it ought never to contain random trash in the move field. From/to will always be 0 <= x < 64, and will always be either nullmove or a move valid in some universe.
My engine makes some assumptions based on the move being legal. This could definitely result in undefined behavior if such a move is assumed to be legal (at least in my engine).