diff --git a/.classpath b/.classpath index 4ee4c98..e8e161c 100644 --- a/.classpath +++ b/.classpath @@ -5,5 +5,6 @@ + diff --git a/build.xml b/build.xml index 64d7f8a..b641d96 100644 --- a/build.xml +++ b/build.xml @@ -48,7 +48,8 @@ - + + diff --git a/data/gogame.bat b/data/gogame.bat deleted file mode 100644 index 90b8cf0..0000000 --- a/data/gogame.bat +++ /dev/null @@ -1 +0,0 @@ -java -jar kgsGtp.jar kgsGtp.ini \ No newline at end of file diff --git a/data/kgsGtp.ini b/data/kgsGtp.ini index 3672e75..ca673d5 100644 --- a/data/kgsGtp.ini +++ b/data/kgsGtp.ini @@ -9,5 +9,4 @@ reconnect=t automatch.rank=25k rules=chinese rules.boardSize=9 -rules.time=0 -rules.komi=5.5 \ No newline at end of file +rules.time=0 \ No newline at end of file diff --git a/lib/kgsGtp.jar b/lib/kgsGtp.jar new file mode 100644 index 0000000..450f95c Binary files /dev/null and b/lib/kgsGtp.jar differ diff --git a/src/net/woodyfolsom/msproj/GoGame.java b/src/net/woodyfolsom/msproj/GoGame.java index e2897d8..779cb9f 100644 --- a/src/net/woodyfolsom/msproj/GoGame.java +++ b/src/net/woodyfolsom/msproj/GoGame.java @@ -1,7 +1,14 @@ package net.woodyfolsom.msproj; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintWriter; import java.nio.charset.Charset; +import java.util.Properties; import net.woodyfolsom.msproj.Command.TYPE; import net.woodyfolsom.msproj.policy.AlphaBeta; @@ -13,8 +20,11 @@ import net.woodyfolsom.msproj.policy.RandomMovePolicy; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; +import com.gokgs.client.gtp.GtpClient; +import com.gokgs.client.gtp.Options; -public class GoGame { +public class GoGame implements Runnable { + private static final String PROPS_FILE = "kgsGtp.ini"; private static final int INVALID_MOVE_GENERATOR = 1; private static final Logger LOGGER = Logger.getLogger(GoGame.class .getName()); @@ -22,20 +32,74 @@ public class GoGame { private boolean shutDown = false; private GameConfig gameConfig = new GameConfig(); private GameState gameState = new GameState(9); + private GtpClient client = null; private Policy moveGenerator; + private Properties properties; - public GoGame(Policy moveGenerator) { - this.moveGenerator = moveGenerator; + private PipedOutputStream remoteOutput = new PipedOutputStream(); + private PipedInputStream localInput = new PipedInputStream(remoteOutput); + + private PipedOutputStream localOutputInner = new PipedOutputStream(); + private PipedInputStream remoteInput = new PipedInputStream(localOutputInner); + private PrintWriter localOutput = new PrintWriter(localOutputInner); + + public OutputStream getOutputStream() { + return remoteOutput; } - public static void main(String[] args) { + public InputStream getInputStream() { + return remoteInput; + } + + public Properties getProperties() { + return properties; + } + + public GoGame(Policy moveGenerator, String propFileName) throws IOException { + this.moveGenerator = moveGenerator; + this.properties = new Properties(); + FileInputStream fis = null; + try { + fis = new FileInputStream(propFileName); + properties.load(fis); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException ioe) { + LOGGER.info(ioe.getMessage()); + } + } + } + } + + public void run() { + play(); + } + + public static void main(String[] args) throws IOException { configureLogging(); if (args.length == 0) { - Policy defaultMoveGenerator = new MonteCarloUCT(new RandomMovePolicy(), 2000L); - LOGGER.info("No MoveGenerator specified. Using default: " + defaultMoveGenerator.getClass().getName()); - new GoGame(defaultMoveGenerator).play(); + Policy defaultMoveGenerator = new MonteCarloUCT(new RandomMovePolicy(), 5000L); + LOGGER.info("No MoveGenerator specified. Using default: " + defaultMoveGenerator.toString()); + + GoGame goGame = new GoGame(defaultMoveGenerator, PROPS_FILE); + new Thread(goGame).start(); + + System.out.println("Creating GtpClient"); + goGame.client = new GtpClient(goGame.getInputStream(), goGame.getOutputStream(), new Options(goGame.getProperties(), LOGGER.getName())); + + System.out.println("GtpClient created"); + + System.out.println("Invoking GtpClient.go()..."); + + if (goGame.client.go()) { + System.out.println("GtpClient.go() succeeded."); + } else { + System.out.println("GtpClient.go() failed."); + } } else { - new GoGame(createPolicy(args[0])).play(); + new GoGame(createPolicy(args[0]), PROPS_FILE).play(); } } @@ -60,19 +124,19 @@ public class GoGame { switch (cmd.getType()) { case INVALID: LOGGER.info("Invalid command ignored: " + cmd.getText()); - System.out.println("? Invalid command: " + cmd.getText() + "\n"); + localOutput.println("? Invalid command: " + cmd.getText() + "\n"); break; case boardsize: gameState = new GameState(cmd.getIntField(1)); - System.out.println("=\n"); + localOutput.println("=\n"); break; case clear_board: gameState.clearBoard(); - System.out.println("=\n"); + localOutput.println("=\n"); break; case final_status_list: LOGGER.info(new StateEvaluator(gameConfig).scoreGame(gameState)); - System.out.println("=\n"); + localOutput.println("=\n"); break; case genmove: LOGGER.info("Generating move for:\n" + gameState); @@ -93,13 +157,13 @@ public class GoGame { gameState.playStone(player, nextMove); LOGGER.info(new StateEvaluator(gameConfig).scoreGame(gameState)); - System.out.println("=" + localOutput.println("=" + nextMove.toString() + "\n"); break; case komi: gameConfig.setKomi(cmd.getDoubleField(1)); - System.out.println("=\n"); + localOutput.println("=\n"); break; case list_commands: StringBuilder sb = new StringBuilder("= "); @@ -109,45 +173,60 @@ public class GoGame { sb.append("\n"); } } - System.out.println(sb.toString()); + System.out.println("Sending response: " + sb.toString()); + localOutput.println(sb.toString()); + System.out.println("Response sent."); break; case name: - System.out.println("= CS6601P1\n"); + localOutput.println("= CS6601P1\n"); break; case quit: - System.out.println("=\n"); + localOutput.println("=\n"); shutDown = true; break; case play: if (gameState.playStone(Player.getInstance(cmd.getStringField(1)), cmd .getStringField(2).toUpperCase())) { - System.out.println("=\n"); + localOutput.println("=\n"); } else { String errMsg = "Unable to make requested play: " + cmd.getText(); LOGGER.info(errMsg); LOGGER.info("GameState: " + gameState); - System.out.println("?" + errMsg + "\n"); + localOutput.println("?" + errMsg + "\n"); } LOGGER.info(new StateEvaluator(gameConfig).scoreGame(gameState)); break; case version: - System.out.println("= 0.1\n"); + localOutput.println("= 0.1\n"); break; default: LOGGER.warn("An error occured. Unhandled command: " + cmd); } + localOutput.flush(); } public void play() { byte[] buf = new byte[128]; int inputLength; try { - while (!shutDown && (inputLength = System.in.read(buf)) > 0) { + while (!shutDown && (inputLength = localInput.read(buf)) > 0) { + System.out.println("Waiting for input"); + String commandText = new String(buf, 0, inputLength, Charset.forName("UTF-8")); + + System.out.println("Input received: " + commandText); + LOGGER.info("Command received: " + commandText); - executeCommand(CommandParser.parse(commandText)); + + Command cmd = CommandParser.parse(commandText); + + executeCommand(cmd); + + if (cmd.getType() == Command.TYPE.genmove) { + System.out.println("New game state:\n" + gameState); + } } } catch (IOException ioe) { LOGGER.warn(ioe.getMessage()); diff --git a/src/net/woodyfolsom/msproj/GtpClient.java b/src/net/woodyfolsom/msproj/GtpClient.java deleted file mode 100644 index 19a06c5..0000000 --- a/src/net/woodyfolsom/msproj/GtpClient.java +++ /dev/null @@ -1,48 +0,0 @@ -package net.woodyfolsom.msproj; - -public class GtpClient { - - /** - * Create a new GTP Client. - * - * @param in - * An input stream that will give us any responses from the - * engine. - * @param out - * An output stream that will go to the engine with our commands. - * @param args - * Our options. - */ - public GtpClient(java.io.InputStream in, java.io.OutputStream out, - Options options) { - } - - /** - * Connect to the server and operate the GTP interface. - * - * @return true on success, false if we were - * unable to do what was requested. - */ - public boolean go() { - return false; - } -} - -class Options { - - /** - * Construct a new set of options for the kgsGtp client by pulling values - * out of a set of properties. Any values that we use will be removed from - * the properties, so anything left over is unused. - * - * @param props - * The properties that holds our options as string values. - * @param logName - * The name of the java logger that we will construct. - * @throws IllegalArgumentException - * If any required values are missing or if any illegal values - * are detected. - */ - public Options(java.util.Properties props, String logName) { - } -} diff --git a/src/net/woodyfolsom/msproj/policy/MonteCarloUCT.java b/src/net/woodyfolsom/msproj/policy/MonteCarloUCT.java index 4b98fc9..fd435ec 100644 --- a/src/net/woodyfolsom/msproj/policy/MonteCarloUCT.java +++ b/src/net/woodyfolsom/msproj/policy/MonteCarloUCT.java @@ -139,4 +139,9 @@ public class MonteCarloUCT extends MonteCarlo { Collection prohibitedActions, Player player) { throw new UnsupportedOperationException("Prohibited actions not supported by this class."); } + + @Override + public String toString() { + return "MonteCarloUCT"; + } } \ No newline at end of file