New AI Contest:Planets

Online C++ programming contests.

Moderators: Darobat, RecursiveS, Dante Shamest, Bugdude, Wizard, raimo

New AI Contest:Planets

Postby Darryl » Sat Dec 03, 2005 12:06 am

Welcome to Darryl’s newest contest: AI Planets

Background:
This contest is based on one of the first shareware PC games I downloaded off the internet called Stellar Empires. A copy of it can be found here: http://www.winsite.com/bin/Info?500000032319 I’d suggest trying the game out to get a feel for what this contest is about. I have tried to replicate the play as close as possible, though there are a few differences.

Objective:
The object is to eliminate the other players.

Rules:
If you downloaded game above there is a help file you can refer to as well as below.

The game is turn based. On each turn the following events happen:
1. New ships are created on occupied planets that contain sufficient resources
2. Moves are gathered from the players
3. Ships are moved into an “incoming” queue on each planet based on moves from 2.
4. The queues are evaluated FIFO for each planet.
5. New resources are added to each occupied planet.

Ship Production:
Each planet has resource points, based on these points ships can be produce, for this game I have set it at 10pts/ship. Owned planets increase resource points 1 point each round. An additional point is added for each route where the connecting planet is owned by the same player. All planets start with a -5 resource and therefore do not start producing right away. The home-planet or your starting planet starts with 30 resource points and produces 2 points per round as long as you own it. If conquered it is reduced to 1 point per round even if recaptured by original owner. The resources are added at the end of each turn after the battles/moves have been resolved.

Moves:
A list of moves is gathered from all the players. A move consist of a command to moves x number of ships from one planet to a connected planet. You may move all but 1 ship from any planet, you must leave one. You may only move ships between planets with established routes. If the planet is controlled by another player then a battle will take place for control of the planet. The framework polls each player for a single move and adds them to a list of moves; it continues looping through the players until all players have indicated that they have no more moves for the current round. Once the moves have been collected, they are verified and put into a queue for each planet. The queue is resolved in a FIFO order. Invalid moves are ignored. If you have more than one planet sending ships to the same planet, the ships are combined in the queue and will retain the priority of the ships earliest in the queue. Example, if player1 send 10 ships to planet5, and player2 sends 15 ships to planet 5. The first 10 will colonize the planet; the second 15 will attack the first 10. Supposing that player3 had also sent 15 ships to planet5; His ships will attack the winner of the first battle, whose numbers be weakened from the battle.

Battles:
Battles are simultaneous for both sides of the attack, for instance if 50 ships attack 20 ships, 50 attacks will take place on the 20 ships AND 20 attacks will take place on the 50 ships. The 50 can lose at most 20, but the 20 could lose all 20 in a single attack. Attacks are done using a 10 sided dice, if 7 or better is achieved, then the attack is considered successful. Exceptions: There is one exception in the event that both forces are evenly matched, to eliminate the possibility of both forces being annihilated, the defending attacks are evaluated first, and if all attacks are successful then the defenders will lose 1 attack in evaluating the attackers’ damage. Ex. if 3 attacks 3 and the 3 defenders are destroyed, then only 2 attacks will be evaluated on the attackers to ensure a ship will be left. During a battle, after the attacks have been evaluated for each side, if there are ships left on both sides, they may choose to retreat them or continue with attack. Either player may retreat their ships to a connected-owned planet. Retreat is not available to defender if there are no connected planets that they own.

Programming details:

You will inherit from the class player. You must define a function for each of the pure virtual functions. You may define a function for non-pure virtuals. You may not redefine any non-virtual functions. You may submit a single source (.h or .hpp) or a source pair (.h/.cpp). They should be uniquely named, preferably with your cpphome screen name.

See code for more details on the virtual functions
The player class, framework and a sample player can be downloaded from here: http://venus.walagata.com/w/darryl/planets.zip

The framework, while complete, should be considered beta as I am still tweaking things and adding logging/output. I have tried separating interface from implementation so if you just stick with the public player interface and not rely on private parts or framework code, any changes I make shouldn’t affect your code.

Also, I have a working player in testplayer.h to give an example of how to derive your player.

Entries should be submitted by email to cppcontest@gmail.com.

The contest will end on of Dec 31, 2005 or when I have received 6 entries, whichever comes first unless there seems to be interest after I have received 6 then I will let it run till Dec 31.
User avatar
Darryl
 
Posts: 1342
Joined: Wed Sep 01, 2004 10:50 am
Location: Cayman Islands

Postby Corsix » Sat Dec 03, 2005 1:51 am

Hmm... interesting.
Does shout out for a cross platform SDL GUI though ;)
Code: Select all
#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main
(*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);}
User avatar
Corsix
 
Posts: 1181
Joined: Fri Jul 23, 2004 9:33 am
Location: Berkeley, UK

Postby Darryl » Sat Dec 03, 2005 6:13 am

Corsix wrote:Hmm... interesting.
Does shout out for a cross platform SDL GUI though ;)


