soc.robot
Class SOCRobotClient

java.lang.Object
  extended by soc.client.SOCDisplaylessPlayerClient
      extended by soc.robot.SOCRobotClient
All Implemented Interfaces:
java.lang.Runnable

public class SOCRobotClient
extends SOCDisplaylessPlayerClient

This is a robot client that can play Settlers of Catan.

Once connected, messages from the server are processed in treat(SOCMessage). For each game this robot client plays, there is a SOCRobotBrain.

The built-in robots must be the same version as the server, to simplify things. Third-party bots might be based on this code and be other versions, to simplify their maintenance.

The IMAROBOT connect message gives the bot's class name and a required security cookie, which is passed into the robot client constructor and which must match the server's generated cookie. You can set the server's cookie by setting the server's jsettlers.bots.cookie parameter, or view it by setting jsettlers.bots.showcookie, when starting the server.

Once a bot has connected to the server, it waits to be asked to join games via ROBOTJOINREQUEST messages. When it receives that message type, the bot replies with JOINGAME and the server responds with JOINGAMEAUTH. That message handler creates a SOCRobotBrain to play the game it is joining.

Author:
Robert S Thomas

Field Summary
private  java.util.Hashtable<java.lang.String,CappedQueue<SOCMessage>> brainQs
          the message queues for the different brains
protected  int cleanBrainKills
          number of clean brain kills
private  java.lang.String cookie
          The security cookie value; required by server v1.1.19 and higher.
static java.lang.String CURRENT_PLANS
          constants for debug recording
static java.lang.String CURRENT_RESOURCES
           
private  SOCRobotParameters currentRobotParameters
          the current robot parameters for robot brains
private static boolean debugRandomPause
          For debugging/regression testing, randomly pause responding for several seconds, to simulate a "stuck" robot brain.
private static double DEBUGRANDOMPAUSE_FREQ
          When debugRandomPause is true but not debugRandomPauseActive, frequency of activating it; checked for each non-SOCGameTextMsg and non-SOCGameServerText message received during our own turn.
private static int DEBUGRANDOMPAUSE_SECONDS
          When debugRandomPauseActive is activated, pause this many seconds before continuing.
private  boolean debugRandomPauseActive
          Is debugRandomPause currently in effect for this client? If so, store messages into debugRandomPauseQueue instead of sending them to robotBrains immediately.
private  java.util.Vector<SOCMessage> debugRandomPauseQueue
          When debugRandomPauseActive is true, store incoming messages from the server into this queue until debugRandomPauseUntil.
private  long debugRandomPauseUntil
          When debugRandomPauseActive is true, resume at this time; same format as System.currentTimeMillis().
private  java.util.Hashtable<java.lang.String,java.util.Map<java.lang.String,SOCGameOption>> gameOptions
          options for all games on the server we've been asked to join.
protected  int gamesFinished
          number of games finished
protected  int gamesPlayed
          number of games this bot has played
protected  int gamesWon
          number of games this bot has won
(package private)  boolean printedInitialWelcome
          Have we printed the initial welcome msg from server? Suppress further ones (disconnect-reconnect).
private  java.lang.Thread readerRobot
          the thread that reads incoming messages
(package private)  SOCRobotResetThread resetThread
          used to maintain connection
private  java.util.Hashtable<java.lang.String,SOCRobotBrain> robotBrains
          the robot's "brains", 1 for each game this robot is currently playing.
private  java.util.Hashtable<java.lang.String,java.lang.Integer> seatRequests
          a table of requests from the server to sit at games
protected  long startTime
          start time
 
Fields inherited from class soc.client.SOCDisplaylessPlayerClient
channels, connected, doc, ex, games, gotPassword, host, in, lastMessage, nickname, out, password, port, reader, rejected, s, sFeatures, sLocal, sLocalFeatures, sLocalVersion, STATSPREFEX, strSocketName, sVersion
 
Constructor Summary
SOCRobotClient(java.lang.String h, int p, java.lang.String nn, java.lang.String pw, java.lang.String co)
          Constructor for connecting to the specified host, on the specified port
SOCRobotClient(java.lang.String s, java.lang.String nn, java.lang.String pw, java.lang.String co)
          Constructor for connecting to a local game (practice) on a local stringport.
 
