Answers.Body: <p><code>info depth 1 seldepth 1 multipv 1 score cp 539 nodes 83 nps 41500 tbhits 0 time 2 pv e5f6 info depth 2 seldepth 2 multipv 1 score cp 790 nodes 182 nps 91000 tbhits 0 time 2 pv e4d5 b7b6 e5f6</code></p>
  <p>obviously doesn't have any best move in it. Stockfish needs time to give you a move. Your program will need to filter out those principal variation lines.</p>
  <p>Please don't use <code>waitTime</code>.  Did you ask for 20 seconds? Chess engine may not stop the search exactly after 20s. Do something like this:</p>
  <ul>
  <li>Wait from Stockfish in real-time. In C++, it's something like <code>read()</code> (can't remember exactly without a Google search). Your worker thread waits for the next Stockfish output.</li>
  <li>Check if &quot;bestmove&quot; is in the line, if not, do nothing</li>
  </ul>
  <p>Pseudocode looks like:</p>
  <pre><code>f = ... // handler to Stockfish's standard output
  while (true) {
      line = f.read() // Read Stockfish's next line. Blocked if nothing.
      if (&quot;bestmove&quot; in line) { // Best move?
          ... parse the move ...
      } else {
          print(&quot;Do nothing!&quot;)
      }
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-04-06T13:35:24.193Z
Answers.LastActivityDate: 2021-04-06T13:35:24.193Z
Answers.UserDisplayName: SmallChess
Body: <p>I am writing a java program to connect to the Stockfish Engine and get the best move for some FENs.
  My Connection code is :</p>
  <pre><code>public class connector {
      private Process engineProcess;
      private BufferedReader processReader;
      private OutputStreamWriter processWriter;
      private static final String Path = &quot;path\to\stockfish.exe&quot;;
      
      public boolean startEngine() {
          try {
              engineProcess = Runtime.getRuntime().exec(Path);
              processReader = new BufferedReader(new InputStreamReader(
                      engineProcess.getInputStream()));
              processWriter = new OutputStreamWriter(
                      engineProcess.getOutputStream());
          } catch (Exception e) {
              return false;
          }
          return true;
      }
      
      public void sendCommand(String command) {
          try {
              processWriter.write(command + &quot;\n&quot;);
              processWriter.flush();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
      
      public String getBestMove(String fen, int waitTime) throws IOException, InterruptedException {
          
          sendCommand(&quot;position fen &quot; + fen);
          sendCommand(&quot;go movetime &quot; + waitTime);
          return getOutput(waitTime + 20).split(&quot;bestmove &quot;)[1].split(&quot; &quot;)[0];
      }
  
      public String getOutput(int waitTime) throws IOException, InterruptedException {
          StringBuffer buffer = new StringBuffer();
          
          try { 
              Thread.sleep(waitTime); 
              sendCommand(&quot;isready&quot;); 
              while (true) { 
             String text = processReader.readLine(); 
             System.out.println(&quot;Text is &quot; + text); 
             if(text.equals(&quot;readyok&quot;))
                break; 
             else 
                buffer.append(text + &quot;\n&quot;); 
                
            }
            catch (Exception e) { e.printStackTrace(); }
           
          return buffer.toString();
      }
  
      public void stopEngine() {
          try {
              sendCommand(&quot;quit&quot;);
              processReader.close();
              processWriter.close();
          } catch (IOException e) {
          }
      }
      
  }
  </code></pre>
  <p>My Driver Code is as Follows :</p>
  <pre><code>connector con = new connector();
          boolean started = con.startEngine();
          if(started) {
              Thread.sleep(1000);
              String bestMove = con.getBestMove(&quot;1nbqkbnr/1ppppppp/p7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1&quot;, 5000);
              
              System.out.println(bestMove);
          }else {
              System.out.println(&quot;Failed To Start Engine&quot;);
              System.exit(0);
          }
  </code></pre>
  <p>The Output I am getting is :</p>
  <pre><code>java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
  at connectors.connector.getBestMove(connector.java:42)
  </code></pre>
  <p>I am having a hard time understanding what is wrong with my code. I understand that using processReader , I am reading the InputStream of the engine and appending it to String &quot;text&quot; until I encounter &quot;readyok&quot; , and finally returning this string. But when I output this , it gives me everything including info like</p>
  <p><code>info depth 1 seldepth 1 multipv 1 score cp 539 nodes 83 nps 41500 tbhits 0 time 2 pv e5f6 info depth 2 seldepth 2 multipv 1 score cp 790 nodes 182 nps 91000 tbhits 0 time 2 pv e4d5 b7b6 e5f6</code></p>
  <p>I am unable to get the Best Move. How can I do this?</p>
  
Tags: <stockfish><uci>
Title: Unable To Communicate with UCI through Java Program
ThreadText: # Unable To Communicate with UCI through Java Program
  
  (Asked by: username_0 on 2021-04-06)
  
  I am writing a java program to connect to the Stockfish Engine and get the best move for some FENs.
  My Connection code is :
  
  ```
  public class connector {
      private Process engineProcess;
      private BufferedReader processReader;
      private OutputStreamWriter processWriter;
      private static final String Path = "path\to\stockfish.exe";
      
      public boolean startEngine() {
          try {
              engineProcess = Runtime.getRuntime().exec(Path);
              processReader = new BufferedReader(new InputStreamReader(
                      engineProcess.getInputStream()));
              processWriter = new OutputStreamWriter(
                      engineProcess.getOutputStream());
          } catch (Exception e) {
              return false;
          }
          return true;
      }
      
      public void sendCommand(String command) {
          try {
              processWriter.write(command + "\n");
              processWriter.flush();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
      
      public String getBestMove(String fen, int waitTime) throws IOException, InterruptedException {
          
          sendCommand("position fen " + fen);
          sendCommand("go movetime " + waitTime);
          return getOutput(waitTime + 20).split("bestmove ")[1].split(" ")[0];
      }
  
      public String getOutput(int waitTime) throws IOException, InterruptedException {
          StringBuffer buffer = new StringBuffer();
          
          try { 
              Thread.sleep(waitTime); 
              sendCommand("isready"); 
              while (true) { 
             String text = processReader.readLine(); 
             System.out.println("Text is " + text); 
             if(text.equals("readyok"))
                break; 
             else 
                buffer.append(text + "\n"); 
                
            }
            catch (Exception e) { e.printStackTrace(); }
           
          return buffer.toString();
      }
  
      public void stopEngine() {
          try {
              sendCommand("quit");
              processReader.close();
              processWriter.close();
          } catch (IOException e) {
          }
      }
      
  }
  
  ```
  
  My Driver Code is as Follows :
  
  ```
  connector con = new connector();
          boolean started = con.startEngine();
          if(started) {
              Thread.sleep(1000);
              String bestMove = con.getBestMove("1nbqkbnr/1ppppppp/p7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", 5000);
              
              System.out.println(bestMove);
          }else {
              System.out.println("Failed To Start Engine");
              System.exit(0);
          }
  
  ```
  
  The Output I am getting is :
  
  ```
  java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
  at connectors.connector.getBestMove(connector.java:42)
  
  ```
  
  I am having a hard time understanding what is wrong with my code. I understand that using processReader , I am reading the InputStream of the engine and appending it to String "text" until I encounter "readyok" , and finally returning this string. But when I output this , it gives me everything including info like
  
  `info depth 1 seldepth 1 multipv 1 score cp 539 nodes 83 nps 41500 tbhits 0 time 2 pv e5f6 info depth 2 seldepth 2 multipv 1 score cp 790 nodes 182 nps 91000 tbhits 0 time 2 pv e4d5 b7b6 e5f6`
  
  I am unable to get the Best Move. How can I do this?
  
  **Tags:** stockfish, uci
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2021-04-06. Score: 4 | Accepted answer
  
  `info depth 1 seldepth 1 multipv 1 score cp 539 nodes 83 nps 41500 tbhits 0 time 2 pv e5f6 info depth 2 seldepth 2 multipv 1 score cp 790 nodes 182 nps 91000 tbhits 0 time 2 pv e4d5 b7b6 e5f6`
  
  obviously doesn't have any best move in it. Stockfish needs time to give you a move. Your program will need to filter out those principal variation lines.
  
  Please don't use `waitTime`. Did you ask for 20 seconds? Chess engine may not stop the search exactly after 20s. Do something like this:
  
  * Wait from Stockfish in real-time. In C++, it's something like `read()` (can't remember exactly without a Google search). Your worker thread waits for the next Stockfish output.
  * Check if "bestmove" is in the line, if not, do nothing
  
  Pseudocode looks like:
  
  ```
  f = ... // handler to Stockfish's standard output
  while (true) {
      line = f.read() // Read Stockfish's next line. Blocked if nothing.
      if ("bestmove" in line) { // Best move?
          ... parse the move ...
      } else {
          print("Do nothing!")
      }
  }
  
  ```
  
  
  ---
  
  