Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions config/ls20.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[base]
env_name = ls20

[env]
fps = 30
reset_enabled = 0

[vec]
total_agents = 1024
num_buffers = 2
num_threads = 4

[policy]
hidden_size = 256
num_layers = 2

[train]
total_timesteps = 100_000_000
gamma = 0.99
minibatch_size = 16384
horizon = 128
use_rnn = 1
25 changes: 25 additions & 0 deletions ocean/ls20/binding.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "ls20.h"

#define OBS_SIZE LS20_OBS_SIZE
#define NUM_ATNS 1
#define ACT_SIZES {LS20_ACTION_COUNT}
#define OBS_TENSOR_T ByteTensor
#define MY_ACTION_MASK LS20_ACTION_COUNT

#define Env Ls20
#include "vecenv.h"

void my_init(Env* env, Dict* kwargs) {
env->num_agents = 1;
DictItem* fps = dict_get_unsafe(kwargs, "fps");
env->fps = fps == NULL ? LS20_DEFAULT_FPS : (int)fps->value;
DictItem* reset_enabled = dict_get_unsafe(kwargs, "reset_enabled");
env->reset_enabled = reset_enabled != NULL && reset_enabled->value != 0.0;
}

void my_log(Log* log, Dict* out) {
dict_set(out, "perf", log->perf);
dict_set(out, "score", log->score);
dict_set(out, "episode_return", log->episode_return);
dict_set(out, "episode_length", log->episode_length);
}
84 changes: 84 additions & 0 deletions ocean/ls20/ls20.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include "ls20.h"

static const char* WINNING_LEVELS[LS20_LEVEL_COUNT] = {
"LLLUUUURRRUUU",
"URUUUUURRDRDDDDDDDLLRURLRUUUUUUULLLLLLDLDDDDD",
"UUUUUUUULDDDDDDDDUUULLUUURRRDDRRRRUUULRLDRDDDDDDD",
"LLLDDDLLLRRUUULLUDDUDUDUDUDUDUDUULLUDDULLUUUDLULUUUURURUULLL",
"ULUULDLULRLRLRUDLRLDDLLLULRLRDLDDDDDRDURRULRDDDRRRRRRDUU",
("UUDULRRRRUUULLRRDDDDLLLURRRUUUUUUUDDRRUURDDDUUULUDLLLRLRLLLL"
"DDDRRRDULDLLUUUUUUURLRRRRLLLULDDDDDDDRRDURRRRUUUUURRUURDDDDD"),
"LLDDDDDRLRLRRLDURLRLRLRLDUULUURRRRUDRRUURRUUUUUURDLDDDDDLLUDDDD",
};

static int action_from_char(char action) {
if (action == 'U') return ACTION1;
if (action == 'D') return ACTION2;
if (action == 'L') return ACTION3;
assert(action == 'R');
return ACTION4;
}

static void demo(void) {
unsigned char observations[LS20_OBS_SIZE] = {0};
float action = 0.0f;
float reward = 0.0f;
float terminal = 0.0f;
Ls20 env = {
.num_agents = 1,
.fps = LS20_DEFAULT_FPS,
.observations = observations,
.actions = &action,
.rewards = &reward,
.terminals = &terminal,
};
c_reset(&env);
c_render(&env);
for (int level = 0; level < LS20_LEVEL_COUNT; level++) {
for (const char* step = WINNING_LEVELS[level]; *step; step++) {
action = (float)action_from_char(*step);
c_step(&env);
c_render(&env);
}
}
c_close(&env);
}

static void play(void) {
unsigned char observations[LS20_OBS_SIZE] = {0};
float action = 0.0f;
float reward = 0.0f;
float terminal = 0.0f;
Ls20 env = {
.num_agents = 1,
.observations = observations,
.actions = &action,
.rewards = &reward,
.terminals = &terminal,
};
c_reset(&env);
c_render(&env);
while (!WindowShouldClose()) {
int next_action = -1;
if (IsKeyPressed(KEY_UP) || IsKeyPressed(KEY_W)) next_action = ACTION1;
if (IsKeyPressed(KEY_DOWN) || IsKeyPressed(KEY_S)) next_action = ACTION2;
if (IsKeyPressed(KEY_LEFT) || IsKeyPressed(KEY_A)) next_action = ACTION3;
if (IsKeyPressed(KEY_RIGHT) || IsKeyPressed(KEY_D)) next_action = ACTION4;
if (IsKeyPressed(KEY_R)) next_action = RESET;
if (next_action >= 0) {
action = (float)next_action;
c_step(&env);
}
c_render(&env);
}
c_close(&env);
}

int main(int argc, char** argv) {
if (argc == 2 && strcmp(argv[1], "--demo") == 0) {
demo();
return 0;
}
play();
return 0;
}
Loading