summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Makefile9
-rw-r--r--platforms.cpp5
-rw-r--r--setup.cpp52
-rw-r--r--sim.cpp32
-rw-r--r--sim.hpp4
-rw-r--r--util.cpp22
7 files changed, 103 insertions, 25 deletions
diff --git a/.gitignore b/.gitignore
index 0d95ca3..e308a5c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
obj
-physics
+boxcatapult2d
tags
TAGS
*.swp
@@ -15,3 +15,5 @@ TAGS
SDL2
box2d
.vs*
+setups
+*.b2s
diff --git a/Makefile b/Makefile
index 1f6b4f2..ee952dd 100644
--- a/Makefile
+++ b/Makefile
@@ -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);
diff --git a/setup.cpp b/setup.cpp
index 19c6374..378076f 100644
--- a/setup.cpp
+++ b/setup.cpp
@@ -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;
+ }
+}
+
diff --git a/sim.cpp b/sim.cpp
index e8bce95..f16d7cd 100644
--- a/sim.cpp
+++ b/sim.cpp
@@ -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);
}
}
diff --git a/sim.hpp b/sim.hpp
index d55b2f4..1a93566 100644
--- a/sim.hpp
+++ b/sim.hpp
@@ -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
diff --git a/util.cpp b/util.cpp
index 1c3d9e4..99aed75 100644
--- a/util.cpp
+++ b/util.cpp
@@ -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