Implemented UCI handshake with engine

+ UCI game start in MenuBar
+ UCI game creation method in Game
- Fixed double game instance bug after starting a new game
+ Name and author parsing in UCIReceiver
This commit is contained in:
Kai S. K. Engelbart 2019-07-21 14:35:14 +02:00
parent bce35fc950
commit 77cf661f6f
7 changed files with 31 additions and 12 deletions

View File

@ -62,6 +62,14 @@ public class Game {
return new Game(players, boardPane); return new Game(players, boardPane);
} }
public static Game createUCI(BoardPane boardPane, String enginePath) {
Map<Color, Player> players = new HashMap<>();
players.put(Color.WHITE, new NaturalPlayer(Color.WHITE, boardPane.getOverlayComponent()));
players.put(Color.BLACK, new UCIPlayer(Color.BLACK, enginePath));
return new Game(players, boardPane);
}
public void onMove(Player player, Move move) { public void onMove(Player player, Move move) {
if (board.getPos(move).getColor() == player.color && board.attemptMove(move)) { if (board.getPos(move).getColor() == player.color && board.attemptMove(move)) {
System.out.printf("%s: %s%n", player.color, move); System.out.printf("%s: %s%n", player.color, move);

View File

@ -22,6 +22,7 @@ public class UCIPlayer extends Player {
handle = new UCIHandle(enginePath); handle = new UCIHandle(enginePath);
listener = new UCIPlayerListener(); listener = new UCIPlayerListener();
handle.setListener(listener); handle.setListener(listener);
handle.start();
} catch (IOException ex) { } catch (IOException ex) {
ex.printStackTrace(); ex.printStackTrace();
} }

View File

@ -28,25 +28,21 @@ class UCIPlayerListener implements UCIListener {
@Override @Override
public void onUCIOk() { public void onUCIOk() {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void onReadyOk() { public void onReadyOk() {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void onBestMove(String move) { public void onBestMove(String move) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void onBestMove(String move, String ponderMove) { public void onBestMove(String move, String ponderMove) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
@ -72,7 +68,6 @@ class UCIPlayerListener implements UCIListener {
@Override @Override
public void onRegistrationOk() { public void onRegistrationOk() {
System.out.println("Registration ok"); System.out.println("Registration ok");
} }
@Override @Override

View File

@ -17,13 +17,13 @@ public class UCIHandle {
public UCIHandle(String enginePath) throws IOException { public UCIHandle(String enginePath) throws IOException {
process = new ProcessBuilder(enginePath).start(); process = new ProcessBuilder(enginePath).start();
out = new PrintWriter(process.getOutputStream()); out = new PrintWriter(process.getOutputStream(), true);
receiver = new UCIReceiver(process.getInputStream()); receiver = new UCIReceiver(process.getInputStream());
} }
public void start() { public void start() {
uci();
new Thread(receiver).start(); new Thread(receiver).start();
uci();
} }
/** /**

View File

@ -31,8 +31,9 @@ public class UCIReceiver implements Runnable {
@Override @Override
public void run() { public void run() {
try { try {
while (in.ready()) String line;
parse(in.readLine()); while (!Thread.currentThread().isInterrupted())
if ((line = in.readLine()) != null) parse(line);
} catch (IndexOutOfBoundsException ex) { } catch (IndexOutOfBoundsException ex) {
System.err.println("Too few arguments were provided!"); System.err.println("Too few arguments were provided!");
ex.printStackTrace(); ex.printStackTrace();
@ -72,9 +73,9 @@ public class UCIReceiver implements Runnable {
} }
private void parseId(String line) { private void parseId(String line) {
String param = line.substring(line.indexOf(' ')); String param = line.substring(0, line.indexOf(' '));
String arg = line.substring(param.length() + 1); String arg = line.substring(param.length() + 1);
switch (line) { switch (param) {
case "name": case "name":
listener.onIdName(arg); listener.onIdName(arg);
break; break;

View File

@ -76,5 +76,8 @@ public class MainWindow {
public Game getGame() { return game; } public Game getGame() { return game; }
public void setGame(Game game) { this.game = game; } public void setGame(Game game) {
if (this.game != null) this.game.disconnect();
this.game = game;
}
} }

View File

@ -3,6 +3,7 @@ package dev.kske.chess.ui;
import javax.swing.JMenu; import javax.swing.JMenu;
import javax.swing.JMenuBar; import javax.swing.JMenuBar;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import dev.kske.chess.game.Game; import dev.kske.chess.game.Game;
@ -32,6 +33,7 @@ public class MenuBar extends JMenuBar {
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");
naturalMenuItem.addActionListener((evt) -> startGame(Game.createNatural(boardPane))); naturalMenuItem.addActionListener((evt) -> startGame(Game.createNatural(boardPane)));
@ -44,9 +46,18 @@ public class MenuBar extends JMenuBar {
aiVsAiMenuItem.addActionListener((evt) -> startGame(Game.createAIVsAI(boardPane, 4, 3, -10, -10))); aiVsAiMenuItem.addActionListener((evt) -> startGame(Game.createAIVsAI(boardPane, 4, 3, -10, -10)));
uciMenuItem.addActionListener((evt) -> {
String enginePath = JOptionPane.showInputDialog(getParent(),
"Enter the path to a UCI-compatible chess engine:",
"Engine selection",
JOptionPane.QUESTION_MESSAGE);
if (enginePath != null) startGame(Game.createUCI(boardPane, enginePath));
});
gameMenu.add(naturalMenuItem); gameMenu.add(naturalMenuItem);
gameMenu.add(aiMenuItem); gameMenu.add(aiMenuItem);
gameMenu.add(aiVsAiMenuItem); gameMenu.add(aiVsAiMenuItem);
gameMenu.add(uciMenuItem);
add(gameMenu); add(gameMenu);