Robo war competition

Pages: 1234
So skimming this other thread gave me a related idea:
http://www.cplusplus.com/forum/lounge/118595/

I didn't want to hijack that thread since this seems like it'd be a different idea.

It's AI related, but also would be a fun project like Chess++ for a team to develop something fun.

When I was a kid, one of the things that got me into programming was this game "RoboWar" I had for my old mac. It basically involved a square area where you'd put in several robots. Each robot had to be programmed in "Robotalk" which was this simplistic stack-based language:

AIM 5 + AIM' STORE to rotate the turret 5 degrees.

Robots would attempt to locate and fire bullets/missiles at other robots. Last surviving robot would win.

I'm sure there's probably a bunch of similar programs out now. We could probably find/use an existing one... but I think that would take a lot of the fun out of this.


Here's what I'm envisioning:
===========================================

Robots get a certain amount of "money" to buy their parts. Better parts cost more money. But in the end, all robots cannot spend more than the amount (so if you want to invest in better weaponry, you'll suffer in other areas. It's a tradeoff).

Some ideas for parts would be:
- Wheels/Motor. Better parts would let you move/brake faster
- Cameras. Better parts would let you see further and/or wider angle.
- Guns. Better parts shoot faster bullets
- Alternative weaponry (lasers? mines?)
- Armor
- Chaff/Fog - something to hide you from other robot's cameras. (would have to be limited use)


Anything that is directional (cameras/weapons) would be turret based, so you'd have to orient it with the robot. Rotating/orientating would take time (doesn't move instantaneously) so maybe higher quality parts could rotate faster?

You could also have multiple guns/cameras that rotate independently.

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

The robots themselves would be "plugins". I'm thinking dlls (although this wouldn't be portable for those chumps on Linux... maybe they could run in Wine?). The interface would be a small set of functions:

- 1 to do the "shopping" for the robot. It would call back public functions to "purchase" items (obtaining a pointer to a Camera object, or the like)

- 1 called every "tick" in the battle to do a step of AI logic.


That'd be it. Most of the work would be done through the items the robots purchased. So if the logic wanted to rotate the gun to a certain angle, then fire a bullet, it could do something like this in its logic:

1
2
3
maingun->rotateToAngle(desiredAngle);
if(maingun->getAngle() == desiredAngle)
    maingun->fire();


Where 'maingun' was the object obtained during the shopping step. As this illustrates, rotation is not immediate, and the robot has to poll the current angle of the gun to know if it's pointing where it wants it to point or not.


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

This makes it impossible to have "illegal moves" like you'd have in a chess or something game, because the only thing the AI here has control over is the parts its using. And if you try to do something illegal with the parts (like fire 2 bullets in the same logic update), the part can simply ignore it and/or return some kind of error.


To prevent robots from "deadlocking", we could run the logic in a separate thread and have it 'timeout' after a certain length of time. If the robot times out, the driving code could just kill the thread and then that robot would just be dead.


The modularity would allow anyone to submit robots by sending a dll (though that would be a security risk, so maybe we don't want to do that?). And in the main program we could match up whatever robots we wanted and pit them in battle! mwahahaha.

If we want to get really fancy we can add obstacles and stuff. or maybe have different "classes" of robots. So high class robots can spend more money, but get matched up against other higher class robots.


I think this would be awesome and would persist among members of this forum for a while. The problem is it's a reasonably large project for a forum where people can only contribute in their spare time... so I don't know if we'll be able to pull it off.


What do you guys think?
I think this is a great idea, but think a cross platform method should be used for loading bots (not that I have any suggestions off hand).
I also think something of this size would probably need a project leader, would/could that be you?
I think this is a great idea, but think a cross platform method should be used for loading bots


Well I wanted to avoid one person having to compile every submitted robot... but for security reasons I guess we'd have to do that anyway.

I also think something of this size would probably need a project leader, would/could that be you?


I think I could help with design but I don't think I'd be able to contribute much code. Though if someone else gets a github or something set up I could probably do some work with it.

But before any of that gets started I'd like to hash out more ideas. Like get some parts ideas and discussion going.

I could hash out more details for the robot parts if there's sufficient interest... I just don't want to talk to myself =P
I'm in.
You're pretty spot on when you mention only being able to contribute in spare time. My course load has been absolutely killer this past semester, and it's going to be exactly the same (if not worse) come January. I'm relatively free for the next two weeks though! small victory..

It would definitely need a project leader, as naraku mentioned. I'm in no place to step up to that because I don't have the time to commit to that, but if this starts rolling, I'll gladly contribute.

EDIT After Disch's post:
Disch wrote:
I just don't want to talk to myself =P
That's my least capable area; coming up with designs and overall ideas. I much prefer doing the implementing. Lets keep this discussion going and I'll pitch in any ideas that come.
Last edited on
This and the Quiridor idea, what we need is a framework framework. :)
Last edited on
Don't want to taint your idea or anything, but this reminded me of the robot battles TV series :)