Method Summary
 void addCleanKill()
          add one the the number of clean brain kills
 void debugPrintBrainStatus(java.lang.String gameName, boolean sendTextToGame)
          Print brain variables and status for this game, to System.err or as SOCGameTextMsg sent to the game's members, by calling SOCRobotBrain.debugPrintBrainStatus().
 void destroy()
          losing connection to server; leave all games, then try to reconnect
 void disconnectReconnect()
          disconnect and then try to reconnect.
protected  void handleADMINPING(SOCAdminPing mes)
          handle the admin ping message
protected  void handleADMINRESET(SOCAdminReset mes)
          handle the admin reset message
protected  void handleCHANGEFACE(SOCChangeFace mes)
          handle the "change face" message
protected  void handleCLEARTRADEMSG(SOCClearTradeMsg mes)
          handle the "clear trade" message
protected  void handleDELETEGAME(SOCDeleteGame mes)
          handle the "delete game" message
protected  void handleGAMEMEMBERS(SOCGameMembers mes)
          handle the "game members" message, which indicates the entire game state has now been sent.
protected  void handleGAMESTATE(SOCGameState mes)
          handle the "game state" message
private  void handleGAMETEXTMSG_debug(SOCGameTextMsg mes)
          Handle debug text messages from players to the robot, which start with the robot's nickname + ":".
protected  void handleGAMETEXTMSG(SOCGameTextMsg mes)
          handle the "game text message" message
protected  void handleJOINGAME(SOCJoinGame mes)
          handle the "join game" message
protected  void handleJOINGAMEAUTH(SOCJoinGameAuth mes, boolean isPractice)
          handle the "join game authorization" message
protected  void handleLARGESTARMY(SOCLargestArmy mes)
          handle the "largest army" message
protected  void handleLONGESTROAD(SOCLongestRoad mes)
          handle the "longest road" message
protected  void handlePutBrainQ(SOCMessageForGame mes)
          handle any per-game message that just needs to go into its game's brainQs.
protected  void handlePUTPIECE(SOCPutPiece mes)
          handle the "put piece" message
protected  void handleRESETBOARDAUTH(SOCResetBoardAuth mes)
          handle board reset (new game with same players, same game name).
protected  void handleROBOTDISMISS(SOCRobotDismiss mes)
          handle the "dismiss robot" message
protected  void handleROBOTJOINGAMEREQUEST(SOCRobotJoinGameRequest mes)
          handle the "join game request" message.
protected  void handleSERVERPING(SOCServerPing mes)
          handle the server ping message.
protected  void handleSITDOWN(SOCSitDown mes)
          handle the "someone is sitting down" message
protected  void handleSTATUSMESSAGE(SOCStatusMessage mes)
          handle the "status message" message by printing it to System.err; messages with status value 0 are ignored (no problem is being reported) once the initial welcome message has been printed.
protected  void handleUPDATEROBOTPARAMS(SOCUpdateRobotParams mes)
          handle the update robot params message
 void init()
          Initialize the robot player; connect to server, send first messages
 void leaveGame(SOCGame ga, java.lang.String leaveReason, boolean showDebugTrace)
          the user leaves the given game
static void main(java.lang.String[] args)
          for stand-alones
protected  void sendRecordsText(SOCGame ga, java.util.Vector<java.lang.String> record)
          Call sendText on each string element of record.
 void treat(SOCMessage mes)
          Treat the incoming messages.
 
