temporary version of generator

This commit is contained in:
Lendemor 2015-01-13 23:37:37 +01:00
parent 839eebe5d4
commit c745c0746f
3 changed files with 140 additions and 76 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.o

View File

@ -1,8 +1,23 @@
#include "main.h" #include "main.h"
#define MAX_POWER 10 #define MAX_POWER 10
#define MAX_EPICENTER_BY_TYPE 10 #define MAX_EPICENTER_BY_TYPE 7
#define MAX_RADIUS 75 #define DIST_MIN_INTER_EPICENTRE 50
#define MIN_RADIUS 25
#define OFFSET_RADIUS 50
//map type ----> not used for now
enum{
FLAT, VALLEY,
};
//biome type
enum{
VILLAGE, PLAINS, FOREST,MOUNTAINS,NB_BIOMES
};
//probability for each biomes
char proba_table[NB_BIOMES][5] = {{97,2,1,0,0},{85,13,2,0,0},{40,40,20,0,0},{0,0,0,80,20}};
typedef struct{ typedef struct{
int x; int x;
@ -10,58 +25,65 @@ typedef struct{
int type; int type;
int power; int power;
int radius; int radius;
} t_epicenter; } t_biome;
// variables // variables
t_epicenter* l_epicenters; int spx[2], spy[2];
int size_epicenters; t_biome* l_biomes;
int cpt_epicenter = 0; int size_biomes;
int cpt_biome = 0;
int width, height; int width, height;
// functions // functions
int distance_manhattan(int x1,int y1, int x2, int y2); int distance_manhattan(int x1,int y1, int x2, int y2);
int absolute(int val); int absolute(int val);
void set_spawns(t_pixel** map, t_team* teams); void set_spawns(t_pixel** map, t_team* teams);
void create_epicenter(int x, int y, int type); void create_biome(int x, int y, int type);
void create_epicenter_random(int type); void create_biome_random(int type);
int check_nears_biomes(int x, int y);
int check_nears_spawn(int x, int y);
int in_radius(int x,int y,t_biome e);
int generate(int x, int y); int generate(int x, int y);
void init_generator();
void create_map(t_pixel** map, t_team* teams, int w, int h){ void create_map(t_pixel** map, t_team* teams, int w, int h){
int i,j; int i,j;
int type; int type;
//epicenter variable //biome variable
int nb_rock, nb_tree, nb_berries; int nb_plains, nb_forests, nb_mountains;
width = w; width = w;
height = h; height = h;
init_generator();
//Epicenters generation //Epicenters generation
// random choice for numbers of epicenters // random choice for numbers of biomes
nb_rock = rand()%MAX_EPICENTER_BY_TYPE; nb_plains = (rand()%MAX_EPICENTER_BY_TYPE)+3;
nb_tree = rand()%MAX_EPICENTER_BY_TYPE; nb_forests = (rand()%MAX_EPICENTER_BY_TYPE)+3;
nb_berries = rand()%MAX_EPICENTER_BY_TYPE; nb_mountains = (rand()%MAX_EPICENTER_BY_TYPE)+3;
size_epicenters = nb_rock + nb_tree + nb_berries + NB_TEAMS; size_biomes = nb_plains+ nb_forests + nb_mountains + NB_TEAMS;
l_epicenters = malloc(sizeof(t_epicenter)*size_epicenters); l_biomes = malloc(sizeof(t_biome)*size_biomes);
// Spawn generations // Spawn generations
set_spawns(map,teams); set_spawns(map,teams);
for(i=0;i<nb_rock;i++) for(i=0;i<nb_plains;i++)
create_epicenter_random(ROCK); create_biome_random(PLAINS);
for(i=0;i<nb_tree;i++) for(i=0;i<nb_forests;i++)
create_epicenter_random(TREE); create_biome_random(FOREST);
for(i=0;i<nb_berries;i++) for(i=0;i<nb_mountains;i++)
create_epicenter_random(BERRIES); create_biome_random(MOUNTAINS);
// */ // */
//génération de la carte //génération de la carte
for (i=0;i<width;i++){ for (i=0;i<width;i++){
for(j=0;j<height;j++){ for(j=0;j<height;j++){
if (i == 0 || j == 0){ if (i == 0 || j == 0 || i == w-1 || j == h-1){
map[i][j].type = BEDROCK; map[i][j].type = BEDROCK;
}else{ }else{
type=generate(i,j); type=generate(i,j);
@ -69,81 +91,122 @@ void create_map(t_pixel** map, t_team* teams, int w, int h){
} }
} }
} }
}
void init_generator(){
} }
void set_spawns(t_pixel** map, t_team* teams){ void set_spawns(t_pixel** map, t_team* teams){
int k,l; int i;
int x_rand,y_rand; int tier_w, tier_h;
for(k=0;k<NB_TEAMS;k++){ tier_w = width/6;
x_rand= rand()%width; tier_h = height/3;
y_rand= rand()%height;
spx[0] = (rand()%tier_w)+tier_w;
int error = 1; spy[0] = (rand()%tier_h)+tier_h;
while(error != 0){
error = 0; spx[1] = width-spx[0];
for (l=0;l<k;l++){ spy[1] = height-spy[0];
t_coord sp = teams[l].spawn;
if (distance_manhattan(x_rand,y_rand,sp.x,sp.y) < 50) for(i=0;i<2;i++){
error = 1; map[spx[i]][spy[i]].type=SPAWN;
} map[spx[i]][spy[i]].data=malloc(sizeof(int));
} memset(map[spx[i]][spy[i]].data,ORANGE,sizeof(int));
create_biome(spx[i],spy[i],VILLAGE);
map[x_rand][y_rand].type=SPAWN; teams[i].spawn.x = spx[i];
map[x_rand][y_rand].data=malloc(sizeof(int)); teams[i].spawn.y = spy[i];
memset(map[x_rand][y_rand].data,ORANGE,sizeof(int));
create_epicenter(x_rand,y_rand,GRASS);
teams[k].spawn.x = x_rand;
teams[k].spawn.y = y_rand;
} }
} }
void create_epicenter(int x, int y, int type){ void create_biome(int x, int y, int type){
t_epicenter *epicenter = malloc(sizeof(t_epicenter)); t_biome *biome = malloc(sizeof(t_biome));
epicenter->x=x; biome->x=x;
epicenter->y=y; biome->y=y;
epicenter->type = type; biome->type = type;
epicenter->power = (rand()%MAX_POWER)+1;
epicenter->radius = (rand()%100)+1;
l_epicenters[cpt_epicenter++]=*epicenter; switch(type){
case VILLAGE:
biome->power = (rand()%MAX_POWER)+1;
biome->radius = (rand()%(25-10))+10;
break;
case PLAINS:
case FOREST:
case MOUNTAINS:
default:
biome->power = (rand()%MAX_POWER)+1;
biome->radius = (rand()%(OFFSET_RADIUS))+MIN_RADIUS;
break;
}
l_biomes[cpt_biome++]=*biome;
} }
void create_epicenter_random(int type){ void create_biome_random(int type){
create_epicenter(rand()%width,rand()%height,type); int x,y;
do {
x=rand()%width;
y=rand()%height;
} while ((check_nears_biomes(x,y) != 0) || (check_nears_spawn(x,y) != 0)); //prevent biome superposition
create_biome(x,y,type);
}
int check_nears_biomes(int x, int y){
int i, c=0;
for(i=0;i<cpt_biome;i++){
if (in_radius(x,y,l_biomes[i]) != -1) c++;
}
return c;
}
int check_nears_spawn(int x, int y){
int i,c = 0;
for(i=0;i<2;i++)
if (distance_manhattan(x,y,spx[i],spy[i]) < 100) c++;
return c;
}
int in_radius(int x,int y,t_biome e){
int d = distance_manhattan(x,y,e.x,e.y);
return d < e.radius ? d : -1;
} }
int generate(int x, int y){ int generate(int x, int y){
int i, ratio, dist_to_epi, sum, val; int i, j;
int proba[5]; int proba[5];
t_epicenter epi; int sum, dist, ratio, val, seuil=0;
t_biome biome;
for(i=0;i<5;i++){
proba[i]=0;
}
for(i=0;i<size_epicenters;i++){
epi = l_epicenters[i];
dist_to_epi = distance_manhattan(x,y,epi.x, epi.y);
if (dist_to_epi < epi.radius){
ratio = (int) (epi.radius - dist_to_epi * 100) / epi.radius;
proba[epi.type-1] = proba[epi.type-1] + epi.power * ratio;
}
}
memset(&proba,0,sizeof(int)*5);
sum=0; sum=0;
for (i=0;i<5;i++){
sum += proba[i]; for(i=0;i<size_biomes;i++){
biome = l_biomes[i];
if ((dist=in_radius(x,y,biome)) != -1){
ratio=((biome.radius-dist)*100)/biome.radius;
sum += biome.power*ratio*100;
for(j=0;j<5;j++){
proba[j]+=(proba_table[biome.type][j])*(biome.power)*ratio;
}
}
} }
if (sum!=0){ if (sum!=0){
val = rand()%sum; val = rand()%sum;
int seuil = 0;
for (i=0;i<5;i++){ for (i=0;i<5;i++){
seuil += proba[i]; seuil += proba[i];
if(val < seuil) if(val < seuil)
return i+2; return i+1;
}
}else{
val = rand()%100;
if (val <95){
return GRASS;
}else{
return TREE;
} }
} }
return GRASS; return GRASS;
@ -152,7 +215,7 @@ int generate(int x, int y){
int distance_manhattan(int x1,int y1, int x2, int y2){ int distance_manhattan(int x1,int y1, int x2, int y2){
return absolute(x1-x2) + absolute(y1-y2); return absolute(x1-x2) + absolute(y1-y2);
} }
int absolute(int val){ int absolute(int val){
return val > 0 ? val : -val; return val > 0 ? val : -val;
} }

2
team.h
View File

@ -8,7 +8,7 @@ enum{
// Tile types // Tile types
enum{ enum{
BEDROCK, GRASS, ROCK, IRON_ORE, TREE, BERRIES, // nature BEDROCK, GRASS, TREE, BERRIES, ROCK, IRON_ORE, // nature
FOOD, WOOD, STONE, IRON, // resources FOOD, WOOD, STONE, IRON, // resources
CORPSE, DUDE, // humans CORPSE, DUDE, // humans
SPAWN, WALL, ROAD, SWORD, SIGN // buildings SPAWN, WALL, ROAD, SWORD, SIGN // buildings