cz.cuni.pogamut.Client
Class Agent

java.lang.Object
  extended by cz.cuni.pogamut.Client.Agent
All Implemented Interfaces:
RcvMsgListener, Introspectable, java.lang.Runnable, java.util.EventListener
Direct Known Subclasses:
BaseBot, ScriptedAgent, TestBot, TestBot, TestBot2

public class Agent
extends java.lang.Object
implements java.lang.Runnable, RcvMsgListener, Introspectable

Class Agent wraps up the client, all aplications (bots) should be derived from this class and use methods of its compounds (body, memory, map).

Class has three important compounds:

it also contains loggers - for logging anything you want;)

there are two loggers:


=================
USER INFORMATIONS
=================
This class is meant as the model of the bot inside UT2004.

We recommand you to read the documentation of methods overriden by this class and then check out the Agent class.

========================================================================

Q: How it all works?
--------------------

The bot consists of two threads - Logic thread and Communication thread.

Communication thread is meant to communicate with Parser (which can be LOCAL - part of the agent or REMOTE - run as an independent application usualy at computer where UT2004 server is running).

Parser is parsing text messages from GameBots and translates them into java objects which are sent to communication thread. The communication thread is responsible for maintaining information about the world around the bot.
For that - see cz.cuni.Client.GameMap / History / HistoryBatch / Agent, etc.

Before logic thread is started you must be sure, that you've bind a parser to the bot (well NetBeans plugin does that for you :-). Check out methods cz.cuni.Client.Agent.connectToLocalParser() / connectToRemoteParser().