Methods inherited from class soc.client.SOCDisplaylessPlayerClient
acceptOffer, bankTrade, buildRequest, buyDevCard, cancelBuildRequest, changeFace, choosePlayer, chSend, clearOffer, discard, disconnect, discoveryPick, endTurn, getNickname, handleBCASTTEXTMSG, handleBOARDLAYOUT, handleBOARDLAYOUT2, handleBOARDSPECIALEDGE, handleCANCELBUILDREQUEST, handleCHANNELS, handleCHOOSEPLAYERREQUEST, handleCLEAROFFER, handleDELETECHANNEL, handleDEVCARDACTION, handleDEVCARDCOUNT, handleDICERESULT, handleDICERESULTRESOURCES, handleDICERESULTRESOURCES, handleDISCARDREQUEST, handleFIRSTPLAYER, handleGAMES, handleGAMESERVERTEXT, handleGAMESTATS, handleINVENTORYITEMACTION, handleJOIN, handleJOINAUTH, handleLEAVE, handleLEAVEGAME, handleMAKEOFFER, handleMEMBERS, handleMOVEPIECE, handleMOVEROBBER, handleNEWCHANNEL, handleNEWGAME, handlePIECEVALUE, handlePLAYERELEMENT_numKnights, handlePLAYERELEMENT_numPieces, handlePLAYERELEMENT_numRsrc, handlePLAYERELEMENT_simple, handlePLAYERELEMENT, handlePOTENTIALSETTLEMENTS, handlePUTPIECE, handleREJECTCONNECTION, handleREJECTOFFER, handleREMOVEPIECE, handleRESOURCECOUNT, handleREVEALFOGHEX, handleSETPLAYEDDEVCARD, handleSETSEATLOCK, handleSETSPECIALITEM, handleSETTURN, handleSIMPLEACTION, handleSIMPLEREQUEST, handleSTARTGAME, handleTEXTMSG, handleTURN, leaveChannel, leaveGame, monopolyPick, moveRobber, offerTrade, pickFreeResources, pickSpecialItem, playDevCard, put, putPiece, rejectOffer, resend, rollDice, run, sendText, setSeatLock, simpleRequest, sitDown, startGame
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CURRENT_PLANS

public static final java.lang.String CURRENT_PLANS
constants for debug recording

See Also:
Constant Field Values

CURRENT_RESOURCES

public static final java.lang.String CURRENT_RESOURCES
See Also:
Constant Field Values

debugRandomPause

private static boolean debugRandomPause
For debugging/regression testing, randomly pause responding for several seconds, to simulate a "stuck" robot brain.

Note: This debugging tool is not scalable to many simultaneous games, because it delays all messages, not just ones for a specific game / brain, and it won't be our turn in each of those games.

Since:
1.1.11
See Also:
DEBUGRANDOMPAUSE_FREQ, debugRandomPauseActive

debugRandomPauseActive

private boolean debugRandomPauseActive
Is debugRandomPause currently in effect for this client? If so, store messages into debugRandomPauseQueue instead of sending them to robotBrains immediately. The pause goes on until debugRandomPauseUntil arrives. This is all handled within treat(SOCMessage).

Since:
1.1.11

debugRandomPauseQueue

private java.util.Vector<SOCMessage> debugRandomPauseQueue
When debugRandomPauseActive is true, store incoming messages from the server into this queue until debugRandomPauseUntil. Initialized in treat(SOCMessage).

Since:
1.1.11

debugRandomPauseUntil

private long debugRandomPauseUntil
When debugRandomPauseActive is true, resume at this time; same format as System.currentTimeMillis().

Since:
1.1.11
See Also:
DEBUGRANDOMPAUSE_SECONDS

DEBUGRANDOMPAUSE_FREQ

private static final double DEBUGRANDOMPAUSE_FREQ
When debugRandomPause is true but not debugRandomPauseActive, frequency of activating it; checked for each non-SOCGameTextMsg and non-SOCGameServerText message received during our own turn.

Since:
1.1.11
See Also:
Constant Field Values

DEBUGRANDOMPAUSE_SECONDS

private static final int DEBUGRANDOMPAUSE_SECONDS
When debugRandomPauseActive is activated, pause this many seconds before continuing.

See Also:
debugRandomPauseUntil, Constant Field Values

cookie

private java.lang.String cookie
The security cookie value; required by server v1.1.19 and higher.

Since:
1.1.19

readerRobot

private java.lang.Thread readerRobot
the thread that reads incoming messages


currentRobotParameters

private SOCRobotParameters currentRobotParameters
the current robot parameters for robot brains


robotBrains

private java.util.Hashtable<java.lang.String,SOCRobotBrain> robotBrains
the robot's "brains", 1 for each game this robot is currently playing.

See Also:
SOCDisplaylessPlayerClient.games

brainQs

private java.util.Hashtable<java.lang.String,CappedQueue<SOCMessage>> brainQs
the message queues for the different brains


seatRequests

private java.util.Hashtable<java.lang.String,java.lang.Integer> seatRequests
a table of requests from the server to sit at games


gameOptions

