c-chess-cli

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

c-chess-cli

Post by lucasart »

I wrote a simple tool, similar to cutechess-cli. The source code is 100% original, and uses no third party libraries, so it's very lightweight (ie. no C++ STL, Qt, Glib, or whatever). Just plain C and POSIX. Hopefully it's all explained in the readme, how to compile and use:
https://github.com/lucasart/c-chess-cli

Compatibility:
  • OS: should work on any POSIX system, including MacOS, Android, perhaps even Windows with msys2. But I've only tested on Linux.
  • Compiler: only supports GCC or Clang. tested with both.
  • C standard library: only tested with glibc or musl.
Of course, it doesn't have nearly as many features as cutechess-cli. But I think I've built all the basics right (molulo bugs :lol: ), and can easily extend from there.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
zullil
Posts: 6442
Joined: Tue Jan 09, 2007 12:31 am
Location: PA USA
Full name: Louis Zulli

Re: c-chess-cli

Post by zullil »

Thanks for this! About to give it a try (on Linux).
Joerg Oster
Posts: 937
Joined: Fri Mar 10, 2006 4:29 pm
Location: Germany

Re: c-chess-cli

Post by Joerg Oster »

lucasart wrote: Sun May 17, 2020 3:56 am I wrote a simple tool, similar to cutechess-cli. The source code is 100% original, and uses no third party libraries, so it's very lightweight (ie. no C++ STL, Qt, Glib, or whatever). Just plain C and POSIX. Hopefully it's all explained in the readme, how to compile and use:
https://github.com/lucasart/c-chess-cli

Compatibility:
  • OS: should work on any POSIX system, including MacOS, Android, perhaps even Windows with msys2. But I've only tested on Linux.
  • Compiler: only supports GCC or Clang. tested with both.
  • C standard library: only tested with glibc or musl.
Of course, it doesn't have nearly as many features as cutechess-cli. But I think I've built all the basics right (molulo bugs :lol: ), and can easily extend from there.
When compiling I'm getting a warning (gcc version 8.4.0 (Ubuntu 8.4.0-1ubuntu1~18.04)):

Code: Select all