Yea you're absolutely right, and I thought about maybe tring to do one before deadline, but I have never used SDL. Me and a buddy used to play this game taking turns on the same computer, I would love to add a network interface to and be able to play multiplayer over the net.
User avatar
Darryl
 
Posts: 1342
Joined: Wed Sep 01, 2004 10:50 am
Location: Cayman Islands

Postby Corsix » Sat Dec 03, 2005 6:40 am

Some feedback of the framework:
- I would like to be able to, as a Player class, find out the total number of planets and players in the game.
- Some more comments would be nice, eg:[syntax="cpp"]void Universe::linkPlanets()
{
std::bitset<1000> PlanetsLinked;

for (int i = 0;i < (int)mPlanets.size(); i++)
{
if (PlanetsLinked.none())
{
PlanetsLinked.set(i);
continue;
}
int r = rand()%(std::min<int>(2,(int)PlanetsLinked.count()))+1;
int low = std::max<int>(0,i-10);
int high = i-1;

std::set<int> lnks;
while ( (int)lnks.size() < r)
{
int r2 = rand()%(high-low+1)+low;
if (r2 != i) lnks.insert(r2);
}
for (std::set<int>::iterator it = lnks.begin(); it != lnks.end(); it++)
{
mPlanets[i].mConnectingPlanets.push_back(*it);
mPlanets[*it].mConnectingPlanets.push_back(i);
}
PlanetsLinked.set(i);

}
}
[/syntax]eh?
- Why is mHomePlanet a protected member of player? That means i can change it...

Also, how is a player eliminated? Is it by owning 0 ships or owning 0 planets or both?
Code: Select all
#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main
(*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);}
User avatar
Corsix
 
Posts: 1181
Joined: Fri Jul 23, 2004 9:33 am
Location: Berkeley, UK

Postby Darryl » Sat Dec 03, 2005 7:14 am

Corsix wrote:Some feedback of the framework:
- I would like to be able to, as a Player class, find out the total number of planets and players in the game.


there's 1000 planets, You can see in my testplayer class when i iterated through the planets, I hard coded 1000. but i should make it a function in case I change it. You can know number of players and their id by iterating through the planets and collecting them, but a lookup would be better here too.
- Some more comments would be nice, eg:[syntax="cpp"]void Universe::linkPlanets()
{
std::bitset<1000> PlanetsLinked;

for (int i = 0;i < (int)mPlanets.size(); i++)
{
if (PlanetsLinked.none())
{
PlanetsLinked.set(i);
continue;
}
int r = rand()%(std::min<int>(2,(int)PlanetsLinked.count()))+1;
int low = std::max<int>(0,i-10);
int high = i-1;

std::set<int> lnks;
while ( (int)lnks.size() < r)
{
int r2 = rand()%(high-low+1)+low;
if (r2 != i) lnks.insert(r2);
}
for (std::set<int>::iterator it = lnks.begin(); it != lnks.end(); it++)
{
mPlanets[i].mConnectingPlanets.push_back(*it);
mPlanets[*it].mConnectingPlanets.push_back(i);
}
PlanetsLinked.set(i);

}
}
[/syntax]eh?
true, but I focused the comments on the player code and not framework, but i can add more. I'll repost in a little bit with more comments. Was there something in this code you needed to know about or just an example of no comments?

- Why is mHomePlanet a protected member of player? That means i can change it...

because it was just a quick lookup(info only) for the player to know his own home world. The fact that a world is a homeworld is stored in the planet itself. My logic was if the person changed it theyed only hurt themselves and not change actually change their homeworld, and i was being lazy. I could change it to be consistent.

Also, how is a player eliminated? Is it by owning 0 ships or owning 0 planets or both?


Technically both, the check is done at beginning of the round, there's no way to have 1 without the other going into a round. While there may be some some ships in a incoming queue when you lose your last planet during a round, that queue will be resolved before end of round, since they have no where to retreat they either are eliminated or they conquer the planet.
User avatar
Darryl
 
Posts: 1342
Joined: Wed Sep 01, 2004 10:50 am
Location: Cayman Islands

Postby Corsix » Sat Dec 03, 2005 7:38 am

I wanted to know what the section of code did; which would have helped if it had a comment at the top, eg. "Links each planet to 2 random other planets" (or is it 3?).

Also, can planets lose resource points? The way I see it, a planet with 30 pts will make 3 ships every round, then when it gets to 40 pts, it makes 4 per round. The way I read it in the description was that a planet with 30 pts would make 3 ships then go down to 0, then work its way up to 10, make a ship and go down to 0 again.

Also, is there an easy way of getting the number of resource points that a planet has? It is possible to work it out from the current interface, but I would only be replicating the calculations done by an existing function. (Or did you want it this way, so that you have to work a way of doing it?)

Finally, why is mResources (in planet) defined as an integer? Is it possible to have this value negative? Could it wrap around the bounds of an integer? (Same with mShips)

Edit: One more thing, do you call srand?
Code: Select all
#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main
(*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);}
User avatar
Corsix
 
