c-chess-cli

Discussion of chess software programming and technical issues.

Moderators: Harvey Williamson, Dann Corbit, hgm

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
Post Reply
User avatar
lucasart
Posts: 3168
Joined: Mon May 31, 2010 11:29 am
Full name: lucasart
Contact:

c-chess-cli

Post by lucasart » Sun May 17, 2020 1: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.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.

zullil
Posts: 6442
Joined: Mon Jan 08, 2007 11:31 pm
Location: PA USA
Full name: Louis Zulli

Re: c-chess-cli

Post by zullil » Mon May 18, 2020 12:13 pm

Thanks for this! About to give it a try (on Linux).

Joerg Oster
Posts: 792
Joined: Fri Mar 10, 2006 3:29 pm
Location: Germany

Re: c-chess-cli

Post by Joerg Oster » Tue May 19, 2020 1:48 pm

lucasart wrote:
Sun May 17, 2020 1: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: 876
Joined: Tue Apr 19, 2016 4:08 am
Location: U.S.A
Full name: Andrew Grant
Contact:

Re: c-chess-cli

Post by AndrewGrant » Tue May 19, 2020 2:21 pm

Joerg Oster wrote:
Tue May 19, 2020 1: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);
}

Joerg Oster
Posts: 792
Joined: Fri Mar 10, 2006 3:29 pm
Location: Germany

Re: c-chess-cli

Post by Joerg Oster » Tue May 19, 2020 2:33 pm

AndrewGrant wrote:
Tue May 19, 2020 2:21 pm
Joerg Oster wrote:
Tue May 19, 2020 1: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: 792
Joined: Fri Mar 10, 2006 3:29 pm
Location: Germany

Re: c-chess-cli

Post by Joerg Oster » Tue May 19, 2020 2:38 pm

lucasart wrote:
Sun May 17, 2020 1: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: 1641
Joined: Tue Aug 30, 2016 6:19 pm
Full name: Rasmus Althoff
Contact:

Re: c-chess-cli

Post by Ras » Tue May 19, 2020 3:00 pm

AndrewGrant wrote:
Tue May 19, 2020 2:21 pm
He 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: 792
Joined: Fri Mar 10, 2006 3:29 pm
Location: Germany

Re: c-chess-cli

Post by Joerg Oster » Tue May 19, 2020 8:08 pm

Joerg Oster wrote:
Tue May 19, 2020 2:38 pm
lucasart wrote:
Sun May 17, 2020 1: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: 3168
Joined: Mon May 31, 2010 11:29 am
Full name: lucasart
Contact:

Re: c-chess-cli

Post by lucasart » Tue May 19, 2020 11:43 pm

Ras wrote:
Tue May 19, 2020 3:00 pm
AndrewGrant wrote:
Tue May 19, 2020 2:21 pm
He 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: 3168
Joined: Mon May 31, 2010 11:29 am
Full name: lucasart
Contact:

Re: c-chess-cli

Post by lucasart » Wed May 20, 2020 12:16 am

Joerg Oster wrote:
Tue May 19, 2020 8:08 pm
A 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.

Post Reply