Game can now be run using java -jar GoGame.jar.

Rather than relying on the kgsGtp.jar application to run GoGame,
the GoGame agent calls the GtpClient using PipedInput/OutputStreams.
This commit is contained in:
cs6601
2012-09-06 09:43:32 -04:00
parent d4acc5beda
commit ca6863b43e
8 changed files with 110 additions and 74 deletions

View File

@@ -5,5 +5,6 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="lib" path="lib/junit-4.10.jar"/>
<classpathentry kind="lib" path="lib/log4j-1.2.16.jar"/>
<classpathentry kind="lib" path="lib/kgsGtp.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -48,7 +48,8 @@
<jar jarfile="${dist}/GoGame.jar">
<fileset dir="${build}" excludes="**/*Test.class" />
<manifest>
<attribute name="Main-Class" value="cs6601.p1.GoGame" />
<attribute name="Main-Class" value="net.woodyfolsom.msproj.GoGame" />
<attribute name="Class-Path" value="kgsGtp.jar log4j-1.2.16.jar"/>
</manifest>
</jar>
</target>

View File

@@ -1 +0,0 @@
java -jar kgsGtp.jar kgsGtp.ini

View File

@@ -9,5 +9,4 @@ reconnect=t
automatch.rank=25k
rules=chinese
rules.boardSize=9
rules.time=0
rules.komi=5.5
rules.time=0

BIN
lib/kgsGtp.jar Normal file

Binary file not shown.

View File

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

View File

@@ -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 <code>true</code> on success, <code>false</code> 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) {
}
}

View File

@@ -139,4 +139,9 @@ public class MonteCarloUCT extends MonteCarlo {
Collection<Action> prohibitedActions, Player player) {
throw new UnsupportedOperationException("Prohibited actions not supported by this class.");
}
@Override
public String toString() {
return "MonteCarloUCT";
}
}