Posts: 1181
Joined: Fri Jul 23, 2004 9:33 am
Location: Berkeley, UK

Postby Darryl » Sat Dec 03, 2005 8:13 am

Resources start negative for each planet but the homeplanet, but they only increase, so your interpretation is right, 30 would make 3 ships every round till it hit 40.

While you can't have negative ships, there are some calculations that may result in negative ships, which then get adjusted to 0 but I don't want it to wrap to a really big number of ships

In the game I copied this from, there is no way of knowing where the resources are at so I didn't add it here either.

The code basically creates a random number of links up to 2, originally I had it at four but it was creating too many links to some planets, because while it may only create two links, the two planets it links too is random so many planets can link to the same planet. The code also only links to planets that have previously been linked to ensure there are no islands of isolated planets. It also makes sure the planets it links to are not so far away, so planet 900 won't link to planet 20.
User avatar
Darryl
 
Posts: 1342
Joined: Wed Sep 01, 2004 10:50 am
Location: Cayman Islands

Postby Corsix » Sat Dec 03, 2005 8:20 am

I'm getting runtime errors in VC7.1. Here's the call stack:
Code: Select all
   kernel32.dll!77e738b2()    
   kernel32.dll!77e738b2()    
   CPPH_Planets.exe!_CxxThrowException(void * pExceptionObject=0x0012f428, const _s__ThrowInfo * pThrowInfo=0x004770cc)  + 0x39   C++
>   CPPH_Planets.exe!std::deque<Planet,std::allocator<Planet> >::_Xran()  Line 904   C++
   CPPH_Planets.exe!std::deque<Planet,std::allocator<Planet> >::at(unsigned int _Pos=1254)  Line 514   C++
   CPPH_Planets.exe!Player::getConnectedPlanets(int pid=1254)  Line 43   C++
   CPPH_Planets.exe!TestPlayer::resolveBattle(int planetId=1254, int yourShips=3, int enemyShips=1, bool attacker=true)  Line 83 + 0x1e   C++
   CPPH_Planets.exe!Game::run()  Line 201 + 0x42   C++
   CPPH_Planets.exe!main()  Line 34 + 0xb   C++
   CPPH_Planets.exe!mainCRTStartup()  Line 259 + 0x19   C
   kernel32.dll!77e8141a()    
Code: Select all
#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main
(*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);}
User avatar
Corsix
 
Posts: 1181
Joined: Fri Jul 23, 2004 9:33 am
Location: Berkeley, UK

Postby Darryl » Sat Dec 03, 2005 8:52 am

hmmm, there's shouldn't be a planet 1254, did you change the number of planets?
User avatar
Darryl
 
Posts: 1342
Joined: Wed Sep 01, 2004 10:50 am
Location: Cayman Islands

Postby Corsix » Sat Dec 03, 2005 9:02 am

I found the problem; I had made two Game objects.
Code: Select all
#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main
(*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);}
User avatar
Corsix
 
Posts: 1181
Joined: Fri Jul 23, 2004 9:33 am
Location: Berkeley, UK

Postby Darryl » Sat Dec 03, 2005 9:24 am

Ok, Corsix, I added a function to get number of planets. I didn't do one for number of players opting instead to pass it in with the init() function. I still need to add comments but I wanted to get this uploaded first since it effects the player. I also added the msvc 7.1 for those using msvc 7.1 or higher
User avatar
Darryl
 
Posts: 1342
Joined: Wed Sep 01, 2004 10:50 am
Location: Cayman Islands

Postby Darryl » Sat Dec 03, 2005 10:57 am

Corsix wrote:I found the problem; I had made two Game objects.

yea that would do it because the variable that numbers them is static so it would go above 1000 with 2 game objects;
User avatar
Darryl
 
Posts: 1342
Joined: Wed Sep 01, 2004 10:50 am
Location: Cayman Islands

Postby Corsix » Sat Dec 03, 2005 11:42 am

It seems that srand is called after the planets are 'randomly' generated. Thus the planets are the same every time.
Code: Select all
#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main
(*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);}
User avatar
Corsix
 
Posts: 1181
Joined: Fri Jul 23, 2004 9:33 am
Location: Berkeley, UK

Postby Corsix » Sat Dec 03, 2005 12:38 pm

One thing, I'm working on a GUI, but it would really help if each planet had an X/Y co-ordinate. While this is not too major, it would also require the planet linking code to be changed so that each planet is connected to it's [between one and three] nearest neighbours.
Code: Select all
#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main
(*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);}
User avatar
Corsix
 
Posts: 1181
Joined: Fri Jul 23, 2004 9:33 am
Location: Berkeley, UK

Postby Darryl » Sat Dec 03, 2005 12:40 pm

oops my bad! fixed now. Originally had it in main and move it to game. I moved it to universe now.
User avatar
Darryl
 
Posts: 1342
Joined: Wed Sep 01, 2004 10:50 am
Location: Cayman Islands

Next

Return to Contests

Who is online

Users browsing this forum: No registered users and 0 guests