Added engine info serialization and integration into MenuBar
This commit is contained in:
parent
b25acff367
commit
e353aef867
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,3 +22,4 @@ local.properties
|
|||||||
|
|
||||||
# Annotation Processing
|
# Annotation Processing
|
||||||
.apt_generated/
|
.apt_generated/
|
||||||
|
/engine_infos.ser
|
||||||
|
@ -144,11 +144,7 @@ public class Board implements Cloneable {
|
|||||||
|
|
||||||
// Update the king's position if the moved piece is the king and castling
|
// Update the king's position if the moved piece is the king and castling
|
||||||
// availability
|
// availability
|
||||||
if (piece.getType() == Type.KING) {
|
if (piece.getType() == Type.KING) kingPos.put(piece.getColor(), move.dest);
|
||||||
kingPos.put(piece.getColor(), move.dest);
|
|
||||||
castlingRights.get(piece.getColor()).put(Type.KING, false);
|
|
||||||
castlingRights.get(piece.getColor()).put(Type.QUEEN, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update log
|
// Update log
|
||||||
log.add(move, capturePiece);
|
log.add(move, capturePiece);
|
||||||
@ -162,6 +158,9 @@ public class Board implements Cloneable {
|
|||||||
// Increment halfmove clock
|
// Increment halfmove clock
|
||||||
++halfmoveClock;
|
++halfmoveClock;
|
||||||
|
|
||||||
|
// Reset halfmove clock
|
||||||
|
if (piece.getType() == Type.PAWN || capturePiece != null) halfmoveClock = 0;
|
||||||
|
|
||||||
updateCastlingRights();
|
updateCastlingRights();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package dev.kske.chess.ui;
|
package dev.kske.chess.ui;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -17,45 +22,77 @@ public class EngineUtil {
|
|||||||
|
|
||||||
private static volatile List<EngineInfo> engineInfos;
|
private static volatile List<EngineInfo> engineInfos;
|
||||||
|
|
||||||
|
private static final String engineInfoFile = "engine_infos.ser";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
engineInfos = new ArrayList<>();
|
loadEngineInfos();
|
||||||
}
|
}
|
||||||
|
|
||||||
private EngineUtil() {}
|
private EngineUtil() {}
|
||||||
|
|
||||||
public static void addEngine(String enginePath) {
|
public static void addEngine(String enginePath) {
|
||||||
try {
|
try {
|
||||||
EngineInfo info = new EngineInfo(enginePath);
|
EngineInfo info = new EngineInfo(enginePath);
|
||||||
UCIHandle handle = new UCIHandle(enginePath);
|
UCIHandle handle = new UCIHandle(enginePath);
|
||||||
handle.setListener(new UCIListener() {
|
handle.setListener(new UCIListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIdName(String name) {
|
public void onIdName(String name) {
|
||||||
info.name = name;
|
info.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIdAuthor(String author) {
|
public void onIdAuthor(String author) {
|
||||||
info.author = author;
|
info.author = author;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUCIOk() {
|
public void onUCIOk() {
|
||||||
engineInfos.add(info);
|
engineInfos.add(info);
|
||||||
System.out.println("Engine: " + info.name);
|
handle.quit();
|
||||||
}
|
saveEngineInfos();
|
||||||
});
|
}
|
||||||
handle.start();
|
});
|
||||||
} catch (IOException ex) {
|
handle.start();
|
||||||
ex.printStackTrace();
|
} catch (IOException ex) {
|
||||||
}
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EngineInfo {
|
@SuppressWarnings("unchecked")
|
||||||
|
private static void loadEngineInfos() {
|
||||||
|
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(engineInfoFile))) {
|
||||||
|
Object obj = in.readObject();
|
||||||
|
if (obj instanceof ArrayList<?>) engineInfos = (ArrayList<EngineInfo>) obj;
|
||||||
|
else throw new IOException("Serialized object has the wrong class.");
|
||||||
|
} catch (ClassNotFoundException | IOException ex) {
|
||||||
|
engineInfos = new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void saveEngineInfos() {
|
||||||
|
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(engineInfoFile))) {
|
||||||
|
out.writeObject(engineInfos);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EngineInfo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -474177108900833005L;
|
||||||
|
|
||||||
public String path, name, author;
|
public String path, name, author;
|
||||||
|
|
||||||
public EngineInfo(String path) {
|
public EngineInfo(String path) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name + " by " + author + " at " + path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<EngineInfo> getEngineInfos() { return engineInfos; }
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import javax.swing.JTable;
|
|||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.table.DefaultTableModel;
|
import javax.swing.table.DefaultTableModel;
|
||||||
|
|
||||||
import dev.kske.chess.board.Log;
|
import dev.kske.chess.board.Move;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project: <strong>Chess</strong><br>
|
* Project: <strong>Chess</strong><br>
|
||||||
@ -23,8 +23,6 @@ public class LogFrame extends JFrame {
|
|||||||
private JPanel mcontentPane;
|
private JPanel mcontentPane;
|
||||||
private JTable mtable;
|
private JTable mtable;
|
||||||
|
|
||||||
private Log log;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the frame.
|
* Create the frame.
|
||||||
*/
|
*/
|
||||||
@ -38,17 +36,12 @@ public class LogFrame extends JFrame {
|
|||||||
setContentPane(mcontentPane);
|
setContentPane(mcontentPane);
|
||||||
|
|
||||||
mtable = new JTable();
|
mtable = new JTable();
|
||||||
mtable.setModel(new DefaultTableModel(new Object[][] {}, new String[] { "Black", "New column" }));
|
mtable.setModel(new DefaultTableModel(new Object[][] {}, new String[] { "White", "Black" }));
|
||||||
mtable.setEnabled(false);
|
mtable.setEnabled(false);
|
||||||
mcontentPane.add(mtable, BorderLayout.CENTER);
|
mcontentPane.add(mtable, BorderLayout.CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
public void add(Move move) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Log getLog() { return log; }
|
|
||||||
|
|
||||||
public void setLog(Log log) { this.log = log; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import javax.swing.JMenuItem;
|
|||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
import dev.kske.chess.game.Game;
|
import dev.kske.chess.game.Game;
|
||||||
|
import dev.kske.chess.ui.EngineUtil.EngineInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project: <strong>Chess</strong><br>
|
* Project: <strong>Chess</strong><br>
|
||||||
@ -17,12 +18,12 @@ public class MenuBar extends JMenuBar {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -7221583703531248228L;
|
private static final long serialVersionUID = -7221583703531248228L;
|
||||||
|
|
||||||
private final MainWindow mainWindow;
|
private final MainWindow mainWindow;
|
||||||
private final BoardPane boardPane;
|
private final BoardPane boardPane;
|
||||||
|
|
||||||
public MenuBar(MainWindow mainWindow) {
|
public MenuBar(MainWindow mainWindow) {
|
||||||
this.mainWindow = mainWindow;
|
this.mainWindow = mainWindow;
|
||||||
boardPane = mainWindow.getBoardPane();
|
boardPane = mainWindow.getBoardPane();
|
||||||
|
|
||||||
initGameMenu();
|
initGameMenu();
|
||||||
initEngineMenu();
|
initEngineMenu();
|
||||||
@ -31,10 +32,10 @@ public class MenuBar extends JMenuBar {
|
|||||||
private void initGameMenu() {
|
private void initGameMenu() {
|
||||||
JMenu gameMenu = new JMenu("Game");
|
JMenu gameMenu = new JMenu("Game");
|
||||||
|
|
||||||
JMenuItem naturalMenuItem = new JMenuItem("Game against natural opponent");
|
JMenuItem naturalMenuItem = new JMenuItem("Game against natural opponent");
|
||||||
JMenuItem aiMenuItem = new JMenuItem("Game against artificial opponent");
|
JMenuItem aiMenuItem = new JMenuItem("Game against artificial opponent");
|
||||||
JMenuItem aiVsAiMenuItem = new JMenuItem("Watch AI vs. AI");
|
JMenuItem aiVsAiMenuItem = new JMenuItem("Watch AI vs. AI");
|
||||||
JMenuItem uciMenuItem = new JMenuItem("UCI");
|
JMenuItem uciMenuItem = new JMenuItem("UCI");
|
||||||
|
|
||||||
naturalMenuItem.addActionListener((evt) -> startGame(Game.createNatural(boardPane)));
|
naturalMenuItem.addActionListener((evt) -> startGame(Game.createNatural(boardPane)));
|
||||||
|
|
||||||
@ -49,10 +50,10 @@ public class MenuBar extends JMenuBar {
|
|||||||
|
|
||||||
uciMenuItem.addActionListener((evt) -> {
|
uciMenuItem.addActionListener((evt) -> {
|
||||||
String enginePath = JOptionPane.showInputDialog(getParent(),
|
String enginePath = JOptionPane.showInputDialog(getParent(),
|
||||||
"Enter the path to a UCI-compatible chess engine:", "Engine selection",
|
"Enter the path to a UCI-compatible chess engine:",
|
||||||
|
"Engine selection",
|
||||||
JOptionPane.QUESTION_MESSAGE);
|
JOptionPane.QUESTION_MESSAGE);
|
||||||
if (enginePath != null)
|
if (enginePath != null) startGame(Game.createUCI(boardPane, enginePath));
|
||||||
startGame(Game.createUCI(boardPane, enginePath));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
gameMenu.add(naturalMenuItem);
|
gameMenu.add(naturalMenuItem);
|
||||||
@ -68,22 +69,29 @@ public class MenuBar extends JMenuBar {
|
|||||||
|
|
||||||
private void initEngineMenu() {
|
private void initEngineMenu() {
|
||||||
JMenu engineMenu = new JMenu("Engine");
|
JMenu engineMenu = new JMenu("Engine");
|
||||||
|
|
||||||
JMenuItem addEngineMenuItem = new JMenuItem("Add engine");
|
JMenuItem addEngineMenuItem = new JMenuItem("Add engine");
|
||||||
|
|
||||||
addEngineMenuItem.addActionListener((evt) -> {
|
addEngineMenuItem.addActionListener((evt) -> {
|
||||||
String enginePath = JOptionPane.showInputDialog(getParent(),
|
String enginePath = JOptionPane.showInputDialog(getParent(),
|
||||||
"Enter the path to a UCI-compatible chess engine:", "Engine selection",
|
"Enter the path to a UCI-compatible chess engine:",
|
||||||
|
"Engine selection",
|
||||||
JOptionPane.QUESTION_MESSAGE);
|
JOptionPane.QUESTION_MESSAGE);
|
||||||
if(enginePath != null)
|
if (enginePath != null) {
|
||||||
EngineUtil.addEngine(enginePath);
|
EngineUtil.addEngine(enginePath);
|
||||||
|
// TODO: Rebuilt the engine menu
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
engineMenu.add(addEngineMenuItem);
|
engineMenu.add(addEngineMenuItem);
|
||||||
|
|
||||||
|
for (EngineInfo info : EngineUtil.getEngineInfos()) {
|
||||||
|
JMenuItem engineMenuItem = new JMenuItem(info.name);
|
||||||
|
engineMenuItem.addActionListener((evt) -> startGame(Game.createUCI(boardPane, info.path)));
|
||||||
|
engineMenu.add(engineMenuItem);
|
||||||
|
}
|
||||||
|
|
||||||
add(engineMenu);
|
add(engineMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startGame(Game game) {
|
private void startGame(Game game) {
|
||||||
mainWindow.setGame(game);
|
mainWindow.setGame(game);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user