diff options
author | venomade <venomade@venomade.com> | 2025-02-27 17:25:46 +0000 |
---|---|---|
committer | venomade <venomade@venomade.com> | 2025-02-27 17:25:46 +0000 |
commit | 259c727658485ea00d6ef8617ecab579be871470 (patch) | |
tree | 5f548781584cf942b0c8a9101eed124da902c9ce /src/trainer/main.c |
Initial Commit
Diffstat (limited to 'src/trainer/main.c')
-rw-r--r-- | src/trainer/main.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/trainer/main.c b/src/trainer/main.c new file mode 100644 index 0000000..fa4d97f --- /dev/null +++ b/src/trainer/main.c @@ -0,0 +1,135 @@ +#include <assert.h> +#include <signal.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include <SDL2/SDL.h> + +#include "../game.h" +#include "logging.h" + +Game games[2] = {0}; + +// Tsoding is now a 3-Star Developer! +const char *tsoding_shift(int *argc, char ***argv) { + assert(*argc > 0); + const char* result = **argv; + *argc -= 1; + *argv += 1; + return result; +} + +void usage(FILE *stream) { + fprintf(stream, "Usage: ./gp_trainer [OPTIONS]\n"); + fprintf(stream, " --gen|g <NUMBER>\n"); + fprintf(stream, " Amount of generations (default: 100)\n"); + fprintf(stream, " --out|o <FILEPATH>\n"); + fprintf(stream, " Output filepath (default: out.bin)\n"); + fprintf(stream, " --plot|p\n"); + fprintf(stream, " Enable Gnuplot live reporting\n"); +} + +FILE* gnulog; +int gnuplot; +int current; +const char* output_filepath; + +void ctrlc(int signum) { + if (gnuplot) { + log_close_pipe(); + fclose(gnulog); + } + + dump_game(output_filepath, &games[current]); + exit(1); +} + +int main(int argc, char *argv[]) { + + signal(SIGINT, ctrlc); + + tsoding_shift(&argc, &argv); //Skip Program Name + + srand(time(NULL)); + int gen_count = 100; + output_filepath = "out.bin"; + gnuplot = 0; + + while (argc > 0) { + const char *flag = tsoding_shift(&argc, &argv); + + if (strcmp(flag, "--gen") == 0 || strcmp(flag, "-g") == 0) { + if (argc == 0) { + usage(stderr); + fprintf(stderr, "ERROR: no value provided for flag %s\n", flag); + exit(1); + } + const char *value = tsoding_shift(&argc, &argv); + gen_count = atoi(value); + + } else if (strcmp(flag, "--out") == 0 || strcmp(flag, "-o") == 0) { + if (argc == 0) { + usage(stderr); + fprintf(stderr, "ERROR: no value provided for flag %s\n", flag); + exit(1); + } + const char *value = tsoding_shift(&argc, &argv); + output_filepath = value; + + } else if (strcmp(flag, "--plot") == 0 || strcmp(flag, "-p") == 0) { + gnuplot = 1; + + } else if (strcmp(flag, "--help") == 0 || strcmp(flag, "-h") == 0) { + usage(stdout); + exit(0); + } else { + usage(stderr); + fprintf(stderr, "ERROR: unknown flag: %s\n", flag); + exit(1); + } + } + + if (gnuplot) { + gnulog = fopen("log.dat", "w"); + log_header(gnulog); + } + + current = 0; + + init_game(&games[current]); + + for (int i = 0; i < gen_count; ++i) { + fprintf(stderr, "Generation %d... ", i); + fflush(stderr); + + clock_t begin = clock(); + while (!is_everyone_dead(&games[current])) { + step_game(&games[current]); + } + + printf("%fs\n", (float)(clock() - begin) / (float) CLOCKS_PER_SEC); + fflush(stdout); + + if (gnuplot) { + log_generation(gnulog, i, &games[current]); + fflush(gnulog); + log_live_update(); + } + + int next = 1 - current; + make_next_generation(&games[current], &games[next]); + current = next; + } + + if (gnuplot) { + log_close_pipe(); + fclose(gnulog); + } + + dump_game(output_filepath, &games[current]); + + return 0; +} |