Better stockfish integration
This commit is contained in:
parent
76ac71fbf1
commit
be4d94a5bb
|
@ -85,13 +85,20 @@ public class Chess {
|
|||
|
||||
JMenuItem toggleAutomaticRandomOpponent = new JMenuItem("Toggle automatic random opponent");
|
||||
toggleAutomaticRandomOpponent.addActionListener(l -> {
|
||||
chessboard.getOtherPlayer().toggleAutomaticRandom();
|
||||
Player opponent = chessboard.getOtherPlayer();
|
||||
opponent.toggleAutomaticRandom(!opponent.isAutomaticRandom());
|
||||
});
|
||||
menuCPU.add(toggleAutomaticRandomOpponent);
|
||||
|
||||
JMenuItem toggleAutomaticSmartOpponent = new JMenuItem("Toggle automatic smart opponent");
|
||||
toggleAutomaticSmartOpponent.addActionListener(l -> {
|
||||
chessboard.getOtherPlayer().toggleAutomaticSmart();
|
||||
Player opponent = chessboard.getOtherPlayer();
|
||||
if(!opponent.isAutomaticSmart()) {
|
||||
Stockfish stockfish = opponent.getStockfish();
|
||||
opponent.toggleAutomaticSmart(stockfish);
|
||||
} else {
|
||||
opponent.toggleAutomaticSmart(null);
|
||||
}
|
||||
});
|
||||
menuCPU.add(toggleAutomaticSmartOpponent);
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import javax.swing.*;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import java.util.Timer;
|
||||
|
@ -72,10 +74,8 @@ public class Player {
|
|||
}
|
||||
|
||||
public boolean smartMove() {
|
||||
if(stockfish == null) {
|
||||
stockfish = new Stockfish();
|
||||
stockfish.startEngine();
|
||||
}
|
||||
stockfish = getStockfish();
|
||||
if(stockfish == null) return false;
|
||||
String fen = chessboard.toFEN();
|
||||
String bestMove = stockfish.getBestMove(fen, 0, 500);
|
||||
PiecePosition fromPos = PiecePosition.fromString(bestMove.substring(0, 2));
|
||||
|
@ -84,9 +84,28 @@ public class Player {
|
|||
APiece piece = chessboard.getPiece(fromPos.x, fromPos.y);
|
||||
piece.move(toPos);
|
||||
chessboard.changeActivePlayer();
|
||||
stockfish.stopEngine();
|
||||
stockfish = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Stockfish getStockfish() {
|
||||
if(stockfish == null) {
|
||||
String binary = Stockfish.findBinary();
|
||||
if(binary == null) {
|
||||
JOptionPane.showMessageDialog(chessboard, "Stockfish engine not found! (stockfishchess.org)\nDownload 'stockfish' or 'stockfish.exe' to the program's folder or the system's path.");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
stockfish = new Stockfish(binary);
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(chessboard, "Unable to start Stockfish engine!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return stockfish;
|
||||
}
|
||||
|
||||
public Chessboard getChessboard() {
|
||||
return chessboard;
|
||||
}
|
||||
|
@ -119,12 +138,26 @@ public class Player {
|
|||
return myPieces;
|
||||
}
|
||||
|
||||
public void toggleAutomaticRandom() {
|
||||
automaticRandom = !automaticRandom;
|
||||
public void toggleAutomaticRandom(boolean state) {
|
||||
if(state) automaticSmart = false;
|
||||
automaticRandom = state;
|
||||
}
|
||||
|
||||
public void toggleAutomaticSmart() {
|
||||
automaticSmart = !automaticSmart;
|
||||
public boolean isAutomaticRandom() {
|
||||
return automaticRandom;
|
||||
}
|
||||
|
||||
public void toggleAutomaticSmart(Stockfish stockfish) {
|
||||
boolean state = stockfish != null;
|
||||
if(state) {
|
||||
this.stockfish = stockfish;
|
||||
automaticRandom = false;
|
||||
}
|
||||
automaticSmart = state;
|
||||
}
|
||||
|
||||
public boolean isAutomaticSmart() {
|
||||
return automaticSmart;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.*;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Stockfish {
|
||||
|
||||
private Process engineProcess;
|
||||
private BufferedReader processReader;
|
||||
private OutputStreamWriter processWriter;
|
||||
private Process process;
|
||||
private BufferedReader reader;
|
||||
private OutputStreamWriter writer;
|
||||
|
||||
private static final String PATH = "./stockfish";
|
||||
|
||||
/**
|
||||
* Starts Stockfish engine as a process and initializes it
|
||||
*
|
||||
* @return True on success. False otherwise
|
||||
*/
|
||||
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;
|
||||
public static String findBinary() {
|
||||
ArrayList<String> paths = new ArrayList<>();
|
||||
paths.add(".");
|
||||
for (String path : System.getenv("PATH").split(":")) {
|
||||
paths.add(path);
|
||||
}
|
||||
return true;
|
||||
for (String path : paths) {
|
||||
for (String binary : new String[]{"stockfish", "stockfish.exe"}) {
|
||||
String file = Paths.get(path, binary).toString();
|
||||
if(new File(file).exists()) return file;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Stockfish(String binary) throws IOException {
|
||||
process = Runtime.getRuntime().exec(binary);
|
||||
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
writer = new OutputStreamWriter(process.getOutputStream());
|
||||
}
|
||||
|
||||
public void sendCommand(String command) {
|
||||
try {
|
||||
processWriter.write(command + "\n");
|
||||
processWriter.flush();
|
||||
writer.write(command + "\n");
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public class Stockfish {
|
|||
Thread.sleep(waitTime);
|
||||
sendCommand("isready");
|
||||
while (true) {
|
||||
String text = processReader.readLine();
|
||||
String text = reader.readLine();
|
||||
if (text.equals("readyok"))
|
||||
break;
|
||||
else
|
||||
|
@ -57,8 +57,8 @@ public class Stockfish {
|
|||
}
|
||||
|
||||
public String getBestMove(String fen, int skill, int waitTime) {
|
||||
sendCommand("position fen " + fen);
|
||||
sendCommand("setoption name Skill Level value " + skill);
|
||||
sendCommand("position fen " + fen);
|
||||
sendCommand("go movetime " + waitTime);
|
||||
String[] parts = getOutput(waitTime+150).split("bestmove ");
|
||||
while(parts.length != 2) {
|
||||
|
@ -70,10 +70,9 @@ public class Stockfish {
|
|||
public void stopEngine() {
|
||||
try {
|
||||
sendCommand("quit");
|
||||
processReader.close();
|
||||
processWriter.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
reader.close();
|
||||
writer.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue