UCI "position" question

Discussion of chess software programming and technical issues.

Moderator: Ras

benvining
Posts: 22
Joined: Fri May 30, 2025 10:18 pm
Full name: Ben Vining

UCI "position" question

Post by benvining »

I've just written my first version of a crude uci implementation, and I'm wondering why the "position" command is specified the way it is. I understand that there's the "ucinewgame" command, so perhaps we could assume that the board hasn't been reset unless that's called, but according to the spec document I found, it sounds like not all GUIs will emit this command. So in order to defensively parse "position" commands, it seems to me like we have to start from the given starting position, make the given list of moves, and then see if the resulting position was the same as the last one we ended up at. It seems like this defeats the purpose of incremental updates for bitboards, Zobrist hashes, etc, if the whole sequence of moves needs to be remade every time we parse a new move.

Am I misunderstanding the spec? How do other engines handle this?
syzygy
Posts: 5693
Joined: Tue Feb 28, 2012 11:56 pm

Re: UCI "position" question

Post by syzygy »

benvining wrote: Mon Jun 02, 2025 1:19 am I've just written my first version of a crude uci implementation, and I'm wondering why the "position" command is specified the way it is. I understand that there's the "ucinewgame" command, so perhaps we could assume that the board hasn't been reset unless that's called, but according to the spec document I found, it sounds like not all GUIs will emit this command. So in order to defensively parse "position" commands, it seems to me like we have to start from the given starting position, make the given list of moves, and then see if the resulting position was the same as the last one we ended up at.
There is no need to check if it is "the last one we ended up at" (and typically it won't be, since the opponent will have made a move). Your engine should just accept the position it is given and calculate from there.
It seems like this defeats the purpose of incremental updates for bitboards, Zobrist hashes, etc, if the whole sequence of moves needs to be remade every time we parse a new move.
Incremental bitboard updates are done for speeding up the search. You will still do them while playing out the moves in the move list you are getting as part of the position command. Processing that move list for each game move (as opposed to tree move) will cost essentially no time.
benvining
Posts: 22
Joined: Fri May 30, 2025 10:18 pm
Full name: Ben Vining

Re: UCI "position" question

Post by benvining »

typically it won't be, since the opponent will have made a move
Right, I guess I'm asking if we can assume that the new "position" command will always be the previous position with one more move made.
Incremental bitboard updates are done for speeding up the search
That makes sense, obviously traversing the move tree takes far more time. I suppose I will go with just parsing the given position & making the given move sequence every time I get a "position" command
User avatar
Steve Maughan
Posts: 1273
Joined: Wed Mar 08, 2006 8:28 pm
Location: Florida, USA

Re: UCI "position" question

Post by Steve Maughan »

benvining wrote: Mon Jun 02, 2025 7:52 am...Right, I guess I'm asking if we can assume that the new "position" command will always be the previous position with one more move made....
It sounds like you're trying to optimize something that really doesn't need to be optimized. The UCI protocol is, from the engine's perspective, a stateless protocol. The engine receives the "position" command, and then calculates based on the "go" command.

— Steve
http://www.chessprogramming.net - Juggernaut & Maverick Chess Engine
User avatar
hgm
Posts: 28353
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: UCI "position" question

Post by hgm »

benvining wrote: Mon Jun 02, 2025 7:52 amRight, I guess I'm asking if we can assume that the new "position" command will always be the previous position with one more move made.
No, you cannot assume that. The previous move of the engine might have transposed back into the opening book the GUI is using, and the GUI might have played a number of moves on behalf of the engine as a consequence, before presenting the position after getting out of book again to the engine.

Also, the user might have taken back a move.
mar
Posts: 2652
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: UCI "position" question

Post by mar »

Steve Maughan wrote: Mon Jun 02, 2025 3:53 pm It sounds like you're trying to optimize something that really doesn't need to be optimized. The UCI protocol is, from the engine's perspective, a stateless protocol. The engine receives the "position" command, and then calculates based on the "go" command.

— Steve
it depends how fast your move validation is, assuming you do validate moves from the "GUI" - imagine a human making a typo in the console...

what I did when switching Isa to UCI is I remember last position command string (this is only valid when it's a position .... moves ... command)
if the actual position command starts with the last position command, I only do incremental move parsing and validation

there's still IO overhead, but...

as for statelessness - the engine typically has most of the state from the last position command, imagine how nice it would be to be able to do something like "position last moves ..." or even something shorter
rebuilding state from scratch (not really since you keep TT) each time is slow and dumb (especially at hyperbullet) as you're basically serializing the whole game each time
benvining
Posts: 22
Joined: Fri May 30, 2025 10:18 pm
Full name: Ben Vining

Re: UCI "position" question

Post by benvining »

assuming you do validate moves from the "GUI"
I didn't realize we were supposed to validate moves received via UCI. What is the engine supposed to do if the "position" command contains an illegal move?
benvining
Posts: 22
Joined: Fri May 30, 2025 10:18 pm
Full name: Ben Vining

Re: UCI "position" question

Post by benvining »

if the actual position command starts with the last position command, I only do incremental move parsing and validation
That's basically what I was getting at. I'm not sure yet if it's really worth it, but I'll definitely keep it in mind.
mar
Posts: 2652
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: UCI "position" question

Post by mar »

benvining wrote: Mon Jun 02, 2025 8:05 pm I didn't realize we were supposed to validate moves received via UCI. What is the engine supposed to do if the "position" command contains an illegal move?
not in an ideal world. but there are GUIs out there (like Arena) that let the engine search when the position has 0 legal moves,
or letting the engine search when it's already a threefold etc.

plus humans can input any nonsense manually from the command line

maybe you're right and it's not worth bothering with this, but I prefer to report an error rather than getting random crashes later
benvining
Posts: 22
Joined: Fri May 30, 2025 10:18 pm
Full name: Ben Vining

Re: UCI "position" question

Post by benvining »

I'm working in C++, and currently my code to parse a move from a UCI string will throw an exception if it doesn't recognize the rile/rank chars, or if there's no piece on the starting square (since my Move structure holds a piece type). But I'm not checking there if making the move would place the player's king in check...