diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | platforms.cpp | 5 | ||||
-rw-r--r-- | setup.cpp | 52 | ||||
-rw-r--r-- | sim.cpp | 32 | ||||
-rw-r--r-- | sim.hpp | 4 | ||||
-rw-r--r-- | util.cpp | 22 |
7 files changed, 103 insertions, 25 deletions
@@ -1,5 +1,5 @@ obj -physics +boxcatapult2d tags TAGS *.swp @@ -15,3 +15,5 @@ TAGS SDL2 box2d .vs* +setups +*.b2s @@ -1,12 +1,15 @@ WARNINGS=-Wall -Wextra -Wshadow -Wconversion -Wpedantic -pedantic -std=gnu++11 -Wno-unused-function -Wimplicit-fallthrough LIBS=-ldl `pkg-config --libs --cflags sdl2 gl` -l:libbox2d.a DEBUG_CFLAGS=$(CFLAGS) $(WARNINGS) $(LIBS) -DDEBUG -O0 -g3 -obj/debug: physics obj/sim.so obj - touch obj/debug -physics: *.[ch]* +RELEASE_CFLAGS=$(CFLAGS) $(WARNINGS) $(LIBS) -O3 -s +boxcatapult2d: *.[ch]* $(CXX) main.cpp -o $@ $(DEBUG_CFLAGS) +release: *.[ch]* obj + $(CXX) main.cpp -o boxcatapult2d $(RELEASE_CFLAGS) # obj/sim.so: *.[ch]* obj # $(CXX) sim.cpp -fPIC -shared -o $@ $(DEBUG_CFLAGS) # touch obj/sim.so_changed obj: mkdir -p obj +clean: + rm boxcatapult2d diff --git a/platforms.cpp b/platforms.cpp index e52b302..8658aae 100644 --- a/platforms.cpp +++ b/platforms.cpp @@ -96,7 +96,7 @@ static void platforms_render(State *state, Platform *platforms, u32 nplatforms) float theta2 = theta1 + angle; float dtheta = 0.03f * sgnf(angle); float radius = platform->radius; - v2 last_point; + v2 last_point = {}; for (float theta = theta1; angle > 0 ? (theta < theta2) : (theta > theta2); theta += dtheta) { v2 point = b2_to_gl(state, v2_add(platform->center, v2_polar(radius, theta))); if (theta != theta1) { @@ -154,6 +154,7 @@ static void platforms_render(State *state, Platform *platforms, u32 nplatforms) // sets platform->body to a new Box2D body. static void platform_make_body(State *state, Platform *platform, u32 index) { b2World *world = state->world; + assert(!platform->body); float radius = platform->radius; @@ -272,7 +273,7 @@ static void platform_write_to_file(Platform const *p, FILE *fp) { } } -static void platform_read_from_file(Platform const *p, FILE *fp) { +static void platform_read_from_file(Platform *p, FILE *fp) { p->radius = fread_float(fp); p->start_angle = fread_float(fp); p->color = fread_u32(fp); @@ -13,7 +13,7 @@ static v2 setup_rand_point(void) { #define PLATFORM_MOVE_CHANCE 0.5f // chance that the platform will be a moving one #define PLATFORM_ROTATE_CHANCE 0.5f // chance that the platform will be a rotating one (platforms can be moving and rotating) -static void setup_random(State *state, Setup *setup, float cost_allowed) { +static void setup_random(Setup *setup, float cost_allowed) { // how much "money" we have to spend float cost_left = cost_allowed; @@ -54,16 +54,28 @@ static void setup_random(State *state, Setup *setup, float cost_allowed) { cost_left -= fabsf(platform->rotate_speed) * PLATFORM_ROTATE_SPEED_COST; } } - - platform_make_body(state, platform, setup->nplatforms - 1); } assert(cost_left >= 0); } // make this setup the active one static void setup_use(State *state, Setup *setup) { + b2World *world = state->world; + // get rid of old platform bodies + for (u32 i = 0; i < state->nplatforms; ++i) { + Platform *p = &state->platforms[i]; + if (p->body) + world->DestroyBody(p->body); + } memcpy(state->platforms, setup->platforms, setup->nplatforms * sizeof(Platform)); state->nplatforms = setup->nplatforms; + // create new bodies + for (u32 i = 0; i < state->nplatforms; ++i) { + Platform *p = &state->platforms[i]; + p->body = NULL; + platform_make_body(state, p, i); + } + assert((u32)world->GetBodyCount() == state->nplatforms + 2); // platforms + 2 walls } static void setup_reset(State *state) { @@ -129,10 +141,34 @@ static float setup_score(State *state, Setup *setup) { return setup->score; } -static void setup_write_to_file(Setup *setup, FILE *fp) { - u32 nplatforms = setup->nplatforms; - fwrite_u32(fp, nplatforms); - for (u32 i = 0; i < nplatforms; ++i) { - platform_write_to_file(&setup->platforms[i], fp); +static bool setup_write_to_file(Setup const *setup, char const *filename) { + FILE *fp = fopen(filename, "wb"); + if (fp) { + u32 nplatforms = setup->nplatforms; + fwrite_u32(fp, nplatforms); + for (u32 i = 0; i < nplatforms; ++i) { + platform_write_to_file(&setup->platforms[i], fp); + } + fclose(fp); + return true; + } else { + logln("Couldn't write setup to %s.", filename); + return false; } } + +static bool setup_read_from_file(Setup *setup, char const *filename) { + FILE *fp = fopen(filename, "rb"); + if (fp) { + u32 nplatforms = setup->nplatforms = fread_u32(fp); + for (u32 i = 0; i < nplatforms; ++i) { + platform_read_from_file(&setup->platforms[i], fp); + } + fclose(fp); + return true; + } else { + logln("Couldn't read setup from %s.", filename); + return false; + } +} + @@ -250,6 +250,8 @@ void sim_frame(Frame *frame) { #undef optional_gl_proc #undef required_gl_proc + make_directory("setups"); + shaders_load(state); state->platform_thickness = 0.05f; @@ -280,10 +282,33 @@ void sim_frame(Frame *frame) { left_wall_body->CreateFixture(&left_wall_shape, 0); - for (size_t i = 0; i < arr_count(state->generation); ++i) { - setup_random(state, &state->generation[i], 50); - printf("%f \n",setup_score(state, &state->generation[i])); + #if 1 + Setup *best_setup = &state->generation[0]; + for (size_t i = 0; i < GENERATION_SIZE; ++i) { + Setup *setup = &state->generation[i]; + setup_random(setup, 50); + char filename[64] = {0}; + snprintf(filename, sizeof filename-1, "setups/%03zu.b2s", i); + setup_write_to_file(setup, filename); + setup_score(state, setup); + logln("Setup %zu: %.2f m", i, setup->score); + if (setup->score > best_setup->score) { + best_setup = setup; + } } + logln("Best: setup %ld", (long)(best_setup - state->generation)); + setup_use(state, best_setup); + assert(state->nplatforms == best_setup->nplatforms); + #endif + + #if 0 + Setup *setup = &state->generation[0]; + //setup_random(state, setup, 50); + //setup_write_to_file(setup, "setups/test.b2s"); + setup_read_from_file(setup, "setups/test.b2s"); + setup_use(state, setup); + #endif + { Platform *b = &state->platform_building; @@ -488,6 +513,7 @@ void sim_frame(Frame *frame) { if (keys_pressed[KEY_SPACE]) { state->building = false; state->simulating = true; + setup_reset(state); } } @@ -126,7 +126,7 @@ typedef struct { } ShaderBall; typedef struct { - b2Body *body; + b2Body *body; // Box2D body for platform -- created when setup_use is called (for setups), or when the platform is manually built v2 center; @@ -218,7 +218,7 @@ typedef struct { u32 nplatforms; Platform platforms[MAX_PLATFORMS]; -#define GENERATION_SIZE 100 +#define GENERATION_SIZE 1000 Setup generation[GENERATION_SIZE]; u32 tmp_mem_used; // this is not measured in bytes, but in MaxAligns @@ -173,7 +173,7 @@ static int qsort_stricmp(const void *av, const void *bv) { #endif } -static void fwrite_bool(FILE *fp, bool x) { +static void fwrite_u8(FILE *fp, u8 x) { fwrite(&x, sizeof x, 1, fp); } @@ -189,27 +189,37 @@ static void fwrite_v2(FILE *fp, v2 v) { fwrite(&v, sizeof v, 1, fp); } -static void fread_bool(FILE *fp) { - bool x; +static u8 fread_u8(FILE *fp) { + u8 x; fread(&x, sizeof x, 1, fp); return x; } -static void fread_u32(FILE *fp) { +static u32 fread_u32(FILE *fp) { u32 x; fread(&x, sizeof x, 1, fp); return x; } -static void fread_float(FILE *fp) { +static float fread_float(FILE *fp) { float x; fread(&x, sizeof x, 1, fp); return x; } -static void fread_v2(FILE *fp) { +static v2 fread_v2(FILE *fp) { v2 v; fread(&v, sizeof v, 1, fp); return v; } +#if _WIN32 +static void make_directory(char const *name) { + _mkdir(name); +} +#else +#include <sys/stat.h> +static void make_directory(char const *name) { + mkdir(name, 0755); +} +#endif |