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!")
      }
  }
  
  
  ---
  
  