private java.util.Hashtable<java.lang.String,java.util.Map<java.lang.String,SOCGameOption>> gameOptions
options for all games on the server we've been asked to join. Some games may have no options, so will have no entry here, although they will have an entry in SOCDisplaylessPlayerClient.games once joined. Key = game name, Value = map of game's SOCGameOptions. Entries are added in handleROBOTJOINGAMEREQUEST(SOCRobotJoinGameRequest). Since the robot and server are the same version, the set of "known options" will always be in sync.


gamesPlayed

protected int gamesPlayed
number of games this bot has played


gamesFinished

protected int gamesFinished
number of games finished


gamesWon

protected int gamesWon
number of games this bot has won


cleanBrainKills

protected int cleanBrainKills
number of clean brain kills


startTime

protected long startTime
start time


resetThread

SOCRobotResetThread resetThread
used to maintain connection


printedInitialWelcome

boolean printedInitialWelcome
Have we printed the initial welcome msg from server? Suppress further ones (disconnect-reconnect).

Since:
1.1.06
Constructor Detail

SOCRobotClient

public SOCRobotClient(java.lang.String h,
                      int p,
                      java.lang.String nn,
                      java.lang.String pw,
                      java.lang.String co)
Constructor for connecting to the specified host, on the specified port

Parameters:
h - host
p - port
nn - nickname for robot
pw - password for robot
co - cookie for robot connections to server

SOCRobotClient

public SOCRobotClient(java.lang.String s,
                      java.lang.String nn,
                      java.lang.String pw,
                      java.lang.String co)
Constructor for connecting to a local game (practice) on a local stringport.

Parameters:
s - the stringport that the server listens on
nn - nickname for robot
pw - password for robot
co - cookie for robot connections to server
Method Detail

init

public void init()
Initialize the robot player; connect to server, send first messages


disconnectReconnect

public void disconnectReconnect()
disconnect and then try to reconnect. If the reconnect fails, SOCDisplaylessPlayerClient.ex is set. Otherwise ex is null.


treat

public void treat(SOCMessage mes)
Treat the incoming messages. Messages of unknown type are ignored (mes will be null from SOCMessage.toMsg(String)).

Note: Currently, does not call SOCDisplaylessPlayerClient.treat(SOCMessage). New messages should be added in both places if both displayless and robot should handle them.

Overrides:
treat in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleSERVERPING

protected void handleSERVERPING(SOCServerPing mes)
handle the server ping message. Echo back to server, to ensure we're still connected. (ignored before version 1.1.08)

Parameters:
mes - the message

handleADMINPING

protected void handleADMINPING(SOCAdminPing mes)
handle the admin ping message

Parameters:
mes - the message

handleADMINRESET

protected void handleADMINRESET(SOCAdminReset mes)
handle the admin reset message

Parameters:
mes - the message

handleUPDATEROBOTPARAMS

protected void handleUPDATEROBOTPARAMS(SOCUpdateRobotParams mes)
handle the update robot params message

Parameters:
mes - the message

handleROBOTJOINGAMEREQUEST

protected void handleROBOTJOINGAMEREQUEST(SOCRobotJoinGameRequest mes)
handle the "join game request" message. Remember the game options, and record in seatRequests. Send a JOINGAME to server in response. Server will reply with JOINGAMEAUTH.

Board resets are handled similarly.

Parameters:
mes - the message
See Also:
handleRESETBOARDAUTH(SOCResetBoardAuth)

handleSTATUSMESSAGE

protected void handleSTATUSMESSAGE(SOCStatusMessage mes)
handle the "status message" message by printing it to System.err; messages with status value 0 are ignored (no problem is being reported) once the initial welcome message has been printed.

Overrides:
handleSTATUSMESSAGE in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleJOINGAMEAUTH

protected void handleJOINGAMEAUTH(SOCJoinGameAuth mes,
                                  boolean isPractice)
handle the "join game authorization" message

Overrides:
handleJOINGAMEAUTH in class SOCDisplaylessPlayerClient
Parameters:
mes - the message
isPractice - Is the server local for practice, or remote?

handleJOINGAME

protected void handleJOINGAME(SOCJoinGame mes)
handle the "join game" message

Overrides:
handleJOINGAME in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleGAMEMEMBERS

protected void handleGAMEMEMBERS(SOCGameMembers mes)
handle the "game members" message, which indicates the entire game state has now been sent. If we have a seatRequests for this game, sit down now.

