aboutsummaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorjacopo grandi <jak.sk8@hotmail.it>2021-03-04 12:40:52 +0100
committerjacopo grandi <jak.sk8@hotmail.it>2021-03-04 12:40:52 +0100
commit02e55b0647eb5c631e7d7669a13fd0d47ec26c15 (patch)
tree35a3017c62aeeec101af8ac43d0b5a22691c637e /gst
parentb0396bf70211adaad17ae0e2cf6e851b1467ae00 (diff)
morning fixes and bruteforce unit generation
Diffstat (limited to 'gst')
-rw-r--r--gst/generate.c70
-rw-r--r--gst/generate.h11
-rw-r--r--gst/info.c40
-rw-r--r--gst/info.h4
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
diff --git a/gst/info.c b/gst/info.c
index 91a26a2..cb1d9f1 100644
--- a/gst/info.c
+++ b/gst/info.c
@@ -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);
}
+
diff --git a/gst/info.h b/gst/info.h
index e0d784a..4f04a34 100644
--- a/gst/info.h
+++ b/gst/info.h
@@ -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"