Stockfish improvements
This commit is contained in:
parent
4699e26afc
commit
0025bf344f
|
@ -34,11 +34,8 @@ public class Chess {
|
|||
window.setSize(800, 600);
|
||||
window.setMinimumSize(new Dimension(800, 600));
|
||||
|
||||
chessboard = Chessboard.fromFEN(DEFAULT_FEN);
|
||||
newGame(Chessboard.fromFEN(DEFAULT_FEN));
|
||||
|
||||
window.setJMenuBar(createMenuBar());
|
||||
|
||||
window.add(chessboard, BorderLayout.CENTER);
|
||||
window.pack();
|
||||
|
||||
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
@ -212,14 +209,22 @@ public class Chess {
|
|||
|
||||
public static void setCPU(Player player, String mode, Runnable update) {
|
||||
if(mode != null && mode.equals("smart")) {
|
||||
Stockfish stockfish = player.getStockfish();
|
||||
if(stockfish != null) {
|
||||
player.setStockfish(stockfish);
|
||||
player.setCPU(mode);
|
||||
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;
|
||||
}
|
||||
if(Stockfish.getInstance() == null) {
|
||||
try {
|
||||
Stockfish.create(binary);
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(chessboard, "Unable to start Stockfish engine!");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
player.setCPU(mode);
|
||||
}
|
||||
player.setCPU(mode);
|
||||
update.run();
|
||||
}
|
||||
|
||||
|
@ -232,8 +237,10 @@ public class Chess {
|
|||
}
|
||||
|
||||
public static void newGame(Chessboard newChessboard) {
|
||||
window.remove(chessboard);
|
||||
if(chessboard != null) window.remove(chessboard);
|
||||
chessboard = newChessboard;
|
||||
Stockfish sf = Stockfish.getInstance();
|
||||
if(sf != null) sf.stopEngine();
|
||||
window.setJMenuBar(createMenuBar());
|
||||
window.add(chessboard, BorderLayout.CENTER);
|
||||
repaintWindow();
|
||||
|
|
|
@ -511,6 +511,14 @@ public class Chessboard extends JPanel {
|
|||
public void changeActivePlayer() {
|
||||
activePlayer = getOtherPlayer();
|
||||
repaintRootPane();
|
||||
if(player1.inCheck()) {
|
||||
System.out.println("Player1 in check!");
|
||||
if(player1.inMate()) System.out.println("Player1 in mate!");
|
||||
}
|
||||
if(player2.inCheck()) {
|
||||
System.out.println("Player2 in check!");
|
||||
if(player2.inMate()) System.out.println("Player2 in mate!");
|
||||
}
|
||||
activePlayer.play();
|
||||
}
|
||||
|
||||
|
|
|
@ -49,16 +49,14 @@ public class ChessboardMouseAdapter extends MouseAdapter {
|
|||
PiecePosition pos = c.getPieceCoordinates(me.getX(), me.getY());
|
||||
APiece piece = c.getPiece(pos.x, pos.y);
|
||||
APiece selectedPiece = c.getSelectedPiece();
|
||||
if (piece != null && piece.getPlayer() == c.getActivePlayer() && selectedPiece != piece) {
|
||||
if (selectedPiece != piece && canMove(c, piece)) {
|
||||
c.setSelectedPiece(piece);
|
||||
c.showPossibleMoves(piece.getPossibleMoves());
|
||||
c.repaintRootPane();
|
||||
} else if(selectedPiece != null) {
|
||||
if(selectedPiece.getPossibleMoves()[pos.y][pos.x]) {
|
||||
selectedPiece.move(pos);
|
||||
if(c.getActivePlayer().inCheck()) System.out.println("Inactive player in check!");
|
||||
c.changeActivePlayer();
|
||||
if(c.getActivePlayer().inCheck()) System.out.println("Active player in check!");
|
||||
} else {
|
||||
c.repaintRootPane();
|
||||
}
|
||||
|
@ -71,7 +69,7 @@ public class ChessboardMouseAdapter extends MouseAdapter {
|
|||
Chessboard c = (Chessboard) me.getSource();
|
||||
PiecePosition pos = c.getPieceCoordinates(me.getX(), me.getY());
|
||||
APiece piece = c.getPiece(pos.x, pos.y);
|
||||
if (piece != null && piece.getPlayer() == c.getActivePlayer()) {
|
||||
if (canMove(c, piece)) {
|
||||
c.setSelectedPiece(piece);
|
||||
c.showPossibleMoves(piece.getPossibleMoves());
|
||||
c.repaintRootPane();
|
||||
|
@ -97,9 +95,7 @@ public class ChessboardMouseAdapter extends MouseAdapter {
|
|||
if(piece != null) {
|
||||
if(piece.getPossibleMoves()[pos.y][pos.x]) {
|
||||
piece.move(pos, false);
|
||||
if(c.getActivePlayer().inCheck()) System.out.println("Inactive player in check!");
|
||||
c.changeActivePlayer();
|
||||
if(c.getActivePlayer().inCheck()) System.out.println("Active player in check!");
|
||||
} else {
|
||||
c.repaintRootPane();
|
||||
}
|
||||
|
@ -108,4 +104,10 @@ public class ChessboardMouseAdapter extends MouseAdapter {
|
|||
c.showPossibleMoves(null);
|
||||
}
|
||||
|
||||
public boolean canMove(Chessboard chessboard, APiece piece) {
|
||||
if(piece == null) return false;
|
||||
Player player = piece.getPlayer();
|
||||
return player == chessboard.getActivePlayer() && player.getCPU() == null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import javax.swing.*;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import java.util.Timer;
|
||||
|
@ -15,10 +13,10 @@ public class Player {
|
|||
|
||||
private King king;
|
||||
|
||||
private Stockfish stockfish;
|
||||
|
||||
private String cpu;
|
||||
|
||||
private boolean isPlaying = false;
|
||||
|
||||
public Player(Chessboard chessboard, StartPosition startPosition, PieceColor color) {
|
||||
this.chessboard = chessboard;
|
||||
this.color = color;
|
||||
|
@ -28,9 +26,22 @@ public class Player {
|
|||
public boolean inCheck() {
|
||||
return king.isEndangered();
|
||||
}
|
||||
|
||||
public boolean inMate() {
|
||||
for (APiece piece : getPieces()) {
|
||||
boolean[][] possibleMoves = piece.getPossibleMoves();
|
||||
for (int y = 0; y < possibleMoves.length; y++) {
|
||||
for (int x = 0; x < possibleMoves[y].length; x++) {
|
||||
if(possibleMoves[y][x]) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void play() {
|
||||
if(cpu == null) return;
|
||||
isPlaying = true;
|
||||
Timer t = new Timer();
|
||||
t.schedule(new TimerTask() {
|
||||
@Override
|
||||
|
@ -39,9 +50,10 @@ public class Player {
|
|||
if (cpu.equals("random")) randomMove();
|
||||
if (cpu.equals("smart")) smartMove();
|
||||
}
|
||||
isPlaying = false;
|
||||
t.cancel();
|
||||
}
|
||||
}, 1000, 1000);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
public boolean randomMove() {
|
||||
|
@ -75,38 +87,20 @@ public class Player {
|
|||
}
|
||||
|
||||
public boolean smartMove() {
|
||||
stockfish = getStockfish();
|
||||
Stockfish stockfish = Stockfish.getInstance();
|
||||
if(stockfish == null) return false;
|
||||
String fen = chessboard.toFEN();
|
||||
String bestMove = stockfish.getBestMove(fen, 0, 500);
|
||||
if(bestMove == null) return false;
|
||||
PiecePosition fromPos = PiecePosition.fromString(bestMove.substring(0, 2));
|
||||
PiecePosition toPos = PiecePosition.fromString(bestMove.substring(2, 4));
|
||||
if(fromPos == null || toPos == null) return false;
|
||||
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;
|
||||
}
|
||||
|
@ -141,15 +135,11 @@ public class Player {
|
|||
|
||||
public void setCPU(String cpu) {
|
||||
this.cpu = cpu;
|
||||
if(cpu != null && chessboard.getActivePlayer() == this) play();
|
||||
if(chessboard.getActivePlayer() == this && !isPlaying) play();
|
||||
}
|
||||
|
||||
public String getCPU() {
|
||||
return cpu;
|
||||
}
|
||||
|
||||
public void setStockfish(Stockfish stockfish) {
|
||||
this.stockfish = stockfish;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,16 @@ public class Stockfish {
|
|||
private BufferedReader reader;
|
||||
private OutputStreamWriter writer;
|
||||
|
||||
public static Stockfish instance;
|
||||
|
||||
public static void create(String binary) throws IOException {
|
||||
instance = new Stockfish(binary);
|
||||
}
|
||||
|
||||
public static Stockfish getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static String findBinary() {
|
||||
ArrayList<String> paths = new ArrayList<>();
|
||||
paths.add(".");
|
||||
|
@ -38,20 +48,16 @@ public class Stockfish {
|
|||
}
|
||||
}
|
||||
|
||||
public String getOutput(int waitTime) {
|
||||
public String getOutput(int waitTime) throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
try {
|
||||
Thread.sleep(waitTime);
|
||||
sendCommand("isready");
|
||||
while (true) {
|
||||
String text = reader.readLine();
|
||||
if (text.equals("readyok"))
|
||||
break;
|
||||
else
|
||||
buffer.append(text + "\n");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Thread.sleep(waitTime);
|
||||
sendCommand("isready");
|
||||
while (true) {
|
||||
String text = reader.readLine();
|
||||
if (text.equals("readyok"))
|
||||
break;
|
||||
else
|
||||
buffer.append(text + "\n");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
@ -60,9 +66,15 @@ public class Stockfish {
|
|||
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) {
|
||||
parts = getOutput(150).split("bestmove ");
|
||||
String[] parts = new String[0];
|
||||
try {
|
||||
parts = getOutput(waitTime+150).split("bestmove ");
|
||||
while(parts.length != 2) {
|
||||
parts = getOutput(150).split("bestmove ");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return parts[1].split(" ")[0];
|
||||
}
|
||||
|
@ -73,6 +85,7 @@ public class Stockfish {
|
|||
reader.close();
|
||||
writer.close();
|
||||
} catch (IOException e) {}
|
||||
instance = null;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue