Loading...
 

PogamutUT2004


Controlling Bot

I want to play the game and get info about the enemy visibility, location info, shooting info etc. from the bot I that play with. I thought possessing the bot that I created with pogamut and playing it in the game would give me all information I need, but I don't know how to take control over the bot.
Another way could be by joining the game and reading all the information about other bot's (the bot I'm playing with) from pogamut but I don't think you can read enemy visibility and shooting info for other bots in pogamut.
What I need is a comprehensive log of the player I control, currently I can only get whatever Player class can return (location, weapon name).
It might be easy or impossible, I just couldn't figure out any way
Thanks for any help
Hi!

There is an UT2004Observer class and UT2004ObserverFactory and UT2004ObserverRunner...

Whenever you start UT2004Observer by:

UT2004Observer obs = new UT2004ObserverRunner().startAgent();

You must somehow obtain an ID of the player you want to observe (one you get for instance from Self message of respective bot) and send this command:

getAct().act(new InitializeObserver().setId(idOfBotIWantToObserve);
obs.getAct().act(new ConfigurationObserver().setUpdate(0.2).setAll(true).setSelf(true).setAsync(true).setGame(false).setSee(false).setSpecial(false));

Then you may attach various listeners to obs.getWorldView() as usual.

I also recommand you to read documentation for ConfigurationObserver command.]

Does it help?

Cheers!
Jimmy
Thanks for the reply. I tried this code:

public void run(){
            IUT2004Observer obs = new UT2004ObserverRunner(new UT2004ObserverFactory(new UT2004ObserverModule()), enemy.getId().getStringId()).startAgent();
            obs.getAct().act(new InitializeObserver().setId(enemy.getId().getStringId()));
            obs.getAct().act(new ConfigurationObserver().setUpdate(0.2).setAll(true).setAsync(true).setGame(false).setSee(false).setSpecial(false));
            System.out.println("Agent NAME: "+obs.getName());
            System.out.println("There are "+obs.getWorldView().getAll(NavPoint.class).values().size()+" nav points");
            obs.getWorldView().addEventListener(BotDamaged.class, botDamaged);
}


and outside of the function created botDamaged function

IWorldEventListener botDamaged = new IWorldEventListener < BotDamaged > () {
        public void notify(BotDamaged event) {
            System.out.println("BOT DAMAGED");
        }
}


And my main function is:
public static void main(String args[]) throws PogamutException {
        new EmptyBot().run();
}



'enemy' variable is type of Player and is the second player that I play against.
I only get "There are 0 nav points" message and no bot damaged messages.

Is there something I'm missing or I need to redesign my code?
Thanks
Hi!

Your code looks perfectly fine, almost, you should not set "id of the enemy" as the name for your observer (it is probably not hurting anything but...).
IUT2004Observer obs = new UT2004ObserverRunner(new UT2004ObserverFactory(new UT2004ObserverModule()), "Observer" + enemy.getId().getStringId()).startAgent();

... should be more suitable.