This sounds like an excellent idea. I'd be interested in participating in some way. I'll be sure to monitor this thread.
How do people feel about wxWidgets?
Lowest0ne wrote:
what we need is a framework framework
Framework for frameworks, i like it, lol.

Lowest0ne wrote:
How do people feel about wxWidgets?
Prefer Qt, probably only because I've dealt with it more though. wxWidgets is (afaik) the only other decent alternative to Qt. Every other GUI framework i've run into sucks royally.
closed account (3qX21hU5)
I would be in also.

Not sure what I would be able to contribute to but will definitely take part in building my own robot.

If you guys don't decide to do it in Qt or wxWidgets I would be willing to whip up a quick 2D game client for this in SFML. Wouldn't be nothing fancy but if you are interested let me know.

Though would need to know more information on it like would it be tile based movement? Any walls or other objects other then the robots? Stuff like that.
Last edited on
I think we'd need something like SFML. I don't think Qt or wx would be suitable for this.

I would be willing to whip up a quick 2D game client for this in SFML. Wouldn't be nothing fancy but if you are interested let me know.


That'd be awesome.

Though would need to know more information on it like would it be tile based movement?


Nah, movement would not be tile based.

I would like for there to be walls (could be as simple as straight lines) so that robots could use them for cover and the like. Plus we'd need them for the boundary of the map.

The real tricky part is the camera interface, because I want it to report useful information, but not absolute coordinates because that'd be a little silly.

Since there appears to be interest, I'll try to hammer down some finer details today.
And we'll also need weight.
Here's some more details notes. This is basically the "parts" that will be available to the robots. The AI code that contest participants would write would be interfacing with these classes. The "game engine" would just be implementing them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// 'Vector2' is just a 2 dimentional vector.  Probably this:

typedef sf::Vector2<double> Vector2;



// Not all robots will have Gps... I figure this is an "extra" you can spend money on.
class Gps
{
    Vector2 getPosition();
};


class Turret
{
    bool    isMoving();                     // true if the turret is spinning towards the target.  False if at target
    double  getCurrentAngle();              // returns current ACTUAL angle
    double  getTargetAngle();               // returns target angle
    void    setTargetAngle(double angle);   // sets target angle (turret will being spinning towards target)
    
    double  getRotationSpeed();             // gets the speed of rotation (units TBD... "radians per tick" maybe?)
    
    // angles in radians or degrees?
    // standard orientation:
    //      0 or   0 deg = east
    //   pi/2 or  90 deg = north
    //     pi or 180 deg = west
    // 3*pi/2 or 270 deg = south
};

// Unlike all other parts... a robot can only have one set of Wheels.  Whereas you can have as many of the other
//  parts as you want.

class Wheels : public Turret
{
    void    setTargetSpeed(double speed);   // speed in "pixels per tick" units.
    double  getCurrentSpeed();              // current speed (may not be target speed if accellerating or braking)
    double  getTargetSpeed();
    double  getMaxSpeed();
    
    double  getAccellerationSpeed();        // rate at which the bot accellerates
    double  getBrakeSpeed();                // rate at which the bot slows
};


class Gun : public Turret
{
    bool    fire();                         // might return false if unable to fire.  Maybe give some more detailed error reporting?
                                            // might be unable to fire if out of ammo.. or if you're firing too soon after just having fired.
                                            
    double  getFireRate();                  // returns rate of fire in "ticks / shot"
    int     getMaxAmmo();
    int     getRemainingAmmo();
};

/*
    Stuff for the camera - maybe make this into proper structs rather than
    a typedef of pair.  In case we want to add future properties to them
 */
