NAME
Create -- create a new galaxy
NOTES
This code was developed since we found that the old code
sometimes created galaxies that left some nations in rather
unfair positions. That is some nations would have their home
planet located far away from other planets, while others nations
home planets were located near a whole bunch of good planets.
The code tries to provide all player with an equal chance on
success, while still keeping the layout of the galaxy diverse
and interesting.
How is this accomplised:
(1) Each nation will get the same number of planets within a
circle of a given radius. The size of these planets differ
but the total sum of the sizes is the same for all nations.
The resources of the planets are still chosen random.
(2) The home world can be spaced widely from eachother, ensuring
that a nation isn't kicked out in the first few turns.
(3) To improve the tactical possibilities a number of `stuff
planets' will be scattered across the galaxy. These are
small useless planets that provide players with different
routes to attack their enemies.
(4) In addition it is possible to let the nations start with
more than one home planet, this will speed up the game.
All these options can be controled with a set of variables
that you will be asked to supply when you the galaxy
program to create a new galaxy. A large number of
different galaxies is thus possible. Try to experiment a
little before you settle on a galaxy you like.
Notice that as opposed to the original code the names of
the nations at turn zero will not be Player_xx but
Nation_xx.
Added the option to space out the empires along the edge of
a large circle, in order to make certain that no one got
a better placement geographically than any other player.
No attempt was made to ensure any seeding of players. If
you get stuck between Jacco and Frans, you are still toast. :)
Tommy 980629
AUTHOR
Frans, Rogerio Fung, Tommy
BUGS
You found bugs?
Catch them in a jar and send them to fslothouber@acm.org
SYNOPSIS
gamespecification *readGameSpec(FILE *) spec = readGameSpec(specfile)
FUNCTION
Reads and interprets a file that specifies the layout of the galaxy, and information about the players.
RESULT
Pointer to a gamespecification structure. Any parameters not defined in the specification file are given some "sensible" default.
SEE ALSO
See Doc/example.glx for information on the layout of such a file. CMD_template()
SOURCE
gamespecification *
readGameSpec(FILE * specfile)
{
gamespecification *aGameSpec;
char *isRead;
char *key;
char *value;
int team = 0;
srand((int) time(NULL));
aGameSpec = allocStruct(gamespecification);
setName(aGameSpec, "TestGame");
aGameSpec->gameOptions.gameOptions = 0;
aGameSpec->galaxySize = 200;
aGameSpec->numberOfHomePlanets = 2;
aGameSpec->numberOfEmptyPlanets = 6;
aGameSpec->numberOfStuffPlanets = 5;
aGameSpec->minDist = 25.0;
aGameSpec->radiusEmptyPlanets = 30.0;
aGameSpec->radiusSecondaryPlanets = 3.0;
aGameSpec->players = NULL;
aGameSpec->numberOfPlayers = 0;
aGameSpec->coreSizes = malloc(2 * sizeof(double));
aGameSpec->teamGame = FALSE;
aGameSpec->coreSizes[0] = 1000.0;
aGameSpec->coreSizes[1] = 400.0;
aGameSpec->gameOptions.initial_drive = 1.0;
aGameSpec->gameOptions.initial_weapons = 1.0;
aGameSpec->gameOptions.initial_shields = 1.0;
aGameSpec->gameOptions.initial_cargo = 1.0;
for (isRead = fgets(lineBuffer, LINE_BUFFER_SIZE, specfile);
isRead; isRead = fgets(lineBuffer, LINE_BUFFER_SIZE, specfile)) {
key = getstr(lineBuffer);
printf("Game options => %ld ; key : %s\n",
aGameSpec->gameOptions.gameOptions, key);
if (key[0] != '\0') {
if (noCaseStrcmp("player", key) == 0) {
newplayer *aNewPlayer;
char nationName[20];
aNewPlayer = allocStruct(newplayer);
aNewPlayer->addr = strdup(getstr(0));
aNewPlayer->team = team;
(aGameSpec->numberOfPlayers)++;
sprintf(nationName, "Nation_%d", aGameSpec->numberOfPlayers);
setName(aNewPlayer, nationName);
sprintf(nationName, "P%d", rand());
aNewPlayer->pswd = strdup(nationName);
addList(&(aGameSpec->players), aNewPlayer);
for (value = getstr(0), aNewPlayer->numberOfHomePlanets = 0;
value[0] != '\0';
value = getstr(0), aNewPlayer->numberOfHomePlanets++);
if (aNewPlayer->numberOfHomePlanets) {
int i;
aNewPlayer->coreSizes =
malloc(aNewPlayer->numberOfHomePlanets * sizeof(double));
getstr(lineBuffer);
getstr(0); /* skip address */
for (value = getstr(0), i = 0;
value[0] != '\0'; value = getstr(0), i++) {
aNewPlayer->coreSizes[i] = atof(value);
}
}
else {
int i;
aNewPlayer->coreSizes =
malloc(aGameSpec->numberOfHomePlanets * sizeof(double));
for (i = 0; i < aGameSpec->numberOfHomePlanets; i++) {
aNewPlayer->coreSizes[i] = aGameSpec->coreSizes[i];
}
aNewPlayer->numberOfHomePlanets = aGameSpec->numberOfHomePlanets;
}
}
else if (noCaseStrcmp("size", key) == 0) {
value = getstr(0);
aGameSpec->galaxySize = atof(value);
}
else if (noCaseStrcmp("nation_spacing", key) == 0) {
value = getstr(0);
aGameSpec->minDist = atof(value);
}
else if (noCaseStrcmp("empty_planets", key) == 0) {
value = getstr(0);
aGameSpec->numberOfEmptyPlanets = atoi(value);
}
else if (noCaseStrcmp("stuff_planets", key) == 0) {
value = getstr(0);
aGameSpec->numberOfStuffPlanets = atoi(value);
}
else if (noCaseStrcmp("rows", key) == 0) {
value = getstr(0);
aGameSpec->numberOfRows = atoi(value);
}
else if (noCaseStrcmp("columns", key) == 0) {
value = getstr(0);
aGameSpec->numberOfColumns = atoi(value);
}
else if (noCaseStrcmp("team", key) == 0) {
value = getstr(0);
team = atoi(value);
}
else if (noCaseStrcmp("empty_radius", key) == 0) {
value = getstr(0);
aGameSpec->radiusEmptyPlanets = atof(value);
}
else if (noCaseStrcmp("secondary_radius", key) == 0) {
value = getstr(0);
aGameSpec->radiusSecondaryPlanets = atof(value);
}
else if (noCaseStrcmp("nation_spacing", key) == 0) {
value = getstr(0);
aGameSpec->minDist = atof(value);
}
else if (noCaseStrcmp("name", key) == 0) {
setName(aGameSpec, getstr(0));
}
else if (noCaseStrcmp("teamgame", key) == 0) {
aGameSpec->teamGame = TRUE;
}
else if (noCaseStrcmp("core_sizes", key) == 0) {
int number;
for (value = getstr(0), aGameSpec->numberOfHomePlanets = 0;
value[0] != '\0';
value = getstr(0), aGameSpec->numberOfHomePlanets++);
aGameSpec->coreSizes =
malloc(aGameSpec->numberOfHomePlanets * sizeof(double));
getstr(lineBuffer);
for (value = getstr(0), number = 0;
value[0] != '\0'; value = getstr(0), number++) {
aGameSpec->coreSizes[number] = atof(value);
}
}
else if (noCaseStrcmp("initialtechlevels", key) == 0) { /* CB-20010407
* ; no
* verification
* at all */
aGameSpec->gameOptions.initial_drive = atof(getstr(0)); /* seems
* strtod
* is not
* portable
*/
aGameSpec->gameOptions.initial_weapons = atof(getstr(0));
aGameSpec->gameOptions.initial_shields = atof(getstr(0));
aGameSpec->gameOptions.initial_cargo = atof(getstr(0));
if (aGameSpec->gameOptions.initial_drive < 1.0) {
aGameSpec->gameOptions.initial_drive = 1.0;
}
if (aGameSpec->gameOptions.initial_weapons < 1.0) {
aGameSpec->gameOptions.initial_weapons = 1.0;
}
if (aGameSpec->gameOptions.initial_shields < 1.0) {
aGameSpec->gameOptions.initial_shields = 1.0;
}
if (aGameSpec->gameOptions.initial_cargo < 1.0) {
aGameSpec->gameOptions.initial_cargo = 1.0;
}
}
else if (noCaseStrcmp("fullbombing", key) == 0) {
aGameSpec->gameOptions.gameOptions |= GAME_NONGBOMBING;
}
else if (noCaseStrcmp("keepproduction", key) == 0) {
aGameSpec->gameOptions.gameOptions |= GAME_KEEPPRODUCTION;
}
else if (noCaseStrcmp("createcircle", key) == 0) { /* Don't
* know if
* still
* used
* ???? CB
* 20010425 */
aGameSpec->gameOptions.gameOptions |= GAME_CREATECIRCLE;
}
else if (noCaseStrcmp("dontdropdead", key) == 0) {
aGameSpec->gameOptions.gameOptions |= GAME_NODROP;
}
else if (noCaseStrcmp("savereportcopy", key) == 0) {
aGameSpec->gameOptions.gameOptions |= GAME_SAVECOPY;
}
else if (noCaseStrcmp("sphericalgalaxy", key) == 0) { /* CB-20010401
* ; see
* galaxy.h
*/
/* printf ("*==> %ld\n", aGameSpec->gameOptions); */
aGameSpec->gameOptions.gameOptions |= GAME_SPHERICALGALAXY;
/* printf ("*==> %ld\n", aGameSpec->gameOptions); */
}
else {
printf("Unknown key %s\n", key);
}
}
}
return aGameSpec;
}
NAME
printGameSpecs -- print the game specs.
SYNOPSIS
void printGameSpecs(gamespecification *aGameSpec)
SOURCE
void
printGameSpecs(gamespecification *aGameSpec)
{
newplayer *curNewPlayer;
/* aGameSpec->gameOptions = 0; CB-20010407 */
printf("Galaxy: %s\n", aGameSpec->name);
if (aGameSpec->teamGame) {
printf("TeamGame: Yes\n");
}
else {
printf("TeamGame: No\n");
}
printf("Size: %.0f x %.0f\n",
aGameSpec->galaxySize, aGameSpec->galaxySize);
printf("Full bombing : %s\n",
(aGameSpec->gameOptions.
gameOptions & GAME_NONGBOMBING ? "ON" : "OFF"));
printf("Keep production : %s\n",
(aGameSpec->gameOptions.
gameOptions & GAME_KEEPPRODUCTION ? "ON" : "OFF"));
printf("Drop dead players: %s\n",
(aGameSpec->gameOptions.
gameOptions & GAME_NODROP ? "ON" : "OFF"));
printf("Save report copy : %s\n",
(aGameSpec->gameOptions.
gameOptions & GAME_SAVECOPY ? "ON" : "OFF"));
printf("Spherical Galaxy : %s\n",
(aGameSpec->gameOptions.
gameOptions & GAME_SPHERICALGALAXY ? "ON" : "OFF"));
printf("Initial tech levels:\n\
* Drive: %5.2f,\n\
* Weapons: %5.2f,\n\
* Shields: %5.2f,\n\
* Cargo: %5.2f.\n", aGameSpec->gameOptions.initial_drive, aGameSpec->gameOptions.initial_weapons, aGameSpec->gameOptions.initial_shields, aGameSpec->gameOptions.initial_cargo);
printf("Nations: %d\n", aGameSpec->numberOfPlayers);
printf("Home planets/nation: %d\n", aGameSpec->numberOfHomePlanets);
printf("Spacing nations: %.1f\n", aGameSpec->minDist);
printf("Secondary planet radius: %.1f\n",
aGameSpec->radiusSecondaryPlanets);
printf("Empty planets/nation: %d\n",
aGameSpec->numberOfEmptyPlanets);
printf("Located in within a: %.1f radius\n",
aGameSpec->radiusEmptyPlanets);
printf("Stuff planets/nation: %d\n",
aGameSpec->numberOfStuffPlanets);
for (curNewPlayer = aGameSpec->players;
curNewPlayer; curNewPlayer = curNewPlayer->next) {
printf("%s played by %s with password %s\n",
curNewPlayer->name, curNewPlayer->addr, curNewPlayer->pswd);
}
}
NAME
creategame -- create a game based on a gamespecification.
SYNOPSIS
game *creategame(gamespecification *) newGame = creategame(aGameSpec)
FUNCTION
Creates all nations. For each nation a number of planets are created and intialized. The number of nations and number of planets are defined in the game specification.
RESULT
Pointer to an initialized game structure.
SOURCE
game *
creategame(gamespecification *aGameSpec)
{
if (createGameDirectories(aGameSpec->name)) {
int planet_name;
int created_ok;
game *aGame;
srand((int) time(NULL));
resetErnie(197162622 + (rand() & 0xFF));
aGame = allocStruct(game);
setName(aGame, aGameSpec->name);
aGame->turn = 0;
aGame->gameOptions.gameOptions = aGameSpec->gameOptions.gameOptions;
aGame->gameOptions.initial_drive =
aGameSpec->gameOptions.initial_drive;
aGame->gameOptions.initial_weapons =
aGameSpec->gameOptions.initial_weapons;
aGame->gameOptions.initial_shields =
aGameSpec->gameOptions.initial_shields;
aGame->gameOptions.initial_cargo =
aGameSpec->gameOptions.initial_cargo;
/* Do not change this! planets can be looked up by number and this
* function expects the first planet to have number 1 */
planet_name = 1;
if (aGameSpec->teamGame) {
created_ok = createCheckeredLayout(aGameSpec, aGame, planet_name);
if (created_ok)
setTeamAllies(aGame->players);
}
else {
created_ok = createStandardLayout(aGameSpec, aGame, planet_name);
}
if (created_ok) {
Randomize_Planet_Numbers(aGame);
preComputeGroupData(aGame);
nationStatus(aGame);
return aGame;
}
else {
freegame(aGame);
return NULL;
}
}
else {
return NULL;
}
}
NAME
createGameDirectories --
FUNCTION
Creates a number of sub directories that are used to store
files of a game. Each subdirectory has the same name as
the game. They are created in the directories:
reports/
orders/
statistics/
INPUTS
name -- name of the game
SOURCE
int
createGameDirectories(char *name)
{
sprintf(lineBuffer, "%s/data/%s", galaxynghome, name);
if (GOS_mkdir(lineBuffer, 0700)) {
#if 0
fprintf(stderr, "Warning a game under that name already exists\n");
fprintf(stderr, "Do you want to continue [y/n]?\n");
scanf("%s", lineBuffer);
if (*lineBuffer != 'y')
return FALSE;
#endif
}
else {
sprintf(lineBuffer, "%s/reports/%s", galaxynghome, name);
GOS_mkdir(lineBuffer, 0700);
sprintf(lineBuffer, "%s/orders/%s", galaxynghome, name);
GOS_mkdir(lineBuffer, 0700);
sprintf(lineBuffer, "%s/statistics/%s", galaxynghome, name);
GOS_mkdir(lineBuffer, 0700);
sprintf(lineBuffer, "%s/forecasts/%s", galaxynghome, name);
GOS_mkdir(lineBuffer, 0700);
}
return TRUE;
}
NAME
createPlayer -- allocate and initialize a player structure.
SYNOPSIS
player *createPlayer(game *aGame, newplayer *aNewPlayer)
FUNCTION
RESULT
Pointer to an initialized player structure.
SOURCE
player *
createPlayer(gamespecification *aGameSpec, game *aGame,
newplayer *aNewPlayer)
{
player *aPlayer;
aPlayer = allocStruct(player);
setName(aPlayer, aNewPlayer->name);
aPlayer->pswd = strdup(aNewPlayer->pswd);
aPlayer->addr = strdup(aNewPlayer->addr);
aPlayer->team = aNewPlayer->team;
aPlayer->realName = strdup("none");
aPlayer->pswdstate = 1;
aPlayer->drive = aGameSpec->gameOptions.initial_drive;
aPlayer->weapons = aGameSpec->gameOptions.initial_weapons;
aPlayer->shields = aGameSpec->gameOptions.initial_shields;
aPlayer->cargo = aGameSpec->gameOptions.initial_cargo;
aPlayer->msize = aGame->galaxysize;
aPlayer->flags =
F_ANONYMOUS | F_AUTOUNLOAD | F_PRODTABLE | F_SORTGROUPS |
F_GROUPFORECAST | F_PLANETFORECAST | F_SHIPTYPEFORECAST |
F_ROUTESFORECAST | F_XMLREPORT | F_TXTREPORT ;
/* F_MACHINEREPORT */
return aPlayer;
}
NAME
printPlanetStats
SOURCE
void
printPlanetStats(planet *p)
{
printf(" Planet %s %.2f %.2f %.2f %.2f %.2f %.2f\n",
p->name, p->x, p->y, p->size, p->pop, p->ind, p->resources);
}
NAME
Add_Stuff_Planets -- add a number of stuff planets.
SYNOPSIS
void Add_Stuff_Planets(game *, int, int *)
Add_Stuff_Planets(aGame, stuff_planets, planet_name)
FUNCTION
Stuff planets are small useless planets that are randomly scattered accross the galaxy to fill up the empty space between the empires.
INPUTS
aGame -- game to add the planets to. stuff_planets -- the number of stuff planets to be added. planet_name -- the name (number) of the previous planet.
RESULT
A number of planet are added to the game's planet list. planet_name is modified, will have the name (number) of the last planet that was added.
SOURCE
void
Add_Stuff_Planets(game *aGame, int stuff_planets, int *planet_name)
{
int cur_planet_nr;
planet *p;
double new_x, new_y;
int is_ok;
for (cur_planet_nr = 0; cur_planet_nr < stuff_planets; cur_planet_nr++) {
unode = (struct uniq_avl *) malloc(sizeof(struct uniq_avl));
for (is_ok = FALSE; !is_ok;) {
is_ok = TRUE;
new_x = round2(frand(aGame->galaxysize));
new_y = round2(frand(aGame->galaxysize));
if (new_x < 0 || new_x >= aGame->galaxysize) {
is_ok = FALSE;
continue;
}
if (new_y < 0 || new_y >= aGame->galaxysize) {
is_ok = FALSE;
continue;
}
sprintf(unode->key, "%08d%08d", (int) (new_x * 100),
(int) (new_y * 100));
if (avl_search(&unique, (avl *) unode, avliter) == 0) {
avl_insert(&unique, (avl *) unode);
}
else {
printf("x, y: %.2f,%.2f ;; key: %s\n", new_x, new_y, unode->key);
is_ok = FALSE;
continue;
}
}
p = addplanet(aGame);
(*planet_name)++;
p->x = new_x;
p->y = new_y;
p->size = 2.0 + frand(170.0);
p->resources = round2(pow(2.0, frand2()));
p->producing = PR_CAP;
}
}
NAME
Add_Circle_Stuff_Planets --
NAME
Randomize_Planet_Numbers -- shuffle planet names.
FUNCTION
Randomly shuffle the planet names. The method used is randomly selecting two planets and swapping all their data. This process is repeated 2000 times. The names are randomized to prevent players from guessing which planets are the good planets and bad planets around the nations core home planets.
NOTES
This is not a particular good or speedy way of shuffling. Someone suggested a much faster method, but that got misplaced.
SOURCE
void
Randomize_Planet_Numbers(game *aGame)
{
int total_nr_of_planets;
planet *p;
int randomizor;
for (p = aGame->planets, total_nr_of_planets = 0; p; p = p->next) {
total_nr_of_planets++;
}
for (randomizor = 0; randomizor < 2000; randomizor++) {
int pln1, pln2, nm;
planet *p1, *p2;
pln1 = rand() % total_nr_of_planets;
pln2 = rand() % total_nr_of_planets;
for (p1 = aGame->planets, nm = 0; nm < pln1; p1 = p1->next, nm++);
for (p2 = aGame->planets, nm = 0; nm < pln2; p2 = p2->next, nm++);
if (!p1->owner && !p2->owner) {
player *temp;
temp = p2->owner;
p2->owner = p1->owner;
p1->owner = temp;
swap_data(&p1->x, &p2->x);
swap_data(&p1->y, &p2->y);
swap_data(&p1->size, &p2->size);
swap_data(&p1->pop, &p2->pop);
swap_data(&p1->ind, &p2->ind);
swap_data(&p1->resources, &p2->resources);
}
}
}
NAME
Add_Core_Home_Planet -- add a core home planet for a nation.
FUNCTION
Each nation has atleast one home planet. This is it's core home planet. The other home planets are located around it. This function allocates a core home planet. It makes sure that there is a minimum distance between all core home planets. The core home planets are all located on a big disc that fits inside the square galaxy. The disc is used to prevent nations ending up in one of the corners.
INPUTS
aGame -- game to add the planet to. min_dist -- minimum distance between the core planets. planet_name -- name of the previously added planet. aPlayer -- nation the core planet will belong to. RESULTS A core plane is added to the game's planet list. planet_name is modified, will have the name (number) of this planet. NULL if something went wrong.
NAME
Add_Circle_Home_Planet
NOTES
Currently not used since the code to create a circle game has not yet been added to creategame().
NAME
Add_Extra_Home_Planets
FUNCTION
In addition to its core home planet a nation can have a number of additional home planets. This functions adds these. They are added randomly on a donut shape disk centered around the core home planet. The donut hole has a radius of 1, and the donut disk has a radius of max_radius.
SOURCE
void
Add_Extra_Home_Planets(game *aGame,
double x, double y,
double size,
double max_radius,
int *planet_name, player *aPlayer)
{
planet *p;
double radius, angle;
double new_x, new_y;
int is_ok;
unode = (struct uniq_avl *) malloc(sizeof(struct uniq_avl));
for (is_ok = FALSE; !is_ok;) {
is_ok = TRUE;
radius = 1.0 + frand(max_radius - 1.0);
angle = frand(360.0) * (2 * 3.141592654 / 360.0);
new_x = round2(x + sin(angle) * radius);
new_y = round2(y + cos(angle) * radius);
if (new_x < 0 || new_x >= aGame->galaxysize) {
is_ok = FALSE;
continue;
}
if (new_y < 0 || new_y >= aGame->galaxysize) {
is_ok = FALSE;
continue;
}
sprintf(unode->key, "%08d%08d", (int) (new_x * 100),
(int) (new_y * 100));
if (avl_search(&unique, (avl *) unode, avliter) == 0) {
avl_insert(&unique, (avl *) unode);
}
else {
printf("x, y: %.2f,%.2f ;; key: %s\n", new_x, new_y, unode->key);
is_ok = FALSE;
continue;
}
}
p = addplanet(aGame);
(*planet_name)++;
p->x = round2(new_x);
p->y = round2(new_y);
p->owner = aPlayer;
p->size = size;
p->producing = PR_DRIVE;
p->resources = 10;
p->pop = size;
p->ind = size;
printPlanetStats(p);
}
NAME
Add_Extra_Circle_Stuff_Planets
NAME
Add_Center_Planet -- add a planet in the exact centre of the galaxy.
SOURCE
void
Add_Center_Planet(game *aGame, int *planet_name)
{
planet *p;
p = addplanet(aGame);
(*planet_name)++;
p->x = round2(aGame->galaxysize / 2.0);
p->y = round2(aGame->galaxysize / 2.0);
p->size = 5000.0;
p->producing = PR_DRIVE;
p->resources = round2(pow(2.0, frand2()));
}
NAME
Add_Empty_Planets -- add some good size empty planets.
FUNCTION
This adds a number of good (relatively big sized) planets around the core home planet of a nation. The sum of the sizes of all these planets is about the same for each nation.
SOURCE
void
Add_Empty_Planets(game *aGame,
int nplanets, double empty_dist,
double x, double y,
int *planet_name, double low_range, double up_range)
{
double tot_mass;
double *planet_sizes;
int cur_planet_nr;
double cur_total_size;
planet *p;
printf("o Adding empty planets.\n");
planet_sizes = alloc(nplanets * sizeof(double));
for (cur_total_size = 0.0, cur_planet_nr = 0; cur_planet_nr < nplanets; cur_planet_nr++) {
planet_sizes[cur_planet_nr] = frand(MAXPOP - 80) + 80.0;
cur_total_size += planet_sizes[cur_planet_nr];
}
/* Adjust the Planet sizes in order to make sure that each players get
* about the same total amount */
for (;
(cur_total_size < nplanets * low_range) ||
(cur_total_size > nplanets * up_range);) {
int pl_sel;
float adj_factor;
adj_factor = 7.5 + frand(5);
pl_sel = frand3(nplanets);
if (cur_total_size > nplanets * up_range) {
(planet_sizes[pl_sel]) -= adj_factor;
cur_total_size -= adj_factor;
}
else {
(planet_sizes[pl_sel]) += adj_factor;
cur_total_size += adj_factor;
}
if (planet_sizes[pl_sel] < 20.0) {
planet_sizes[pl_sel] += adj_factor;
cur_total_size += adj_factor;
}
if (planet_sizes[pl_sel] > 980.0) {
planet_sizes[pl_sel] -= adj_factor;
cur_total_size -= adj_factor;
}
}
for (cur_planet_nr = 0, tot_mass = 0.0;
cur_planet_nr < nplanets; cur_planet_nr++) {
double radius, angle;
double new_x, new_y;
int is_ok;
unode = (struct uniq_avl *) malloc(sizeof(struct uniq_avl));
for (is_ok = FALSE; !is_ok;) {
is_ok = TRUE;
radius = 0.2 + frand(empty_dist - 0.2);
angle = frand(360.0) * (2 * 3.141592654 / 360.0);
new_x = round2(x + sin(angle) * radius);
new_y = round2(y + cos(angle) * radius);
if (new_x < 0 || new_x >= aGame->galaxysize) {
is_ok = FALSE;
continue;
}
if (new_y < 0 || new_y >= aGame->galaxysize) {
is_ok = FALSE;
continue;
}
sprintf(unode->key, "%08d%08d", (int) (new_x * 100),
(int) (new_y * 100));
if (avl_search(&unique, (avl *) unode, avliter) == 0) {
avl_insert(&unique, (avl *) unode);
}
else {
printf("x, y: %.2f,%.2f ;; key: %s\n", new_x, new_y, unode->key);
is_ok = FALSE;
continue;
}
}
p = addplanet(aGame);
(*planet_name)++;
p->x = new_x;
p->y = new_y;
p->size = planet_sizes[cur_planet_nr];
p->resources = round2(0.3 + pow(8.0, frand2()));
p->producing = PR_CAP;
tot_mass += (p->size) / (10.0 + 1.0 / p->resources);
printPlanetStats(p);
}
printf(" Total production mass: %.2f\n", tot_mass);
free(planet_sizes);
}
NAME
swap_data -- swap two doubles
SYNOPSIS
void swap_data(double *v1, double *v2)
NAME
CalcCirclegalaxysize