-1

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?

1
  • this question needs to be asked on stack overflow. – Toby Harnish Apr 9 at 2:28
4

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.