As said earlier here I would greatly appreciate help from the much smarter people than me on this forum.
I released my chessnix 1.3 today here, which has a playing strength of around 3200 ELO. For comparison: the strongest human players in the world are 2800. The strongest existing chess engine is around 3645.
I will try and make not too many “chessnix” posts. There are 4 or 5 areas where I think I can do better Zig.
Warning: chess programming is quite an insane area.
This is actually the first time I created a multithreaded something and want to know if I am doing it right.
The external GUI - which starts the engine application - talks to the engine using the UCI protocol: just strings which have to be parsed, using the stdin and stdout.
The main loop is in uci.zig which always has to be responsive all the time.
The most important commands are go, stop and quit.
In engine.zig there is a go() function which starts the search thread.
(Note: in the future the engine should be able to start multiple search threads).
So the order of things is:
engine.go() → engine.run_controller_thread() → searcher.go().
go
The Searcher searches the current chess position and periodically checks if:
- we are out of time
- we received a
stoporquitcommand from the main uci loop.
While searching the searcher also outputs strings to stdout.
Question 1)
Everything works as expected (the engine is running ok) and what I really would like to know if what I have programmed is correct and ‘ziggy’ and if there is room to make it cleaner, better, faster. Am I using the atomic stop variable correctly?
Question 2)
Another thing is some commented out code in search.zig:
fn give_best_move()
where I run a
while not is_busy() // do nothing
which is very confusing to me. How do we write a function that returns something, waiting for a thread and only then return?