forked from github/server
The rule of "no more than 5 weeks difference per island" gets coded in a smarter way. No longer creating new island every 5 turns, but actually checking the island.
This commit is contained in:
parent
47327786a2
commit
78615978c8
4 changed files with 27 additions and 142 deletions
|
@ -271,131 +271,6 @@ read_newfactions(const char * filename)
|
||||||
return newfactions;
|
return newfactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SEED_QUALITY /* does this work? */
|
|
||||||
typedef struct seed_t {
|
|
||||||
struct region * region;
|
|
||||||
struct newfaction * player;
|
|
||||||
struct seed_t * next[MAXDIRECTIONS];
|
|
||||||
} seed_t;
|
|
||||||
|
|
||||||
static double
|
|
||||||
get_influence(struct seed_t * seed, struct seed_t * target)
|
|
||||||
{
|
|
||||||
double q = 0.0;
|
|
||||||
direction_t d;
|
|
||||||
if (target==0 || seed==0) return q;
|
|
||||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
||||||
seed_t * s = seed->next[d];
|
|
||||||
if (s==target) {
|
|
||||||
if (target->player) {
|
|
||||||
if (seed->player) {
|
|
||||||
/* neighbours bad. */
|
|
||||||
q -= 4.0;
|
|
||||||
if (seed->player->race==target->player->race) {
|
|
||||||
/* don't want similar people next to each other */
|
|
||||||
q -= 2.0;
|
|
||||||
} else if (seed->player->race==new_race[RC_ELF]) {
|
|
||||||
if (target->player->race==new_race[RC_TROLL]) {
|
|
||||||
/* elf sitting next to troll: poor troll */
|
|
||||||
q -= 5.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (target->player) {
|
|
||||||
/* empty regions good */
|
|
||||||
q += 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
static double
|
|
||||||
get_quality(struct seed_t * seed)
|
|
||||||
{
|
|
||||||
double q = 0.0;
|
|
||||||
int nterrains[T_ASTRAL];
|
|
||||||
direction_t d;
|
|
||||||
|
|
||||||
memset(nterrains, 0, sizeof(nterrains));
|
|
||||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
||||||
seed_t * ns = seed->next[d];
|
|
||||||
if (ns) {
|
|
||||||
terrain_t t = rterrain(ns->region);
|
|
||||||
if (t<T_ASTRAL) ++nterrains[t];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++nterrains[rterrain(seed->region)];
|
|
||||||
|
|
||||||
if (nterrains[T_MOUNTAIN]) {
|
|
||||||
/* 5 points for the first, and 2 points for every other mountain */
|
|
||||||
q += (3+nterrains[T_MOUNTAIN]*2);
|
|
||||||
} else if (seed->player->race==new_race[RC_DWARF]) {
|
|
||||||
/* -10 for a dwarf who isn't close to a mountain */
|
|
||||||
q -= 10.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nterrains[T_PLAIN]) {
|
|
||||||
/* 5 points for the first, and 2 points for every other plain */
|
|
||||||
q += (3+nterrains[T_PLAIN]*2);
|
|
||||||
} else if (seed->player->race==new_race[RC_ELF]) {
|
|
||||||
/* -10 for an elf who isn't close to a plain */
|
|
||||||
q -= 10.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nterrains[T_DESERT]) {
|
|
||||||
/* +10 points for the first if we are insects, and -2 points for every
|
|
||||||
* other desert */
|
|
||||||
if (seed->player->race==new_race[RC_INSECT]) q += 12;
|
|
||||||
q -= (nterrains[T_DESERT]*2);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (rterrain(seed->region)) {
|
|
||||||
case T_DESERT:
|
|
||||||
q -=8.0;
|
|
||||||
break;
|
|
||||||
case T_VOLCANO:
|
|
||||||
q -=20.0;
|
|
||||||
break;
|
|
||||||
case T_GLACIER:
|
|
||||||
q -=10.0;
|
|
||||||
break;
|
|
||||||
case T_SWAMP:
|
|
||||||
q -= 1.0;
|
|
||||||
break;
|
|
||||||
case T_PLAIN:
|
|
||||||
q += 4.0;
|
|
||||||
break;
|
|
||||||
case T_MOUNTAIN:
|
|
||||||
q += 5.0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 2.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static double
|
|
||||||
recalc(seed_t * seeds, int nseeds, int nplayers)
|
|
||||||
{
|
|
||||||
int i, p = 0;
|
|
||||||
double quality = 0.0, q = 0.0, *qarr = malloc(sizeof(int) * nplayers);
|
|
||||||
for (i=0;i!=nseeds;++i) {
|
|
||||||
if (seeds[i].player) {
|
|
||||||
double quality = get_quality(seeds+i);
|
|
||||||
direction_t d;
|
|
||||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
|
||||||
quality += get_influence(seeds[i].next[d], seeds+i);
|
|
||||||
}
|
|
||||||
qarr[p++] = quality;
|
|
||||||
q += quality;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return quality + q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int numnewbies;
|
extern int numnewbies;
|
||||||
|
|
||||||
static terrain_t
|
static terrain_t
|
||||||
|
@ -412,7 +287,6 @@ preferred_terrain(const struct race * rc)
|
||||||
#define PLAYERS_PER_ISLAND 20
|
#define PLAYERS_PER_ISLAND 20
|
||||||
#define MAXISLANDSIZE 50
|
#define MAXISLANDSIZE 50
|
||||||
#define MINFACTIONS 1
|
#define MINFACTIONS 1
|
||||||
#define MAXAGEDIFF 5
|
|
||||||
#define VOLCANO_CHANCE 100
|
#define VOLCANO_CHANCE 100
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
|
@ -420,13 +294,12 @@ virgin_region(const region * r)
|
||||||
{
|
{
|
||||||
direction_t d;
|
direction_t d;
|
||||||
if (r==NULL) return true;
|
if (r==NULL) return true;
|
||||||
if (r->age>MAXAGEDIFF) return false;
|
|
||||||
if (fval(r->terrain, FORBIDDEN_REGION)) return false;
|
if (fval(r->terrain, FORBIDDEN_REGION)) return false;
|
||||||
if (r->units) return false;
|
if (r->units) return false;
|
||||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||||
const region * rn = rconnect(r, d);
|
const region * rn = rconnect(r, d);
|
||||||
if (rn) {
|
if (rn) {
|
||||||
if (rn->age>MAXAGEDIFF) return false;
|
if (rn->age>r->age+1) return false;
|
||||||
if (rn->units) return false;
|
if (rn->units) return false;
|
||||||
if (fval(rn->terrain, FORBIDDEN_REGION)) {
|
if (fval(rn->terrain, FORBIDDEN_REGION)) {
|
||||||
/* because it kinda sucks to have islands that are adjacent to a firewall */
|
/* because it kinda sucks to have islands that are adjacent to a firewall */
|
||||||
|
@ -468,10 +341,10 @@ get_island(region * root, region_list ** rlist)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
island_size(region * r)
|
get_island_info(region * r, int * size_p, int * inhabited_p, int * maxage_p)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0, maxage = 0, inhabited = 0;
|
||||||
region_list * rlist = NULL;
|
region_list * rlist = NULL;
|
||||||
region_list * island = NULL;
|
region_list * island = NULL;
|
||||||
add_regionlist(&rlist, r);
|
add_regionlist(&rlist, r);
|
||||||
|
@ -480,6 +353,15 @@ island_size(region * r)
|
||||||
while (rlist) {
|
while (rlist) {
|
||||||
direction_t d;
|
direction_t d;
|
||||||
r = rlist->data;
|
r = rlist->data;
|
||||||
|
if (r->units) {
|
||||||
|
unit * u;
|
||||||
|
for (u=r->units; u; u=u->next) {
|
||||||
|
if (u->faction->age > maxage) {
|
||||||
|
maxage = u->faction->age;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++inhabited;
|
||||||
|
}
|
||||||
++size;
|
++size;
|
||||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||||
region * rn = rconnect(r, d);
|
region * rn = rconnect(r, d);
|
||||||
|
@ -497,7 +379,9 @@ island_size(region * r)
|
||||||
freset(rlist->data, RF_MARK);
|
freset(rlist->data, RF_MARK);
|
||||||
}
|
}
|
||||||
free_regionlist(island);
|
free_regionlist(island);
|
||||||
return size;
|
if (size_p) *size_p = size;
|
||||||
|
if (inhabited_p) *inhabited_p = inhabited;
|
||||||
|
if (maxage_p) *maxage_p = maxage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -532,7 +416,7 @@ frame_regions(int age, terrain_t terrain)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
autoseed(newfaction ** players, int nsize, boolean new_island)
|
autoseed(newfaction ** players, int nsize, int max_agediff)
|
||||||
{
|
{
|
||||||
short x = 0, y = 0;
|
short x = 0, y = 0;
|
||||||
region * r = NULL;
|
region * r = NULL;
|
||||||
|
@ -546,7 +430,7 @@ autoseed(newfaction ** players, int nsize, boolean new_island)
|
||||||
|
|
||||||
if (listlen(*players)<MINFACTIONS) return 0;
|
if (listlen(*players)<MINFACTIONS) return 0;
|
||||||
|
|
||||||
if (!new_island) {
|
if (max_agediff>0) {
|
||||||
region * rmin = NULL;
|
region * rmin = NULL;
|
||||||
/* find a spot that's adjacent to the previous island, but virgin.
|
/* find a spot that's adjacent to the previous island, but virgin.
|
||||||
* like the last land virgin ocean region adjacent to land.
|
* like the last land virgin ocean region adjacent to land.
|
||||||
|
@ -559,14 +443,15 @@ autoseed(newfaction ** players, int nsize, boolean new_island)
|
||||||
region * rn = rconnect(r, d);
|
region * rn = rconnect(r, d);
|
||||||
if (rn && rn->land && virgin_region(rn)) {
|
if (rn && rn->land && virgin_region(rn)) {
|
||||||
/* only expand islands that aren't single-islands and not too big already */
|
/* only expand islands that aren't single-islands and not too big already */
|
||||||
int n = island_size(rn);
|
int size, inhabitants, maxage;
|
||||||
if (n>2 && n<MAXISLANDSIZE) {
|
get_island_info(rn, &size, &inhabitants, &maxage);
|
||||||
|
if (maxage<=max_agediff && size>2 && size<MAXISLANDSIZE) {
|
||||||
rmin = rn;
|
rmin = rn;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rmin!=NULL) {
|
if (rmin!=NULL) {
|
||||||
region_list * rlist = NULL, * rptr;
|
region_list * rlist = NULL, * rptr;
|
||||||
|
@ -599,7 +484,7 @@ autoseed(newfaction ** players, int nsize, boolean new_island)
|
||||||
*/
|
*/
|
||||||
for (r=regions;r;r=r->next) {
|
for (r=regions;r;r=r->next) {
|
||||||
struct plane * p = r->planep;
|
struct plane * p = r->planep;
|
||||||
if (rterrain(r)==T_OCEAN && p==0 && (rmin==NULL || r->age<=MAXAGEDIFF)) {
|
if (rterrain(r)==T_OCEAN && p==0 && (rmin==NULL || r->age<=max_agediff)) {
|
||||||
direction_t d;
|
direction_t d;
|
||||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||||
region * rn = rconnect(r, d);
|
region * rn = rconnect(r, d);
|
||||||
|
|
|
@ -32,7 +32,7 @@ typedef struct newfaction {
|
||||||
struct alliance * allies;
|
struct alliance * allies;
|
||||||
} newfaction;
|
} newfaction;
|
||||||
|
|
||||||
extern int autoseed(newfaction ** players, int nsize, boolean new_island);
|
extern int autoseed(newfaction ** players, int nsize, int max_agediff);
|
||||||
extern newfaction * read_newfactions(const char * filename);
|
extern newfaction * read_newfactions(const char * filename);
|
||||||
extern void get_island(struct region * root, struct region_list ** rlist);
|
extern void get_island(struct region * root, struct region_list ** rlist);
|
||||||
extern int fix_demand(struct region *r);
|
extern int fix_demand(struct region *r);
|
||||||
|
|
|
@ -29,7 +29,7 @@ seed_players(const char * filename, boolean new_island)
|
||||||
int n = listlen(players);
|
int n = listlen(players);
|
||||||
int k = (n+ISLANDSIZE-1)/ISLANDSIZE;
|
int k = (n+ISLANDSIZE-1)/ISLANDSIZE;
|
||||||
k = n / k;
|
k = n / k;
|
||||||
n = autoseed(&players, k, new_island || (turn % TURNS_PER_ISLAND)==0);
|
n = autoseed(&players, k, new_island?0:TURNS_PER_ISLAND);
|
||||||
if (n==0) {
|
if (n==0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ lua_getstring(const char * lname, const char * key)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ISLANDSIZE 20
|
#define ISLANDSIZE 20
|
||||||
#define TURNS_PER_ISLAND 4
|
#define TURNS_PER_ISLAND 5
|
||||||
static void
|
static void
|
||||||
lua_autoseed(const char * filename, bool new_island)
|
lua_autoseed(const char * filename, bool new_island)
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,7 @@ lua_autoseed(const char * filename, bool new_island)
|
||||||
int n = listlen(players);
|
int n = listlen(players);
|
||||||
int k = (n+ISLANDSIZE-1)/ISLANDSIZE;
|
int k = (n+ISLANDSIZE-1)/ISLANDSIZE;
|
||||||
k = n / k;
|
k = n / k;
|
||||||
n = autoseed(&players, k, new_island || (turn % TURNS_PER_ISLAND)==0);
|
n = autoseed(&players, k, new_island?0:TURNS_PER_ISLAND);
|
||||||
if (n==0) {
|
if (n==0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue