From e15f396ef55e190502ee7603c8e5e3d8f31ad3ea Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Tue, 8 Jan 2019 15:55:22 -0500 Subject: speed up sok_ctx_is_done() --- src/libsok/sok-ctx.c | 66 ++++++++++++++++++++++++++++++++++------------------ src/libsok/sok.h | 4 ++++ 2 files changed, 47 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/libsok/sok-ctx.c b/src/libsok/sok-ctx.c index d9985d7..d19682a 100644 --- a/src/libsok/sok-ctx.c +++ b/src/libsok/sok-ctx.c @@ -145,6 +145,40 @@ LEVEL_PARSER_CBS = { .on_junk = on_junk, }; +static size_t +pos_find( + const sok_pos_t pos, + const sok_pos_t * const set, + const size_t len +) { + for (size_t i = 0; i < len; i++) { + if (POINTS_EQUAL(pos, set[i])) { + return i; + } + } + + return len; +} + +static size_t +sok_ctx_count_goals_left( + sok_ctx_t * const ctx +) { + const size_t num_boxes = ctx->level.num_boxes; + size_t r = 0; + + for (size_t i = 0; i < ctx->level.num_goals; i++) { + r += pos_find( + ctx->level.goals[i], + ctx->boxes, + num_boxes + ) < num_boxes ? 0 : 1; + } + + return r; +} + + void sok_ctx_init(sok_ctx_t * const ctx, void *user_data) { memset(ctx, 0, sizeof(sok_ctx_t)); @@ -175,6 +209,9 @@ sok_ctx_set_level( ctx->home = ctx->level.home; memcpy(ctx->boxes, ctx->level.boxes, ctx->level.num_boxes * sizeof(sok_pos_t)); + // count number of goals left + ctx->num_goals_left = sok_ctx_count_goals_left(ctx); + // return success return true; } @@ -191,21 +228,6 @@ tile_is_floor( ); } -static size_t -pos_find( - const sok_pos_t pos, - const sok_pos_t * const set, - const size_t len -) { - for (size_t i = 0; i < len; i++) { - if (POINTS_EQUAL(pos, set[i])) { - return i; - } - } - - return len; -} - static bool tile_is_box( const sok_ctx_t * const ctx, @@ -274,10 +296,15 @@ sok_ctx_move_box( box_ofs = pos_find(old_pos, ctx->boxes, num_boxes); if (box_ofs < num_boxes) { + // update box and goal count ctx->boxes[box_ofs] = new_pos; + ctx->num_goals_left = sok_ctx_count_goals_left(ctx); + + // return success return true; } + // return failure return false; } @@ -285,14 +312,7 @@ bool sok_ctx_is_done( sok_ctx_t * const ctx ) { - for (size_t i = 0; i < ctx->level.num_goals; i++) { - if (!tile_is_box(ctx, ctx->level.goals[i])) { - return false; - } - } - - // return success - return true; + return ctx->num_goals_left == 0; } bool diff --git a/src/libsok/sok.h b/src/libsok/sok.h index 54e6c93..3e64afd 100644 --- a/src/libsok/sok.h +++ b/src/libsok/sok.h @@ -107,9 +107,13 @@ typedef struct { typedef struct { sok_level_t level; + // moves sok_move_t moves[SOK_CTX_MAX_MOVES]; size_t num_moves; + // number of open goals + size_t num_goals_left; + // player position sok_pos_t home; -- cgit v1.2.3