-3

I want to connect my C++ Program with a Chess Engine in order to have AI for the enemy. In my c++ program-->User will make a move(eg. A2A3)-->I will pass this string to chess engine-->engine will update board-->engine will start A.I for calculating enemy move-->Engine will give enemy's move as string(e.g A7A6) to my C++ program-->etc

I read that in order for my program to interact with a chess engine I have to start the chess_engine.exe file and exchange commands with it via the Standard Input/Output.

Can you tell me how exactly can my Visual Studio program code start a exe file and exchange commands with it?? Any example?

Thank you in advance.

mariosbikos
  • 429
  • 1
  • 5
  • 11
  • Which OS? Or do you use C++11 or Boost? For Windows, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.85%29.aspx – sashoalm May 04 '15 at 13:21
  • You should be using the UCI chess interface, which basically uses pipes via stdio/stdout to exchange information between the frontend and the engine. – trojanfoe May 04 '15 at 13:27
  • yes as far as I can understand UCI is a set of rules/commands to exchange between my app and the chess engine.So I need to open the .exe engine through my application and then exchange commands with the engine via std I/O or can I use ready code which allows me to specify the chess engine file and then use ready functions like--> pass_command(a2a3) ? – mariosbikos May 04 '15 at 13:29
  • I use windows and c++ only(not boost) – mariosbikos May 04 '15 at 13:32

2 Answers2

3

A common misconception is that your engine needs to start separately and connect itself to the GUI. Instead, the GUI itself will open your engine and run it as a child process. The GUI will communicate with your engine using std_in and std_out. In C++, this is as simple as using cin and cout. From your engine, anything that is streamed into cout will be sent to the GUI and any thing streamed from cin will be received from the GUI. In a way, the chess GUI takes the place of your terminal.

According to the UCI specification the first message the GUI sends to the engine is "uci" telling the engine to switch to uci mode. From your engines perspective your code could look something like this.

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string msg;
    getline(cin, msg);    // Read message from GUI
    
    // Does the GUI want use to switch to UCI mode?
    if (msg == "uci") {
        // Yes, switch to UCI move
        
        // Send some engine info to GUI
        cout << "id name MyEnginesName" << endl
             << "id author MyName" << endl;  // The endls are very important
        
        // --- GUI will now send some settings to our engine ---

        // Read option settings from GUI
        while (getline(cin, msg)) {
            if (msg == "uciok") {
                break; // Last option has been received
            }
            else {
                // Parse msg and store option settings
                // ...
            }      
        }

        // Bunch more code here   
    }
    
    cout << "Press any key...";
    cin.get();
    return 0;
}

A great way to learn the UCI protocol is to practice it yourself on the command line. Download a UCI compatible chess engine like lc0 or stockfish. Open a terminal and cd into the engines directory. Run the engine application on the command line and start typing UCI commands as if you were the GUI.

IronMan
  • 51
  • 11
  • Couldn't understand the code. I am looking for code to communicate with SomeEngine.exe. How do I start SomeEngine.exe from my C++ code and how do I send and receive UCI commands. I know the UCI commands, I want to know about the code to send and receive the UCI commands from my GUI. – Ambar Chatterjee Sep 23 '21 at 14:51
  • I this case, the best way to do this is by running a process as a child and communicating with it using pipes. Pipes are basically iostreams like cin and cout except the receiver is a process and not a file or std_in/std_out. A great library for running and talking to a child process is boost-process. Here is a link to a great tutorial https://www.boost.org/doc/libs/1_74_0/doc/html/process.html. Focus on synchronous pipes. Also to integrate boost into your project I highly recommend vcpkg. Adding 3rd party libraries is difficult and vcpkg will automatically integrate boost into your project. – IronMan Sep 27 '21 at 15:33
  • Let me know if it works. – IronMan Sep 28 '21 at 17:50
  • Thanks IronMan. I am interested in the Win32 commands without having to use an external library. Accordingly I am looking at this Stackoverflow thread: https://stackoverflow.com/questions/21458166/how-to-pass-an-input-and-retrieve-an-output-to-a-child-process-in-c-language – Ambar Chatterjee Sep 29 '21 at 04:12
0

To do that, you'll need to start a new thread or process with the engine. Typically, you'll do it by starting a new process where the main function of the engine will be starting point of the new process.

Now, you'll have two processes in your application. You GUI application is the parent process whereas the engine itself will be the child process. You'll need to communicate to the engine via the standard chess UCI protocol. You can pipe inputs and output to/from the child process (which is the engine).

Let's say you want to start a new game. You'll issue the following UCI commands:

isready
ucinewgame

Please read the UCI specification carefully. You can get it on Google.

ABCD
  • 7,914
  • 9
  • 54
  • 90