gcc   -std=gnu99 -mpopcnt -O3 -flto -Wfatal-errors -Wall -Wextra -Wshadow -DNDEBUG ./*.c -o c-chess-cli -lpthread -s
./main.c: In function ‘main’:
./main.c:86:24: warning: passing argument 1 to restrict-qualified parameter aliases with argument 4 [-Wrestrict]
         pthread_create(&threads[i], NULL, thread_start, &threads[i]);
Jörg Oster
AndrewGrant
Posts: 1753
Joined: Tue Apr 19, 2016 6:08 am
Location: U.S.A
Full name: Andrew Grant

Re: c-chess-cli

Post by AndrewGrant »

Joerg Oster wrote: Tue May 19, 2020 3:48 pm When compiling I'm getting a warning (gcc version 8.4.0 (Ubuntu 8.4.0-1ubuntu1~18.04)):

Code: Select all

gcc   -std=gnu99 -mpopcnt -O3 -flto -Wfatal-errors -Wall -Wextra -Wshadow -DNDEBUG ./*.c -o c-chess-cli -lpthread -s
./main.c: In function ‘main’:
./main.c:86:24: warning: passing argument 1 to restrict-qualified parameter aliases with argument 4 [-Wrestrict]
         pthread_create(&threads[i], NULL, thread_start, &threads[i]);
He does this to get a threadID. Its a nice solution to passing just an integer. Any "proper" solution is just ugly.

Here is one ... I'm guessing that long long cast might throw a warning on a 32-bit ARCH.

Code: Select all

void* threadedFunction(void *args) {
    int threadID = (long long) args;
    printf("Starting a Thread! (#%d)", threadID);
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, &threadedFunction, (void*)1);
    pthread_join(thread, NULL);
}
#WeAreAllDraude #JusticeForDraude #RememberDraude #LeptirBigUltra
"Those who can't do, clone instead" - Eduard ( A real life friend, not this forum's Eduard )
Joerg Oster
Posts: 937
Joined: Fri Mar 10, 2006 4:29 pm
Location: Germany

Re: c-chess-cli

Post by Joerg Oster »

AndrewGrant wrote: Tue May 19, 2020 4:21 pm
Joerg Oster wrote: Tue May 19, 2020 3:48 pm When compiling I'm getting a warning (gcc version 8.4.0 (Ubuntu 8.4.0-1ubuntu1~18.04)):

Code: Select all

gcc   -std=gnu99 -mpopcnt -O3 -flto -Wfatal-errors -Wall -Wextra -Wshadow -DNDEBUG ./*.c -o c-chess-cli -lpthread -s
./main.c: In function ‘main’:
./main.c:86:24: warning: passing argument 1 to restrict-qualified parameter aliases with argument 4 [-Wrestrict]
         pthread_create(&threads[i], NULL, thread_start, &threads[i]);
He does this to get a threadID. Its a nice solution to passing just an integer. Any "proper" solution is just ugly.

Here is one ... I'm guessing that long long cast might throw a warning on a 32-bit ARCH.

Code: Select all

void* threadedFunction(void *args) {
    int threadID = (long long) args;
    printf("Starting a Thread! (#%d)", threadID);
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, &threadedFunction, (void*)1);
    pthread_join(thread, NULL);
}
So nothing to really worry about!?
Jörg Oster
Joerg Oster
Posts: 937
Joined: Fri Mar 10, 2006 4:29 pm
Location: Germany

Re: c-chess-cli

Post by Joerg Oster »

lucasart wrote: Sun May 17, 2020 3:56 am I wrote a simple tool, similar to cutechess-cli. The source code is 100% original, and uses no third party libraries, so it's very lightweight (ie. no C++ STL, Qt, Glib, or whatever). Just plain C and POSIX. Hopefully it's all explained in the readme, how to compile and use:
https://github.com/lucasart/c-chess-cli

Compatibility:
  • OS: should work on any POSIX system, including MacOS, Android, perhaps even Windows with msys2. But I've only tested on Linux.
  • Compiler: only supports GCC or Clang. tested with both.
  • C standard library: only tested with glibc or musl.
Of course, it doesn't have nearly as many features as cutechess-cli. But I think I've built all the basics right (molulo bugs :lol: ), and can easily extend from there.
Thanks.

Anything wrong with this command line?

Code: Select all

./c-chess-cli -cmd ./sf-time27c-jo:./sf-master -options Hash=32,Threads=1 -games 8 -concurrency 2 -openings /home/joster/openings/feobos_v20.1-contempt-3.epd -repeat -tc 10+0.1 -resign 3,700 -draw 8,16 -concurrency 2 -pgnout SF-Time27c-JO_10s_c-chess-cli.pgn
All games almost finish immediately, as if both engines wouldn't take any time ...
Jörg Oster
Ras
Posts: 2487
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: c-chess-cli

Post by Ras »

AndrewGrant wrote: Tue May 19, 2020 4:21 pmHe does this to get a threadID. Its a nice solution to passing just an integer.
I'm not sure, but I suspect this is undefined behaviour. A proper solution isn't even that ugly - just change the array of integers into an array of structs with thread ID and integer argument, and then pass the addresses of the struct components for the i-th thread.
Rasmus Althoff
https://www.ct800.net
Joerg Oster
Posts: 937
Joined: Fri Mar 10, 2006 4:29 pm
Location: Germany

Re: c-chess-cli

Post by Joerg Oster »

Joerg Oster wrote: Tue May 19, 2020 4:38 pm
lucasart wrote: Sun May 17, 2020 3:56 am I wrote a simple tool, similar to cutechess-cli. The source code is 100% original, and uses no third party libraries, so it's very lightweight (ie. no C++ STL, Qt, Glib, or whatever). Just plain C and POSIX. Hopefully it's all explained in the readme, how to compile and use:
https://github.com/lucasart/c-chess-cli

Compatibility:
  • OS: should work on any POSIX system, including MacOS, Android, perhaps even Windows with msys2. But I've only tested on Linux.
  • Compiler: only supports GCC or Clang. tested with both.
  • C standard library: only tested with glibc or musl.
Of course, it doesn't have nearly as many features as cutechess-cli. But I think I've built all the basics right (molulo bugs :lol: ), and can easily extend from there.
Thanks.

Anything wrong with this command line?

Code: Select all

./c-chess-cli -cmd ./sf-time27c-jo:./sf-master -options Hash=32,Threads=1 -games 8 -concurrency 2 -openings /home/joster/openings/feobos_v20.1-contempt-3.epd -repeat -tc 10+0.1 -resign 3,700 -draw 8,16 -concurrency 2 -pgnout SF-Time27c-JO_10s_c-chess-cli.pgn
All games almost finish immediately, as if both engines wouldn't take any time ...
After the latest commit everything seems to be working as expected.
I tried fixed depth, tournament tc and Fischer bonus time.

A summary of the result at the end would be nice. :D
Jörg Oster
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: c-chess-cli

Post by lucasart »

Ras wrote: Tue May 19, 2020 5:00 pm
AndrewGrant wrote: Tue May 19, 2020 4:21 pmHe does this to get a threadID. Its a nice solution to passing just an integer.
I'm not sure, but I suspect this is undefined behaviour. A proper solution isn't even that ugly - just change the array of integers into an array of structs with thread ID and integer argument, and then pass the addresses of the struct components for the i-th thread.
Yes, that's the plan. Eventually, I will need such an array of struct, as I will do some synchronization for main thread to ping engines, and detect timeouts.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: c-chess-cli

Post by lucasart »

Joerg Oster wrote: Tue May 19, 2020 10:08 pmA summary of the result at the end would be nice. :D
Yes, I have 3 things to implement, which must be done in the main thread, and require some synchronization. Here they are, by level of difficulty:
  • Periodic updates on results: main thread read results of worker threads, add them up, and show the user (with proper locking, of course).
  • Detect timeout. This can't be done in the worker threads, just checking time after each read (eg. info line waiting for bestmove line). I can't put any upper bound to the time between 2 such reads, and must assume that engines are buggy, so they crash and don't respect the time allocated. I think the proper solution is to do this in the main thread periodically.
  • Ping engines periodically: send isready, and wait (with a timeout) for readyok. Problem is, reading a line with a timeout is surprisingly complicated. No, a simple select() of poll() won't work, at least not 100% of the time (engine could be trolling and send a few char without \n then never send anything). Unless anyone has an idea, it seems the only reliable solution is to spwan yet another thread, just for the purpose of reading a line with a timeout (a controlling thread, which checks time periodically, and if the reading thread hasn't ready, then die).
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.