Also [lease not that we have not used UT2004Observer too much yet so it is possible for you to stumble upon a few bugs.

I fear that this will be the case of "BotDamaged" event - I will check it out.

But regarding NavPoints, I might have a solution. The trick is, that Observer Connection (i.e., port 3002 of GameBots2004) is not exporting all navpoints and items automatically.
But there are commands which enforce GameBots2004 to do so.
http://diana.ms.mff.cuni.cz/pogamut_files/latest/doc/javadoc/cz/cuni/amis/pogamut/ut2004/communication/messages/gbcommands/GetAllInvetories.html\
http://diana.ms.mff.cuni.cz/pogamut_files/latest/doc/javadoc/cz/cuni/amis/pogamut/ut2004/communication/messages/gbcommands/GetAllNavPoints.html

The trick is, that this exports will take some time to process, so you will have to wait for that. That's where WorldEventFuture will come in hand.

So I would suggest you to:

WorldEventFuture latch = new WorldEventFuture(obs.getWorldView(), NavPointListEnd.class);
obs.getAct().act(new GetAllInventories());
obs.getAct().act(new GetAllNavPoints());
latch.get(); // will block, until all items / navpoints are exported


After that, all Items/Navpoints should be accessible inside obs.getWorldView() as usual for the bot.

Does it help?

Jimmy
Hi!

I've just tested the Observer and BotDamaged event works as expected.

Try to correctly name your observer and check whether it works.


Best,
Jimmy
Hi

I couldn't get it working, do you mind sending me the code you tested?
Thanks
Hi!

Actually, I've created a test case that is a bit complex, but I will try to cut it down to important parts... so, here is my observer code:

{CODE()}
package cz.cuni.amis.pogamut.ut2004.observer.impl;

import java.util.concurrent.TimeUnit;

import com.google.inject.Inject;

import cz.cuni.amis.pogamut.base.agent.module.IAgentLogic;
import cz.cuni.amis.pogamut.base.agent.module.LogicModule;
import cz.cuni.amis.pogamut.base.communication.command.IAct;
import cz.cuni.amis.pogamut.base.communication.messages.CommandMessage;
import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectListener;
import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
import cz.cuni.amis.pogamut.base.component.bus.event.BusAwareCountDownLatch;
import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
import cz.cuni.amis.pogamut.ut2004.agent.params.UT2004AgentParameters;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.ConfigurationObserver;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.InitializeObserver;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.BeginMessage;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.BotDamaged;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Item;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.PlayerScore;
import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Self;
import cz.cuni.amis.pogamut.ut2004.communication.worldview.UT2004WorldView;
import cz.cuni.amis.utils.exception.PogamutException;

public class TestUT2004BotObserver extends UT2004Observer {

LogicModule logicModule;

@Inject
public TestUT2004BotObserver(UT2004AgentParameters params,
IComponentBus bus, IAgentLogger agentLogger,
UT2004WorldView worldView, IAct act) {
super(params, bus, agentLogger, worldView, act);

// HOOK LISTENERS
getWorldView().addObjectListener(GameInfo.class, gameInfoListener);
getWorldView().addObjectListener(Self.class, selfListener);
getWorldView().addObjectListener(NavPoint.class, navPointListener);
getWorldView().addObjectListener(Item.class, itemListener);
getWorldView().addObjectListener(Player.class, playerListener);
getWorldView().addEventListener(BotDamaged.class, botDamagedListener);
getWorldView().addEventListener(BeginMessage.class, beginMessageListener);
getWorldView().addEventListener(EndMessage.class, endMessageListener);

}


private boolean gameInfoReceived = false;

private IWorldObjectListener gameInfoListener = new IWorldObjectListener() {

@Override
public void notify(IWorldObjectEvent event) {
gameInfoReceived = true;
}

};

protected boolean selfReceived = false;

private IWorldObjectListener selfListener = new IWorldObjectListener() {

@Override
public void notify(IWorldObjectEvent event) {
selfReceived = true;
}

};

protected boolean navPointReceived = false;

private IWorldObjectListener navPointListener = new IWorldObjectListener() {

@Override
public void notify(IWorldObjectEvent event) {
navPointReceived = true;
}

};

private boolean itemReceived = false;

private IWorldObjectListener itemListener = new IWorldObjectListener() {

@Override
public void notify(IWorldObjectEvent event) {
itemReceived = true;
}

};

protected boolean playerReceived = false;

private IWorldObjectListener playerListener = new IWorldObjectListener() {

@Override
public void notify(IWorldObjectEvent event) {
playerReceived = true;
}

};

protected boolean botDamagedReceived = false;;

private IWorldEventListener botDamagedListener = new IWorldEventListener() {

@Override
public void notify(BotDamaged event) {
botDamagedReceived = true;
}

};

protected boolean beginMessageReceived = false;;

private IWorldEventListener beginMessageListener = new IWorldEventListener() {

@Override
public void notify(BeginMessage event) {
beginMessageReceived = true;
}

};

protected boolean endMessageReceived = false;

private IWorldEventListener endMessageListener = new IWorldEventListener() {

@Override
public void notify(EndMessage event) {
endMessageReceived = true;
}

};

/**
* Sends custom command to the GameBots.
*
* Shortcut for getAct().act(command).
*
* @param command
*/
public void act(CommandMessage command) {
getAct().act(command);
}

// call after observer is starting
public void startObserving(String observedBotId) {
// initialize observer
act(new InitializeObserver().setId(getParams().getObservedBotId()));
act(new ConfigurationObserver().setUpdate(0.2).setAll(true).setAsync(true).setGame(true).setSee(true).setSpecial(true));
}

//// after some time, call

/**
* This method will check which messages we have received from observed bot...
*/
public boolean testMessages() {
StringBuffer sb = new StringBuffer();
sb.append("ERRORS ");

if (!gameInfoReceived) {
sb.append("| GAME INFO NOT RECEIVED");
}
if (!selfReceived) {
sb.append("| SELF NOT RECEIVED");
}
if (!navPointReceived) {
sb.append("| NAVPOINT NOT RECEIVED");
}
if (!itemReceived) {
sb.append("| ITEMS NOT RECEIVED");
}
if (!playerReceived) {
sb.append("| PLAYER NOT RECEIVED");
}
if (!botDamagedReceived) {
sb.append("| BOT DAMAGED NOT RECEIVED");
}
if (!beginMessageReceived) {
sb.append("| BEGIN MESSAGE NOT RECEIVED");
}
if (!endMessageReceived) {
sb.append("| END MESSAGE NOT RECEIVED");
}

if (!sb.toString().equals("ERRORS: ")) {
user.severe("!!!!! " + sb.toString());
throw new PogamutException(sb.toString(), this);
}

return true;
}

}


{CODE


Well it's not the code I'm using (I've rewritten it), but fundamental parts are there.

As you can see - nothing special.

Are you sure, that you're hurting the bot? (Probably silly question...)

Cheers,
Jimmy
Hi

I see how you test the Observer class but I don't know how to use the test class and send all the inputs like AgentParameter, etc. to the constructor.
Also do you need to start a bot in order to attach Observer to players or can you call the test class in main function.
Thanks
Hi,

I've created the test observer as an extension of UT2004Observer, that means, you can't use UT2004ObserverRunner for that. Instead, you must use UT2004ObserverFactory for that purpose.

UT2004ObserverFactory requires UT2004ObserverModule (If you want to know more, read something about goog Guice IoC that we're using). Thus you have to create an extension of UT2004ObserverModule where you specify that it is this new observer you want to construct.

Module:
public class TestUT2004BotObserverModule extends UT2004ObserverModule {
	
	@Override
	protected void configureModules() {
		super.configureModules();
		addModule(new AbstractModule() {

			@Override
			public void configure() {
				bind(IUT2004Observer.class).to(TestUT2004BotObserver.class);				
			}
			
		});
	}

}


Now having such a module, you may instantiate the factory:

UT2004ObserverFactory observerFactory = new UT2004ObserverFactory(new TestUT2004BotObserverModule());


When you look at the methods the factory is offering, you will find out you have to provide some parameters that the observer is going to be started with. Note that this is a place, where you may provide your custom class with your own parameters which will be accessible then inside the observer via getParams() method (this is a way how to parametrize your agent).

Anyway, I will just create a common params for now and leave experiments to you.

UT2004AgentParams observerParams = 
					new UT2004AgentParams()
						.setWorldAddress("localhost", 3002)
                                                .setAgentId(new AgentId("observer");


Good, this params is telling that you want to name your observer as "observer" and you want it to connect to localhost:3002.
Now, we may instantiate our observer.

TestUT2004BotObserver observer = (TestUT2004BotObserver)observerFactory.newAgent(observerParams);


Having the observer constructed, you may start it. Note that you have to take care of cleaning up stuff for yourself when not using UT2004xxxRunner, thus always use try/finally.

observer.start();
try {
      observer.startObserving(someBotId);
       // do your work here
      observer.stop();
} finally {
       if (observer.inState(IAgentStateUp.class)) observer.kill();

}


Cheers!
Jimmy
Hi

First of all thank you for all the help and sorry for making this topic too long but I really need to understand the concept and get this working.
Here's what I've done so far. I have created the 3 classes: "TestUT2004BotObserver" , "TestUT2004BotObserverModule" that you gave and another class to test the program.
Here's the code for testing the program:

import cz.cuni.amis.pogamut.base.agent.impl.AgentId;
import cz.cuni.amis.pogamut.base.agent.state.level1.IAgentStateUp;
import cz.cuni.amis.pogamut.base.communication.connection.impl.socket.ISocketConnectionAddress;
import cz.cuni.amis.pogamut.ut2004.agent.params.UT2004AgentParameters;
import cz.cuni.amis.pogamut.ut2004.factory.guice.remoteagent.UT2004ObserverFactory;

public class Test {

    public Test(){
        //PLAYER NAME: Cleopatra id: DM-TrainingDay.GBxBot3
        //PLAYER NAME: Bulent id: DM-TrainingDay.ObservedPlayer2
        UT2004ObserverFactory observerFactory = new UT2004ObserverFactory(new TestUT2004BotObserverModule());
        UT2004AgentParameters observerParameters =
                            new UT2004AgentParameters()
                                          .setAgentId(new AgentId("observer"))
                                          .setWorldAddress(
                                                    new ISocketConnectionAddress() {
                                                        public String getHost() {
                                                            return "localhost";
                                                        }

                                                        public int getPort() {
                                                            return 3002;
                                                        }
                                                    });

        TestUT2004BotObserver observer = (TestUT2004BotObserver) observerFactory.newAgent(observerParameters);
        observer.start();
        try{
            observer.startObserving("DM-TrainingDay.ObservedPlayer2");
            System.out.println("Observer Started");
            // 10 sec delay
            try{Thread.sleep(10000);} catch(Exception ex){}
            
            observer.testMessages();

            observer.stop();
            System.out.println("Observer Stopped");
        } catch(Exception ex) {
            ex.printStackTrace();
        } finally {
            if(observer.inState(IAgentStateUp.class)){
                observer.kill();
                System.out.println("Observer Killed bc it was in Up State");
            }
        }
    }


    public static void main(String[] args){
        new Test();
    }
}


The test class is nothing but the code you provided. The only thing I try to do is to get the user data from players.
When I run this code I get all the error messages that I can get.

!!!!! ERRORS | GAME INFO NOT RECEIVED | SELF NOT RECEIVED | NAVPOINT NOT RECEIVED | ITEMS NOT RECEIVED | PLAYER NOT RECEIVED | BOT DAMAGED NOT RECEIVED | BEGIN MESSAGE NOT RECEIVED | END MESSAGE NOT RECEIVED


The code looks like working but the observer doesn't seem like bound with the game environment.
Is there anything I need to add or do to get observer working correctly?

Thanks
One thing I noticed in the server messages is that the server gains the connection but loses the Observing connection right away.
Here's the server message I get when I run the code:

"We are in gained child 2, it is DM-TrainingDay.ObservingConnection
Observing connection established.
Lost Child DM-TrainingDay.ObservingConnection"
Hi

I figured out the problem. The object listeners had to be hooked after initializing the observer to the agent. I took the object listeners out of the Observer constructor. Then after initialization the observer, I was able to listen the agent updates.
I also solved another issue I was having before that I needed location info updates more than 4 times in a second. By using separate observer the updateTime was able set the message frequency as many times as I want.
I appreciate the help, Thanks
 

News

News RSS RSS feed for News link



Pogamut

Quarterly RSS RSS feed for quarterly reports

Acknowledgement

This work is supported by GA UK 1053/2007/A-INF/MFF (2007-8), GA UK 351/2006/A-INF/MFF (2006-8), the Ministry of Education of the Czech Republic (grant MSM0021620838) (2008-9), by the Program "Information Society" under project 1ET100300517 (2006-9), and the project Integration of IT Tools into Education of Humanities (2006-8) and by the project CZ.2.17/3.1.00/31162, which are financed by the European Social Fund, the state budget of the Czech Republic, and by the budget of Municipal House Prague.