Show GtpProgram.java syntax highlighted
package geronimo.hoshigo.model.external;
import geronimo.hoshigo.model.GoProgramConfig;
import geronimo.hoshigo.model.game.Move;
import geronimo.hoshigo.model.game.PassMove;
import geronimo.hoshigo.model.game.Score;
import geronimo.hoshigo.model.game.StoneMove;
import geronimo.hoshigo.model.goban.GoColor;
import geronimo.hoshigo.model.goban.GoColorTools;
import geronimo.hoshigo.model.goban.Vertex;
import geronimo.hoshigo.model.goban.VertexParsingException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;
/**
* Definition d'un programme de Go utilisant le protocole GTP
* dans HoshiGo
*/
public class GtpProgram extends GoProgram
{
/**
* Constructeur
* @param programConfig configuration du programme
* @param options option de lancements du programmes
*/
public GtpProgram(GoProgramConfig programConfig, List<String> options)
{
super(programConfig, options);
// TODO Auto-generated constructor stub
try
{
this.launchProgram();
}
catch (GoProgramException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Vide le goban du programme et change éventuellement sa taille
* @throws GoProgramException
*/
protected synchronized void clearBoard(int gobanSize) throws GoProgramException
{
this.sendCommand("boardsize "+ gobanSize);
if (! this.isOkResponse())
{
throw new GtpProgramException("Erreur de changement de taille de goban");
}
this.sendCommand("clear_board");
if (! this.isOkResponse())
{
throw new GtpProgramException("Erreur lors du vidage du goban");
}
}
/**
* arrête gentillement le programme
*/
public synchronized void stopProgram()
{
this.sendCommand("quit");
this.killProgram();
}
/**
* Récupère la réponse du programme GTP et throw une exception s'il y a une
* erreur de la part du programme récepteur
* @return la chaine de carractère après le "="
* @throws GoProgramException si le programme récepteur n'as pas compris la
* dernière commande
*/
private synchronized String getResponseString() throws GoProgramException
{
String[] respTab = new String[0];
String resp = new String();
// recupère la sortie du programme tant qu'il n'y a que des carratères
// blancs
while (resp.replaceAll("\\s","").equals("") && this.programProcess != null)
{
resp = this.getResponse();
// si il y a interruption du programme alors il se peut qu'on
// reçoive une chaine nulle on la remplace par une chaine vide
// ne pas lever un nullpointerexception à la condition du while
if (resp == null)
{
resp = "";
}
}
// divise la chaine récupérée en 2 parties selon le premier blanc
// rencontré
respTab = resp.split("\\s",2);
// verifie si le premier token est un "=" et non un
if ( ! respTab[0].equals("="))
{
if (respTab.length > 1)
{
throw new GtpProgramException("Erreur : " + respTab[1]);
}
else
{
throw new GtpProgramException("Erreur de communication GTP");
}
}
if (respTab.length <= 1)
{
return "";
}
else
{
return respTab[1];
}
}
/**
* @return le nom du programme
*/
public synchronized String getProgramName() throws GoProgramException
{
this.sendCommand("name");
return this.getResponseString();
}
/**
* @return la version du programme
* @throws GoProgramException
*/
public synchronized String getProgramVersion()throws GoProgramException
{
this.sendCommand("version");
return this.getResponseString();
}
/**
* retourne la réponse du programme en séparrant tout les tokens
* @return la liste des tokens séparés par des blancs
* @throws GoProgramException si une erreur survient
*/
private List<String> getResponseTokens() throws GoProgramException
{
List<String> tokenStrings = new Vector<String>();
for (String s : this.getResponseString().split("\\s"))
{
tokenStrings.add(s);
}
return tokenStrings;
}
/**
* @param color la couleur du joueur
* @return l'ensemble de coups légaux
* @throws GoProgramException
*/
public synchronized Set<Move> getLegalMovesFor(GoColor color) throws GoProgramException
{
// envoie la commande
this.sendCommand("all_legal " + GoColorTools.toChar(color));
//recupère la réponse et la transforme en move
Set<Move> moves = new HashSet<Move>();
for (String s : this.getResponseTokens())
{
try
{
moves.add(new StoneMove(new Vertex(s),color));
}
catch (VertexParsingException e)
{
throw new GtpProgramException("Erreur de parsage de vertex : " +
e.getMessage());
}
}
return moves;
}
/**
* @return le score de la partie
* @throws GoProgramException
*/
public synchronized Score getScore() throws GoProgramException
{
this.sendCommand("final_score");
String strScore = this.getResponseString();
GoColor color;
float points ;
if (strScore.length()>3)
{
char c = strScore.charAt(0);
if (Character.toLowerCase(c) == 'b')
{
color = GoColor.BLACK;
}
else if (Character.toLowerCase(c) == 'w')
{
color = GoColor.WHITE;
}
else
{
throw new GtpProgramException("Erreur de parsing du score : couleur invalide");
}
try
{
points = Float.parseFloat(strScore.substring(1));
}
catch (NumberFormatException e)
{
throw new GtpProgramException("Erreur de parsing du score : " + e.getMessage());
}
return new Score(color,points);
}
else
{
throw new GtpProgramException("Erreur de parsing du score : score vide");
}
}
/**
* Génère le coup joué par le programme parmi un ensemble de coups possibles
* @param color couleur du joueur dont on veut savoir son prochain coup
* @return le coup joué par le programme
* @throws GoProgramException
*/
public synchronized Move genMove(GoColor color) throws GoProgramException
{
// envoie la commande
this.sendCommand("genmove " + GoColorTools.toChar(color));
// recupère la commande
String response = this.getResponseString();
// parse la commande
if (response.toLowerCase().equals("pass"))
{
return new PassMove(color);
}
else
{
try
{
return new StoneMove(new Vertex(response),color);
}
catch (VertexParsingException e)
{
throw new GtpProgramException("Erreur de parsage de vertex : " +
e.getMessage());
}
}
}
/**
* Indique au programme de go qu'il y a un coup qui a été joué
* @param move le coup qui a été joué
* @throws GoProgramException
*/
public synchronized void play(Move move) throws GoProgramException
{
// envoie le coup joué
if (move instanceof StoneMove)
{
this.sendCommand("play " + GoColorTools.toChar(move.color) + " " +
((StoneMove)move).coord);
}
else
{
this.sendCommand("play " + GoColorTools.toChar(move.color) + " PASS");
}
// verifie l'acceptation du programme
if (! this.isOkResponse())
{
throw new GtpProgramException("Erreur lors de l'envoir d'un coup");
}
}
/**
* Verifie l'acceptation de la dernière commande envoyée au programme
* @return <tt>true</tt> si la commande est acceptée, <tt>false</tt> sinon
*/
private boolean isOkResponse()
{
try
{
String response = this.getResponseString();
return response.replace("\\s","").equals("");
}
catch (GoProgramException e)
{
return false;
}
}
/**
* Demande au programme de go d'annuler le dernier mouvements
* @throws GoProgramException
*/
public synchronized void undo() throws GoProgramException
{
//envoie la commande
this.sendCommand("undo");
// verifie l'acceptation du programme
if (! this.isOkResponse())
{
throw new GtpProgramException("Erreur de undo");
}
}
/**
* Met à jour la valeur du komi d'une partie
* @param komi nouvelle valeur du komi
* @throws GoProgramException
*/
public void setKomi(float komi) throws GoProgramException
{
//envoie la commande
this.sendCommand("komi " + komi);
// verifie l'acceptation du programme
if (! this.isOkResponse())
{
throw new GtpProgramException("Erreur lors du changement de komi");
}
}
}
See more files for this project here