typedef std::pair< Vector2, Vector2 >   VisibleWall;    // 2 endpoints of a wall
typedef std::pair< Vector2, int >       VisibleRobot;   // position & ID number of the robot.
                                                        //  if we want to have teams, negative IDs could be friendly robots


class Camera : public Turret
{
    std::vector<VisibleWall>    getWalls(Gps* gps);     // returns a list of all visible walls.  That is.. VISIBLE PORTIONS of walls
                    // so only the parts that are within the camera's field of vision.  If a Gps object is supplied, the returned
                    // positions are absolute.  Otherwise, they're relative to the robot's current position.
                    
    std::vector<VisibleRobot>   getRobots(Gps* gps);    // same idea, but gives a list of all visible robots.
    
    // maybe instead of individual functions, all of this could be put in a CameraData struct and returned in a clump?
    
    
    double getViewingAngle();               // get the "field of vision".  More expensive cameras would have wider angles.
    double getViewingDistance();            // get the maximum distance this camera can see.
};




// Not all robots will have communicators (spend $$$).  This would be to communicate data between
//  robots on the same team.  Like if you want to have 2 robots gang up on a guy.
//
// Each team would have their own communications and only robots on the same team would
//  be able to send/receive on it (assume they're encrypted or something)
//
// Each robot (or really, each robot's communicator) has a queue.  When you post a message, it gets
//  added to all your friendly robots' queues.  When you read a message, it pulls it from your queue.

class Communicator
{
    // strings seem like the easiest approach for messages here...
    
    struct packet
    {
        int         id;         // ID of the robot sending the message
        std::string message;    // the message
    };
    
    bool        messagesPending();              // true is messages (from other robots) are pending in the queue
    packet      readMessage();                  // get the next message in the queue (and remove it)
    void        postMessage(std::string msg);   // send a message to friendly robots
};



/*
Other ideas for parts:

- Throw/drop proximity mines which explode when another robot gets close.
- Throw/drop remote bombs which detonate when triggered.
- Jamming device which blocks communications to robots within a certain radius (robots unable to post/read messages)
        Would have to have limited "fuel" or something
- Chaff/cloak which makes the robot not show up on other robots' cameras (would need to have limited "fuel" - but even that might be
        too good... dunno)
- Armor
- Some kind of melee weapon that hurts robots if you bump into them (like a sawblade that is constantly spinning around the robot)
- Some kind of debilitating gun that when you hit a target with it, it jams a robot's circuitry
        and causes the AI logic to not be called for a few ticks.
- Other suggestions???
*/



I would greatly appreciate feedback/opinions/suggestions.
Zereo wrote:
If you guys don't decide to do it in Qt or wxWidgets I would be willing to whip up a quick 2D game client for this in SFML.
It's super simple to embed an SFML RenderWindow in either a Qt or wxWidgets application if a high level gui is required.

Disch wrote:
Nah, movement would not be tile based.
About movement. This could end up pretty interesting. We would need to provide the robot an interface for movement, which could be as simple as "tick forward", and "tick backwards". The exact distance that the robot moves would be determined by some base stats that the framework knows (time elapsed since last tick, base speed, etc) and the equipment that the robot has (there could be equipment for enhanced movement speed or something).
The robot would also be able to control its orientation in the same way, "tick clockwise", "tick counterclockwise" in the same way that the robot moves. That could be turned into a "rotateToAngle" function that you mentioned in the original post or something.
That aside, now to the interesting part. The robot would be fed information from a "camera" object that's oriented in the same direction as the robots front is oriented (robot turns, camera turns, possibly an add in for a separate camera that can rotate freely). The robot could poll the camera, and the camera would then give the robot information about objects in its frame of view. I.e, a camera can see x distance away with a spread of some angle theta. So the camera would be able to tell the robot what it sees, and the relative position of the sighted object to the robot.
This would make developing AI particularly cool, because the robot wouldn't be able to know anything else about its orientation in space or the objects/walls around it except for what the camera tells it.
So it would be up to the AI to keep up with where the robot has moved, build a map of the environment from where it spawned, and traverse the world accordingly.
Also, if, say, the camera spots an enemy robot, we could have the camera give the robot an object that contains information about the robot it spots. How is the enemy robots camera oriented? Can the enemy robot see you? What type of weapons does the enemy robot have? Are they pointed at you?
Depending on the distance the enemy robot is from the robot and the type of camera the robot is equipped with, there could be some kind of relative error in the camera's observations. If the enemy robot is at the farthest distance the camera can spot, maybe it's misses information about the other robot or reports something incorrectly.
All of this information could be used in decision making, so you have to base what you want to do next off of a massive amount of information, making AI construction particularly challenging.
Last edited on
closed account (3qX21hU5)
EDIT: Bah got ninja'd by two people ;p

