icfp12/ovm/task_main.h

92 lines
2.6 KiB
C

#ifndef OVM_TASK_MAIN_H
#define OVM_TASK_MAIN_H
#include "task.h"
#include "trace.h"
typedef void (*task_app_t)(task_t *task, gpointer userdata);
static inline void trace_simulate(task_t *task, gpointer userdata) {
trace_t *trace = (trace_t*) userdata;
trace_entry_t *te;
if (trace->pos > trace->data->len) {
fprintf(stderr, "Unexpected end of solution\n");
exit(11);
}
te = g_ptr_array_index(trace->data, trace->pos);
if (te->timestamp == task->timestamp) {
guint32 i;
trace->pos++;
for (i = 0; i < te->count; i++) {
task->in[te->data[i].addr] = te->data[i].value;
}
}
}
static inline gdouble task_run(task_t *task, task_app_t app, gpointer userdata, const gchar *tracefile) {
gboolean dotrace = (NULL != tracefile);
ovm_init();
if (dotrace) {
task_trace_start(task, tracefile);
}
for ( ; task->out[0] == 0.0 && task->timestamp < 3000000; task->timestamp++) {
app(task, userdata);
if (dotrace) task_trace_step(task);
ovm_step(task->scenario, task->in, task->out);
}
if (dotrace) task_trace_end(task);
return task->out[0];
}
static inline void task_main(int argc, char **argv, task_app_t app, task_app_t debug_app, gpointer userdata, guint default_scenario) {
GError *error = NULL;
GOptionContext *context;
gboolean res;
gdouble score;
task_t *task;
guint scenario = default_scenario;
const gchar *tracefile = NULL;
const gchar *simulate_file = NULL;
gboolean debug = FALSE;
GOptionEntry entries[] = {
{ "scenario", 's', 0, G_OPTION_ARG_INT, &scenario, "run scenario", "number" },
{ "simulate", 'm', 0, G_OPTION_ARG_FILENAME, &simulate_file, "Save trace in file", "PATH" },
{ "trace", 't', 0, G_OPTION_ARG_FILENAME, &tracefile, "Run input data (trace from another run)", "PATH" },
{ "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Show debug", NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
context = g_option_context_new("- ovm task runner");
g_option_context_add_main_entries(context, entries, NULL);
res = g_option_context_parse(context, &argc, &argv, &error);
g_option_context_free(context);
if (!res) {
g_printerr("failed to parse command line arguments: %s\n", error->message);
g_error_free(error);
exit(1);
}
if (simulate_file) {
trace_t *trace = trace_load(simulate_file);
userdata = trace;
app = trace_simulate;
scenario = trace->scenario;
fprintf(stderr, "Simulating solution: Team #%u, Scenario %u\n\n", (guint) trace->team, (guint) trace->scenario);
} else if (debug) {
app = debug_app;
}
task = task_new(scenario);
score = task_run(task, app, userdata, tracefile);
fprintf(stderr, "Finale score: %f\n", score);
task_free(task);
}
#endif