Overrides:
handleGAMEMEMBERS in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handlePutBrainQ

protected void handlePutBrainQ(SOCMessageForGame mes)
handle any per-game message that just needs to go into its game's brainQs. This includes all messages that the SOCRobotBrain needs to react to.

Parameters:
mes - the message
Since:
2.0.00

handleGAMETEXTMSG

protected void handleGAMETEXTMSG(SOCGameTextMsg mes)
handle the "game text message" message

Overrides:
handleGAMETEXTMSG in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleGAMETEXTMSG_debug

private final void handleGAMETEXTMSG_debug(SOCGameTextMsg mes)
Handle debug text messages from players to the robot, which start with the robot's nickname + ":".

Since:
1.1.12

handleSITDOWN

protected void handleSITDOWN(SOCSitDown mes)
handle the "someone is sitting down" message

Overrides:
handleSITDOWN in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleDELETEGAME

protected void handleDELETEGAME(SOCDeleteGame mes)
handle the "delete game" message

Overrides:
handleDELETEGAME in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleGAMESTATE

protected void handleGAMESTATE(SOCGameState mes)
handle the "game state" message

Overrides:
handleGAMESTATE in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handlePUTPIECE

protected void handlePUTPIECE(SOCPutPiece mes)
handle the "put piece" message

Parameters:
mes - the message

handleCLEARTRADEMSG

protected void handleCLEARTRADEMSG(SOCClearTradeMsg mes)
handle the "clear trade" message

Overrides:
handleCLEARTRADEMSG in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleROBOTDISMISS

protected void handleROBOTDISMISS(SOCRobotDismiss mes)
handle the "dismiss robot" message

Parameters:
mes - the message

handleCHANGEFACE

protected void handleCHANGEFACE(SOCChangeFace mes)
handle the "change face" message

Overrides:
handleCHANGEFACE in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleLONGESTROAD

protected void handleLONGESTROAD(SOCLongestRoad mes)
handle the "longest road" message

Overrides:
handleLONGESTROAD in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleLARGESTARMY

protected void handleLARGESTARMY(SOCLargestArmy mes)
handle the "largest army" message

Overrides:
handleLARGESTARMY in class SOCDisplaylessPlayerClient
Parameters:
mes - the message

handleRESETBOARDAUTH

protected void handleRESETBOARDAUTH(SOCResetBoardAuth mes)
handle board reset (new game with same players, same game name). Destroy old Game object. Unlike SOCDisplaylessPlayerClient.handleRESETBOARDAUTH, don't call SOCGame.resetAsCopy().

Take robotbrain out of old game, don't yet put it in new game. Let server know we've done so, by sending LEAVEGAME via leaveGame(SOCGame, String, boolean). Server will soon send a ROBOTJOINGAMEREQUEST if we should join the new game.

Overrides:
handleRESETBOARDAUTH in class SOCDisplaylessPlayerClient
Parameters:
mes - the message
See Also:
SOCServer.resetBoardAndNotify(String, int), handleROBOTJOINGAMEREQUEST(SOCRobotJoinGameRequest)

sendRecordsText

protected void sendRecordsText(SOCGame ga,
                               java.util.Vector<java.lang.String> record)
Call sendText on each string element of record.

Parameters:
ga - Game to sendText to
record - Strings to send, or null

debugPrintBrainStatus

public void debugPrintBrainStatus(java.lang.String gameName,
                                  boolean sendTextToGame)
Print brain variables and status for this game, to System.err or as SOCGameTextMsg sent to the game's members, by calling SOCRobotBrain.debugPrintBrainStatus().

Parameters:
gameName - Game name; if no brain for that game, do nothing.
sendTextToGame - Send to game as SOCGameTextMsg if true, otherwise print to System.err.
Since:
1.1.13

leaveGame

public void leaveGame(SOCGame ga,
                      java.lang.String leaveReason,
                      boolean showDebugTrace)
the user leaves the given game

Parameters:
ga - the game
leaveReason - reason for leaving

addCleanKill

public void addCleanKill()
add one the the number of clean brain kills


destroy

public void destroy()
losing connection to server; leave all games, then try to reconnect

Overrides:
destroy in class SOCDisplaylessPlayerClient

main

public static void main(java.lang.String[] args)
for stand-alones