Added engine info serialization and integration into MenuBar

This commit is contained in:
Kai S. K. Engelbart 2019-07-23 16:28:53 +02:00
parent 0a1ab4bab6
commit 5aa48edb93
Signed by: kske
GPG Key ID: 8BEB13EC5DF7EF13
5 changed files with 96 additions and 58 deletions

1
.gitignore vendored
View File

@ -22,3 +22,4 @@ local.properties
# Annotation Processing # Annotation Processing
.apt_generated/ .apt_generated/
/engine_infos.ser

View File

@ -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();
} }

View File

@ -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; }
} }

View File

@ -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; }
} }

View File

@ -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);