When logic thread is started it does a few things:

  1. calls this.prePrepareAgent() - method which is meant for you, you can use it to initialize variables before the bot connects to GameBot (via parser)
  2. starts the communication thread - if that fails, the thread is destroyed (and you get SEVERE error in log)
  3. calls this.postPrepareAgent() - method in which you can prepare more properties for your bot (note that by that time the GameBots sends you all the navpoint and items which are available somewhere in the map as well as information about the game (like type, mapname, etc.)
  4. goes to the while cycle, which is repeatedly calling doLogic() while running() returns true
  5. when running() returns false, the while cycle is left and this.shutdownAgent() is called - it's place where you can save / print anything you want

Now you should have good picture about which method you need to override and what to place into them - checkout documentation inside those methods for more informations.

Check out the method main() code for tips on how to run the bot from your code.

Q: That's fine but I don't know how to work with the class at all!
------------------------------------------------------------------

You're right - we haven't explained where sensors and efectors of the agent are. And we won't do this here. Just check out Agent.memory (AgentMemory) and Agent.body (AgentBody). Those are class where you find sensors (AgentMemory, stuff like seeAnyEnemy(), etc.) and effectors (AgentBody, stuff like jump(), runTo(), etc.)

Some additional functionality is provided by AgentAux class (eg. logging to file).

Q: how to affect agent initialization, how to spawn agent with different skill, bot level, and everything that is in INIT command in GameBots?
------------------------------------------------------------------- Override postPrepareAgent() method in your descendant of the Agent class and check out body.initializer field. It is instance of AgentInitializer and is used to construct INIT command after postPrepareAgent() finishes.


Field Summary
protected  ParserType bindedParserType
          Type of the binded parser.
protected  AgentBody body
          implements Commands, takes care about communication with parser
private static int botNum
          Serves for numbering the anonymous bots (creating object without supplied name)
private  java.lang.String defaultBotName
          Normally the name can be obtain from AgentMemory.agentName() but this work only after the first SLF message was got from GB.
private  boolean exceptionOccured
          Flag which indicates that exception occured during the logic or communication.
 boolean flagLogicTemporalyStopped
          Flag to allow temporal stop of execution of agent's logic
protected  GameBotConnection gameBotConnection
          When using local parser, here is stored connection to game bot.
protected  GameMap gameMap
          provides on-line response on getPath request using built-in A* provides as well response on get path to players etc. using Gamebots API
static int GARBAGE_COLLECTOR_FREQUENCY
          Every GARBAGE_COLLECTOR_FREQUENCY iterations of Agent.doLogic() the System.gc() is called to clean up things.
static int instancesAlive
          Debugging stuff... here we count how many instances of agents are present, using finalize().
protected  java.util.ArrayList<AgentIterationEndListener> iterationEndListeners
           
private  JavaReflectionProxy javaReflectionProxy
           
 java.util.logging.Logger log
          Logger for user
 double logicFrequency
          Frequency of evaluation of doLogic - used to count milliseconds for sleep in run() it is in Hertz, so for example 10 means evaluation every 100 milliseconds
protected  boolean logicFrequencyChanged
           
private  boolean logicIsPaused
          Whether the logic is paused, raised by pauseLogic() and dropped by resumeLogic(), read in run() Shouldn't be changed from anywhere else.
private  java.util.concurrent.CountDownLatch logicPauseLatch
          Used for pausing the logic of the Agent.
private  boolean logicShouldRun
          Flag which is checked every logic iteration.
private  java.util.concurrent.CountDownLatch logicStartLatch
          You may want to spawn N bots and wait for their initialization, if you do so, you may use setLogicStartLatch() method, which will store the provided CountDownLatch here and do it before you startAgent().
protected  AgentMemory memory
          implements Knowledge, WorldView and RecentMemory, provides all sensoric data
protected  double oldLogicFrequency
           
protected  java.util.logging.Logger parserLogger
          local parser log - not null only iff running local parser
protected  java.util.Collection pauseHolders
          Collection of objects that paused this agent.
protected  java.util.logging.Logger platformLog
          platform log
protected  java.util.Random random
          instance of random for randomized calculations - like choosing an angle to rotate
protected  java.util.logging.Logger rawGBLog
          When using LocalParser this contains raw data (not parsed)
private  java.lang.Thread threadLogic
          Thread of the logic which is created in startAgentXXX() methods.
private  Flag<java.lang.Boolean> threadLogicAlive
          Flag which tells us wether logic thread is alive.
 
Constructor Summary
Agent()
          agent constructor - initialize individually its compounds add listener for PlayerKilled message - necessary to call restartAgent properly
 
Method Summary
 boolean addIterationEndListener(AgentIterationEndListener listener)
          Register the listener for agent logic iterations.
 void bindLocalParser(java.net.URI gameBots)
          This method will CONNECT to game bot + initialize Parser / Mediator but won't start them, allowing IDE to register various flag listeners + get logs.
 void bindRemoteParser(java.net.URI parser)
          This will connect to remote parser and initialize mediator for the body but won't lunch it.
protected  void clearListeners()
          Called at the end of the Agent run to clear all listeners we could possibly have.
private  void closeAllStreamHandlers()
          Closes all stream handlers of loggers on this agent.
private  void closeStreamHandlersOfLog(java.util.logging.Logger log)
          Closes all stream handlers associated given Logger.
 void disconnect()
          Synonym for stopAgentSoft().
protected  void doLogic()
          There you are supposed to connect any external tool for decision making or you can write there some script, that will control the agent.
 void finalize()
           
 ParserType getBindedParserType()
           
 AgentBody getBody()
           
 CommunicationState getCommunicationState()
           
 boolean getFlagLogicTemporalyStopped()
           
 IntrospectableProxy getIntrospectableProxy()
          By default Agent uses automatic introspection based on Java Reflection API.
 java.util.logging.Logger getLogger()
          Get user log - devoted for logic.
 java.lang.Thread getLogicThread()
           
 GameMap getMap()
           
 Mediator getMediator()
           
 AgentMemory getMemory()
           
protected  long getMilisecToSleep(long passedMillisec)
           
 java.lang.String getName()
          For IDE.
 java.util.logging.Logger getPlatformLog()
          get platform log - for usage of platform
 java.util.logging.Logger getRawDataLog()
          Returns log with raw data from gamebots iff using local parser, otherwise it's null
protected  void initBody()
          initialize AgentBody - calls constructor
protected  void initGameMap()
          initialize GameMap - constructor
protected  void initLogging()
          init logging create log file, assign handler, set Level of logging etc.
protected  void initMemory()
          initialize memory, calls constructor
 boolean isRunning()
          Checks whether communication is OK and logic thread is active.
 boolean logicReady()
          check if the agent is ready to run logic
3 parts: Memory restart - needs to switch old memories with new ones - check AgentMemory for more info Has self - basicaly logic can't run without a clue about at least agent's position so SELF message is required Logic paused - necessary for example during usage of manual control - logic sending commands will be quite disturbing
 void pauseLogic(java.lang.Object holder)
          Pauses agent's logic, initialize the logisPauseLatch and raises logicIsPaused flag.
protected  void postPrepareAgent()
          prepare logic according to information from gathered from startCommunication like choosing plan/parameters according to game type note that you still can't send any messages to gamebots (like CONF etc.)
protected  void prePrepareAgent()
          prepares agent logic to run - like initializing neural networks etc.
 void receiveMessage(RcvMsgEvent e)
          place to take care about messages on which you register listener
 boolean removeIterationEndListener(AgentIterationEndListener listener)
          Remove the listener for agent logic iterations from registred ones.
 void resumeLogic(java.lang.Object holder)
          Resumes the paused logic.
 void run()
          We expect that connectTo{Local|Remote}Parser has been already called.
 void sendMessageToGB(java.lang.String str)
           
 void setFlagLogicTemporalyStopped(boolean value)
           
 void setLogicStartLatch(java.util.concurrent.CountDownLatch latch)
          You may want to spaw N bots and wait for their initialization, if you do so, you may use this method which will store the provided CountDownLatch here.
protected  void shutdownAgent()
          clean - up after the end of simulation of agent
 java.lang.Thread startAgent()
          This will lunch the agent with binded parser Once the agent is started it doesn't propagate any exceptions as it is running in another threads.
 java.lang.Thread startAgent(java.lang.String botName)
          This will lunch the agent with binded parser Once the agent is started it doesn't propagate any exceptions as it is running in another threads.
 void stopAgentSoft()
          Drops running flags of logic and communication thread.
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

instancesAlive

public static int instancesAlive
Debugging stuff... here we count how many instances of agents are present, using finalize(). We think that GC can't somehow collect the agents...


GARBAGE_COLLECTOR_FREQUENCY

public static int GARBAGE_COLLECTOR_FREQUENCY
Every GARBAGE_COLLECTOR_FREQUENCY iterations of Agent.doLogic() the System.gc() is called to clean up things. So how often the GC is called depends on doLogic(). Beware - if you program your doLogic() not to quit before agent ends, it will never be called by this mechanism (you're on your own).

Note: it's not good practice to have infinite loop in doLogic() because stopAgent() won't work.


logicFrequency

public double logicFrequency
Frequency of evaluation of doLogic - used to count milliseconds for sleep in run() it is in Hertz, so for example 10 means evaluation every 100 milliseconds


botNum

private static int botNum
Serves for numbering the anonymous bots (creating object without supplied name)


threadLogicAlive

private Flag<java.lang.Boolean> threadLogicAlive
Flag which tells us wether logic thread is alive.


exceptionOccured

private boolean exceptionOccured
Flag which indicates that exception occured during the logic or communication. Whenever the flag is raised the logic is stopped after it's iteration and the agent is stopped.


logicShouldRun

private boolean logicShouldRun
Flag which is checked every logic iteration. If dropped (false) the logic will exit and the communication will be closed.


threadLogic

private java.lang.Thread threadLogic
Thread of the logic which is created in startAgentXXX() methods.


defaultBotName

private java.lang.String defaultBotName
Normally the name can be obtain from AgentMemory.agentName() but this work only after the first SLF message was got from GB. IDE needs the name before that.


logicStartLatch

private java.util.concurrent.CountDownLatch logicStartLatch
You may want to spawn N bots and wait for their initialization, if you do so, you may use setLogicStartLatch() method, which will store the provided CountDownLatch here and do it before you startAgent().

Before starting the logic of the agent the instance will wait for this latch to get down.


logicPauseLatch

private java.util.concurrent.CountDownLatch logicPauseLatch
Used for pausing the logic of the Agent. Initialized in pauseLogic() and raised in resumeLogic(), shouldn't be changed anywhere else.


logicIsPaused

private boolean logicIsPaused
Whether the logic is paused, raised by pauseLogic() and dropped by resumeLogic(), read in run() Shouldn't be changed from anywhere else.


iterationEndListeners

protected java.util.ArrayList<AgentIterationEndListener> iterationEndListeners

body

protected AgentBody body
implements Commands, takes care about communication with parser


memory

protected AgentMemory memory
implements Knowledge, WorldView and RecentMemory, provides all sensoric data


gameMap

protected GameMap gameMap
provides on-line response on getPath request using built-in A* provides as well response on get path to players etc. using Gamebots API


log

public java.util.logging.Logger log
Logger for user


platformLog

protected java.util.logging.Logger platformLog
platform log


parserLogger

protected java.util.logging.Logger parserLogger
local parser log - not null only iff running local parser


random

protected java.util.Random random
instance of random for randomized calculations - like choosing an angle to rotate


bindedParserType

protected ParserType bindedParserType
Type of the binded parser.


gameBotConnection

protected GameBotConnection gameBotConnection
When using local parser, here is stored connection to game bot.


rawGBLog

protected java.util.logging.Logger rawGBLog
When using LocalParser this contains raw data (not parsed)


flagLogicTemporalyStopped

public boolean flagLogicTemporalyStopped
Flag to allow temporal stop of execution of agent's logic


logicFrequencyChanged

protected boolean logicFrequencyChanged

oldLogicFrequency

protected double oldLogicFrequency

javaReflectionProxy

private JavaReflectionProxy javaReflectionProxy

pauseHolders

protected java.util.Collection pauseHolders
Collection of objects that paused this agent.

Constructor Detail

Agent

public Agent()
agent constructor - initialize individually its compounds add listener for PlayerKilled message - necessary to call restartAgent properly

Method Detail

getFlagLogicTemporalyStopped

public boolean getFlagLogicTemporalyStopped()

setFlagLogicTemporalyStopped

public void setFlagLogicTemporalyStopped(boolean value)

initMemory

protected void initMemory()
initialize memory, calls constructor


initBody

protected void initBody()
initialize AgentBody - calls constructor


initGameMap

protected void initGameMap()
initialize GameMap - constructor


getBody

public AgentBody getBody()

getMemory

public AgentMemory getMemory()

getMap

public GameMap getMap()

getLogicThread

public java.lang.Thread getLogicThread()

getCommunicationState

public CommunicationState getCommunicationState()

getMediator

public Mediator getMediator()

getName

public java.lang.String getName()
For IDE.

Returns:
name of the bot

initLogging

protected void initLogging()
init logging create log file, assign handler, set Level of logging etc.


finalize

public void finalize()
Overrides:
finalize in class java.lang.Object

addIterationEndListener

public boolean addIterationEndListener(AgentIterationEndListener listener)
Register the listener for agent logic iterations.

Parameters:
listener -
Returns:
boolean success

removeIterationEndListener

public boolean removeIterationEndListener(AgentIterationEndListener listener)
Remove the listener for agent logic iterations from registred ones.

Parameters:
listener -
Returns:
boolean success

setLogicStartLatch

public void setLogicStartLatch(java.util.concurrent.CountDownLatch latch)
You may want to spaw N bots and wait for their initialization, if you do so, you may use this method which will store the provided CountDownLatch here. Do it before you startAgent() ! Before starting the logic of the agent the instance will wait for this latch to get down.

Parameters:
latch -

bindLocalParser

public final void bindLocalParser(java.net.URI gameBots)
                           throws java.io.IOException,
                                  ConnectException
This method will CONNECT to game bot + initialize Parser / Mediator but won't start them, allowing IDE to register various flag listeners + get logs.

May throws:

Parameters:
gameBots -
Throws:
java.io.IOException - Can't create GameBotConnection object, probably wrong address.
ConnectException - Can't connect to GameBots

bindRemoteParser

public final void bindRemoteParser(java.net.URI parser)
                            throws ConnectException,
                                   java.net.UnknownHostException
This will connect to remote parser and initialize mediator for the body but won't lunch it.

Throws:
ConnectException - Can't connect to RemoteParser.
java.net.UnknownHostException - Can't resolve the address.

getRawDataLog

public java.util.logging.Logger getRawDataLog()
Returns log with raw data from gamebots iff using local parser, otherwise it's null


startAgent

public java.lang.Thread startAgent(java.lang.String botName)
This will lunch the agent with binded parser

Once the agent is started it doesn't propagate any exceptions as it is running in another threads.

It allows you to specify a name for the bot inside UT.

It name of the bot will be equivalent to botName + N, where N is number.

Although this method works with sockets it can be used from contexts without such permisions. All sensitive actions are in privileged block. This method

Parameters:
botName -
Returns:
logic thread

startAgent

public java.lang.Thread startAgent()
This will lunch the agent with binded parser

Once the agent is started it doesn't propagate any exceptions as it is running in another threads.

It will use the default bot name 'PogamutBotN', where N is number.

Returns:
logic thread

getLogger

public java.util.logging.Logger getLogger()
Get user log - devoted for logic.

Returns:
log

getPlatformLog

public java.util.logging.Logger getPlatformLog()
get platform log - for usage of platform

Returns:
platformLog

logicReady

public boolean logicReady()
check if the agent is ready to run logic
3 parts:


getMilisecToSleep

protected long getMilisecToSleep(long passedMillisec)

run

public void run()
We expect that connectTo{Local|Remote}Parser has been already called.

Specified by:
run in interface java.lang.Runnable

closeAllStreamHandlers

private void closeAllStreamHandlers()
Closes all stream handlers of loggers on this agent.


closeStreamHandlersOfLog

private void closeStreamHandlersOfLog(java.util.logging.Logger log)
Closes all stream handlers associated given Logger.


prePrepareAgent

protected void prePrepareAgent()
                        throws PogamutException
prepares agent logic to run - like initializing neural networks etc. not for establishing communication!

Throws:
PogamutException

postPrepareAgent

protected void postPrepareAgent()
                         throws PogamutException
prepare logic according to information from gathered from startCommunication like choosing plan/parameters according to game type note that you still can't send any messages to gamebots (like CONF etc.)

Throws:
PogamutException

shutdownAgent

protected void shutdownAgent()
                      throws PogamutException
clean - up after the end of simulation of agent

Throws:
PogamutException

doLogic

protected void doLogic()
                throws PogamutException
There you are supposed to connect any external tool for decision making or you can write there some script, that will control the agent.

Note: it's not good practice to have infinite loop in doLogic() because stopAgentSoft() won't work. But it's OK if you rewrite the stopAgentSoft()

Throws:
PogamutException

isRunning

public boolean isRunning()
Checks whether communication is OK and logic thread is active.

DOESN'T check whether GameBots / RemoteParser is alive!

Returns:
true if communication is alive and logic thread active

disconnect

public void disconnect()
Synonym for stopAgentSoft(). Drops running flags of logic and communication thread.


stopAgentSoft

public void stopAgentSoft()
Drops running flags of logic and communication thread.


receiveMessage

public void receiveMessage(RcvMsgEvent e)
place to take care about messages on which you register listener

Specified by:
receiveMessage in interface RcvMsgListener

getIntrospectableProxy

public IntrospectableProxy getIntrospectableProxy()
By default Agent uses automatic introspection based on Java Reflection API. But you can provide your own "Logical view" of agents structure, just implement your own IntrospectableProxy and override this method.

Specified by:
getIntrospectableProxy in interface Introspectable
Returns:
introspectable representation of this object

pauseLogic

public void pauseLogic(java.lang.Object holder)
Pauses agent's logic, initialize the logisPauseLatch and raises logicIsPaused flag.

Parameters:
holder - object pausing this agent, the same object must be used in resumeLogic(Object)

resumeLogic

public void resumeLogic(java.lang.Object holder)
Resumes the paused logic. Drops the logicIsPaused flag and drop the latch.

Parameters:
holder - object that was used as parameter in pasuseLogic(Object)

getBindedParserType

public ParserType getBindedParserType()

sendMessageToGB

public void sendMessageToGB(java.lang.String str)
                     throws CantWriteException
Throws:
CantWriteException

clearListeners

protected void clearListeners()
Called at the end of the Agent run to clear all listeners we could possibly have.