Lumpkin wrote:
And we'll also need weight.


Not sure what you mean by that. Could you explain?


Disch wrote:
That'd be awesome.


Ok sounds good. I'll try and get started on it tonight and if not at least by this weekend. I'll just stick to getting the basic framework up and running and then concentrate mainly on the map until more finer details can be worked out.

As for the map a basic tile map would probably work best in my opinion. If no one else objects I think it would probably be easiest to use .tmx maps (Tiled Map Editor) for now and then if something else is needed a unique editor could be built for it later.

Also I will be upfront and say I most likely won't have the experience to do anything with the "plugins" (Implementing a way to be able to have players submit their own AI code and the client runs it) so I will leave that to other more experienced members on that subject.
Last edited on
As for the map a basic tile map would probably work best in my opinion. If no one else objects I think it would probably be easiest to use .tmx maps (Tiled Map Editor) for now and then if something else is needed a unique editor could be built for it later.


I'm OK with using a tile based editor for creating the levels, but I think it'll be infinitely easier to store the maps themselves as a series of line segments within the program.

That way movement is simple line/circle collision detection and you don't have to deal with tile-based crap (ever since I switched to and got used to vector based collision detection... it's just so much easier than tile based).

I kind of had that in mind when I outlined the camera details above. Walls are just a line segment.

It's possible to take a tile-based map and build a series of line segments from it. I've done it before.


Also I will be upfront and say I most likely won't have the experience to do anything with the "plugins" (Implementing a way to be able to have players submit their own AI code and the client runs it) so I will leave that to other more experienced members on that subject.


Heh, that's probably the easiest part. ;)

Submissions will have a class that derives from something like this:

1
2
3
4
5
6
7
class RobotAI
{
public:
    virtual ~RobotAI() { }
    virtual void shopping(Shop& shop) = 0;
    virtual void update() = 0;
};


'shopping' would be called once... which the AI would call several functions in the Shop class to purchase and obtain pointers to the above listed Parts classes (ie: get cameras and stuff).

Then in the battle... once every 'tick', the 'update' function is called. Robots would merely interface with the parts they obtained during the shopping step to have their robot do stuff.
After going through Disch's post:

// 'Vector2' is just a 2 dimentional vector. Probably this:

By "vector" here, I mean the mathematical vector, not the C++ container, which is what I assume you meant. I implemented something like this quite a while back. Its been sitting in a gist for a while:
https://gist.github.com/Thumperrr/2922a7dfed9cd1103ce9

I never implemented the equivalence operator because I got stuck on comparing doubles. It's really awkward to see if two floating point variables are equivalent.

Going through old gists now, found an an implementation that was intended to encapsulate an angle.
I think my intention here was to make disambiguate the definition of an angle so that degree and radians didn't need to be worried about and you could easily interact with the same container using either radian or degree values.
Here I tried to deal with double equivalence. I don't know how effective those helper functions are, though, as I wrote these a really long time ago. And there are multiple of them because some work better in certain situations (AlmostEqualRelativelyOrAbsolute breaks down for numbers close to 0).
I pulled a lot of that from an article I read somewhere on the internet about floating point comparison that I'll try to find again.

But maybe this will come in handy to someone here as well
https://gist.github.com/Thumperrr/2922a7dfed9cd1103ce9
Last edited on
closed account (3qX21hU5)
Disch wrote:
Heh, that's probably the easiest part. ;)

Submissions will have a class that derives from something like this:
...


Ahh so each person just submits their code to someone in the project who compiles it in then? That is quite easy ;p. For some reason I was thinking of a much more complicated way about it ;p.


Disch wrote:
I'm OK with using a tile based editor for creating the levels, but I think it'll be infinitely easier to store the maps themselves as a series of line segments within the program.

