diff options
author | jacopo grandi <jak.sk8@hotmail.it> | 2021-03-04 12:40:52 +0100 |
---|---|---|
committer | jacopo grandi <jak.sk8@hotmail.it> | 2021-03-04 12:40:52 +0100 |
commit | 02e55b0647eb5c631e7d7669a13fd0d47ec26c15 (patch) | |
tree | 35a3017c62aeeec101af8ac43d0b5a22691c637e /gst | |
parent | b0396bf70211adaad17ae0e2cf6e851b1467ae00 (diff) |
morning fixes and bruteforce unit generation
Diffstat (limited to 'gst')
-rw-r--r-- | gst/generate.c | 70 | ||||
-rw-r--r-- | gst/generate.h | 11 | ||||
-rw-r--r-- | gst/info.c | 40 | ||||
-rw-r--r-- | gst/info.h | 4 |
4 files changed, 122 insertions, 3 deletions
diff --git a/gst/generate.c b/gst/generate.c new file mode 100644 index 0000000..1d8a340 --- /dev/null +++ b/gst/generate.c @@ -0,0 +1,70 @@ +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <string.h> + +#include "generate.h" + +void generate_init () { + srand(time(NULL)); +} + +float calc_unit_cost (infos *info, info_unit *u) { + stats_unit base; + stats_unit_compute(info, u, &base); + return stats_compute_cost(&info->cost_weights, &base); +} + +int accept_cond (infos *info, info_unit *u, float cost_max) { + stats_unit base; + stats_unit_compute(info, u, &base); + float cost = stats_compute_cost(&info->cost_weights, &base); + if (base.frame.weight > base.frame.weight_max) return 0; + if (cost > cost_max) return 0; + return 1; +} + +// generates randomly a valid unit +void gen_unit_attempt (infos *info, info_unit *u, float cost_max) { + info_unit_init(u); + stats_unit base; + u->chassis = rand() % info->statslen[STATS_CHASSIS]; + u->battery = rand() % info->statslen[STATS_BATTERY]; + u->brain = rand() % info->statslen[STATS_BRAIN]; + stats_unit_compute(info, u, &base); + for (int i=0; i<base.frame.slot_weapon; i++) { + u->weapons[i] = rand() % info->statslen[STATS_WEAPONS]; + if (!accept_cond(info, u, cost_max)) { u->weapons[i] = -1; return; } + } + for (int i=0; i<base.frame.slot_armor; i++) { + u->armor[i] = rand() % info->statslen[STATS_ARMOR]; + if (!accept_cond(info, u, cost_max)) { u->armor[i] = -1; return; } + } + for (int i=0; i<base.frame.slot_aug; i++) { + u->augs[i] = rand() % info->statslen[STATS_AUGS]; + if (!accept_cond(info, u, cost_max)) { u->augs[i] = -1; return; } + } +} + +// selects the max cost generated unit +int generate_unit (infos *info, info_unit *u, float cost_max) { + info_unit cand = *u; + info_unit candmax; info_unit_init(&candmax); + float cost; + for (int i=0; i<GENERATE_UNIT_MAX_ATTEMPTS; i++) { + cand = *u; + gen_unit_attempt(info, &cand, cost_max); + if (accept_cond(info, &cand, cost_max)) { + if (calc_unit_cost(info, &cand) + > calc_unit_cost(info, &candmax)) { + candmax = cand; + printf("found: %f\n", calc_unit_cost(info, &cand)); + } + } + } + if (candmax.chassis != -1) { + *u = candmax; + return 0; + } + else return 1; +}
\ No newline at end of file diff --git a/gst/generate.h b/gst/generate.h new file mode 100644 index 0000000..a4da2d6 --- /dev/null +++ b/gst/generate.h @@ -0,0 +1,11 @@ +#ifndef GENERATE_H +#define GENERATE_H + +#include "info.h" + +#define GENERATE_UNIT_MAX_ATTEMPTS 48637 + +void generate_init (); +int generate_unit (infos *info, info_unit *u, float cost); + +#endif
\ No newline at end of file @@ -40,6 +40,23 @@ void info_unit_init (info_unit *u) { for(int i=0; i<16; u->augs[i] = -1, i++); for(int i=0; i<34; u->levels[i] = 0, i++); } + +void info_unit_printf (info_unit *u) { + printf("name: %s\n", u->name); + printf("chassis: %d; ", u->chassis); + printf("battery: %d; ", u->battery); + printf("brain: %d\n", u->brain); + printf("weapon: "); + for(int i=0; i<8; printf("%d, ", u->weapons[i]), i++); + printf("\narmor: "); + for(int i=0; i<8; printf("%d, ", u->armor[i]), i++); + printf("\naugs: "); + for(int i=0; i<16; printf("%d, ", u->augs[i]), i++); + printf("\nlevels: "); + for(int i=0; i<34; printf("%d, ", u->levels[i]), i++); + printf("\n"); +} + /* float info_unit_get_cost (infos *info, info_unit *u) { // see design/notes.txt:implement cost function @@ -273,8 +290,9 @@ void stats_comp_printf (infos *info, stats_comp *comp) { void stats_unit_printf (infos *info, stats_unit *u) { char arr[32][64]; { int n = stats_frame_sprintf (info, &u->frame, arr); printf_arr(arr, n); } - LOOP(8) { + LOOP(u->weaponlen) { int n = stats_weapon_sprintf(info, u->weapon +z, arr); + if (n>0) printf(" weapon: \n"); printf_arr(arr, n); } } @@ -444,6 +462,8 @@ float stats_unit_fold (stats_unit *base, float (*f)(float, float)) { return v; } +float f_clamp_positive (float x) { if (x < 0) x = 0; } + // compute all necessary components stats of u into base void stats_unit_compute (infos *info, info_unit *u, stats_unit *base) { stats_unit_init(base); @@ -467,7 +487,7 @@ void stats_unit_compute (infos *info, info_unit *u, stats_unit *base) { }; for (int i=0; i<8; i++) { - if (u->armor[i] != -1) { + if (u->armor[i] != -1 && i<base->frame.slot_armor) { stats_comp *comp = &info->stats[STATS_ARMOR][u->armor[i]]; int lvl = u->levels[LEVEL_ARMOR+i]; stats_unit_comp_sum(base, &perc, comp, lvl); @@ -475,7 +495,7 @@ void stats_unit_compute (infos *info, info_unit *u, stats_unit *base) { } for (int i=0; i<16; i++) { - if (u->augs[i] != -1) { + if (u->augs[i] != -1 && i<base->frame.slot_aug) { stats_comp *comp = &info->stats[STATS_AUGS][u->augs[i]]; int lvl = u->levels[LEVEL_AUGS+i]; stats_unit_comp_sum(base, &perc, comp, lvl); @@ -497,6 +517,10 @@ void stats_unit_compute (infos *info, info_unit *u, stats_unit *base) { base->weaponlen = wn; stats_unit_map(&perc, f_perc_norm); + for (int w=0; w<wn; w++) { + stats_weapon_map(perc.weapon +w, f_clamp_positive); + } + stats_unit_mul(base, &perc); } @@ -744,6 +768,15 @@ void info_template_add (infos *info, info_unit *temp) { } } +void info_template_rm (infos *info, int n) { + for (int i=0; i<info->templateslen-1; i++) { + if (i >= n) { + info->templates[i] = info->templates[i+1]; + } + } + info->templateslen--; +} + void info_load_army(struct army_ *ar, char *filename) { strcpy(ar->name, filename); char buf[1024*64]; @@ -800,3 +833,4 @@ void info_army_remove (char name[]) { char pathname[64]; sprintf(pathname, "army/%s.txt", name); remove(pathname); } + @@ -90,9 +90,12 @@ typedef struct { } infos; void info_unit_init (info_unit *u); +void info_unit_printf (info_unit *u); int stats_frame_sprintf (infos *info, stats_frame *frame, char arr[][64]); int stats_weapon_sprintf (infos *info, stats_weapon *weap, char arr[][64]); +void stats_unit_printf (infos *info, stats_unit *u); + void stats_unit_compute (infos *info, info_unit *u, stats_unit *base); float stats_compute_damage (stats_weapon *weapon, stats_frame *frame, @@ -104,6 +107,7 @@ void info_load (infos *info); void info_save_templates (infos *info, char *filename); void info_template_add (infos *info, info_unit *temp); +void info_template_rm (infos *info, int n); #include "units.h" |