That way movement is simple line/circle collision detection and you don't have to deal with tile-based crap (ever since I switched to and got used to vector based collision detection... it's just so much easier than tile based).

I kind of had that in mind when I outlined the camera details above. Walls are just a line segment.

It's possible to take a tile-based map and build a series of line segments from it. I've done it before.


The loader I would be using for the .tmx maps already has collision detection implemented in it for map objects. It is actually quite simple and pretty fast (It's using quad tree collision) from my experiences with other games I have used it in.

Here is a quick explanation of how it works if you are interested http://trederia.blogspot.com/2013/10/collision-detection-with-tiled-maps.html and http://trederia.blogspot.com/2013/06/optimising-collision-testing.html. But it's up to you how you want to do it either way is fine by me.

Thumper wrote:
By "vector" here, I mean the mathematical vector, not the C++ container, which is what I assume you meant. I implemented something like this quite a while back. Its been sitting in a gist for a while:
https://gist.github.com/Thumperrr/2922a7dfed9cd1103ce9


SFML provides built in vector's in the library so probably best just to use them in my opinion.
Last edited on
I didn't see your reply until now, Thumper.

I think you're more or less describing the same thing I have in mind. The only differences I can see is this:

- The robots cameras/gun etc would not rotate along with the robot's front. In fact I don't envision the robot even having a front... it's just a circle with a bunch of independently operating turrets.

I suppose you could have the "wheels" turret be the definitive orientation with the robot, and the cameras/guns/etc would rotate to match it... but that would just needlessly complicate the AI, IMO.


Also, if, say, the camera spots an enemy robot, we could have the camera give the robot an object that contains information about the robot it spots. How is the enemy robots camera oriented? Can the enemy robot see you? What type of weapons does the enemy robot have? Are they pointed at you?


This is a very cool idea that I hadn't even considered. That'd be relatively easy to work into the "VisibleRobot" API for the camera that exists now (we'd just have to make that a struct instead of a pair typedef).
Zereo wrote:
Ahh so each person just submits their code to someone in the project who compiles it in then? That is quite easy ;p. For some reason I was thinking of a much more complicated way about it ;p.


I thought about having DLLs that are loaded at runtime... but that opens up security risks and portability issues that might be difficult to tackle.

The loader I would be using for the .tmx maps already has collision detection implemented in it for map objects.


I'm OK with whatever works. But it's not just collision detection we have to consider, we also need to report wall positions back to the camera somehow. If the walls are line segments, this is accomplished with some relatively straightforward math. If the walls are tiles, then we might have to reconsider how the camera reports their positions.


EDIT: I keep missing Thumper's posts

Thumper wrote:
By "vector" here, I mean the mathematical vector, not the C++ container, which is what I assume you meant.


Yes... I meant a mathematical vector.

SFML already has this implemented. It could be a typedef just as I illustrated in my pseudo-code above.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//...
DWORD MyID = GetCurrentThreadId();
DWORD ProcID = GetCurrentProcessId();

THREADENTRY32 ThreadEntry;
   ThreadEntry.dwSize = sizeof(THREADENTRY32);

HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 

Thread32First(SnapShot, &ThreadEntry);

do
{
    if(ThreadEntry.th32OwnerProcessID == ProcID)
   {
        if(ThreadEntry.th32ThreadID != MyID)
       {
            SuspendThread(OpenThread(THREAD_ALL_ACCESS, FALSE, ThreadEntry.th32OwnerProcessID));
       }
   }
}while(Thread32Next(SnapShot, &ThreadEntry);
//... 


I win.

On a more serious note, I really like this idea! I agree that sending precompiled DLL files back and forth may be a security risk but if we are just passing around source code (which we should do anyway to prevent problems between versions of windows and certain wacky things) there shouldn't be an issue.

As for more robot parts (without any forethought to complexity) how about:

- Processors with attributes like cache latency? Have each 'turn' divided into X number of 'ticks' and having lower latency processor allows your commands to be processed at an earlier 'tick'.

- Something to track multiple targets in case we want to do a Battle Royal.

- Some kind of radar so that you can track targets that you do not have LoS to.

- Power Plants so that we can fine tune designs and prevent bots from grabbing all of the best parts and mashing them together.
Pages: 1234