diff options
Diffstat (limited to 'src/core/sok-ctx.c')
-rw-r--r-- | src/core/sok-ctx.c | 163 |
1 files changed, 77 insertions, 86 deletions
diff --git a/src/core/sok-ctx.c b/src/core/sok-ctx.c index e278af1..036bf66 100644 --- a/src/core/sok-ctx.c +++ b/src/core/sok-ctx.c @@ -183,6 +183,52 @@ pos_find( return len; } +static bool +tile_is_goal( + const sok_ctx_t * const ctx, + const sok_pos_t pos +) { + const size_t num_goals = ctx->level.num_goals; + return pos_find(pos, ctx->level.goals, num_goals) < num_goals; +} + +static bool +tile_is_corner( + const sok_ctx_t * const ctx, + const sok_pos_t pos +) { + // right + const bool r = ctx_is_wall(ctx, (sok_pos_t) { + .x = pos.x + 1, + .y = pos.y, + }); + + // top + const bool t = ctx_is_wall(ctx, (sok_pos_t) { + .x = pos.x, + .y = pos.y - 1, + }); + + // left + const bool l = ctx_is_wall(ctx, (sok_pos_t) { + .x = pos.x - 1, + .y = pos.y, + }); + + // bottom + const bool b = ctx_is_wall(ctx, (sok_pos_t) { + .x = pos.x, + .y = pos.y + 1, + }); + + return ( + (t && r) || // top-right + (t && l) || // top-left + (b && l) || // bottom-left + (b && r) // bottom-right + ); +} + static size_t sok_ctx_count_goals_left( sok_ctx_t * const ctx @@ -201,73 +247,29 @@ sok_ctx_count_goals_left( return r; } -/* - * static bool - * sok_ctx_has_corner_boxes( - * const sok_ctx_t * const ctx - * ) { - * for (size_t i = 0; i < ctx->level.num_boxes; i++) { - * // right - * const bool r = ctx_is_wall(ctx, (sok_pos_t) { - * .x = ctx->boxes[i].x + 1, - * .y = ctx->boxes[i].y, - * }); - * - * // top-right - * const bool tr = ctx_is_wall(ctx, (sok_pos_t) { - * .x = ctx->boxes[i].x + 1, - * .y = ctx->boxes[i].y - 1, - * }); - * - * // top - * const bool t = ctx_is_wall(ctx, (sok_pos_t) { - * .x = ctx->boxes[i].x, - * .y = ctx->boxes[i].y - 1, - * }); - * - * // top-left - * const bool tl = ctx_is_wall(ctx, (sok_pos_t) { - * .x = ctx->boxes[i].x - 1, - * .y = ctx->boxes[i].y - 1, - * }); - * - * // left - * const bool l = ctx_is_wall(ctx, (sok_pos_t) { - * .x = ctx->boxes[i].x - 1, - * .y = ctx->boxes[i].y, - * }); - * - * // bottom-left - * const bool bl = ctx_is_wall(ctx, (sok_pos_t) { - * .x = ctx->boxes[i].x - 1, - * .y = ctx->boxes[i].y + 1, - * }); - * - * // bottom - * const bool b = ctx_is_wall(ctx, (sok_pos_t) { - * .x = ctx->boxes[i].x, - * .y = ctx->boxes[i].y + 1, - * }); - * - * const bool br = ctx_is_wall(ctx, (sok_pos_t) { - * .x = ctx->boxes[i].x + 1, - * .y = ctx->boxes[i].y + 1, - * }); - * - * if ( - * (r && tr && t) || // top-right - * (t && tl && l) || // top-left - * (l && bl && b) || // bottom-left - * (b && br && r) // bottom-right - * ) { - * // return - * return true; - * } - * } - * - * return false; - * } - */ +static bool +sok_ctx_box_is_stuck( + const sok_ctx_t * const ctx, + const size_t i +) { + return ( + !tile_is_goal(ctx, ctx->boxes[i]) && + tile_is_corner(ctx, ctx->boxes[i]) + ); +} + +static bool +sok_ctx_has_stuck_boxes( + const sok_ctx_t * const ctx +) { + for (size_t i = 0; i < ctx->level.num_boxes; i++) { + if (sok_ctx_box_is_stuck(ctx, i)) { + return true; + } + } + + return false; +} void sok_ctx_init(sok_ctx_t * const ctx, void *user_data) { @@ -301,7 +303,7 @@ sok_ctx_set_level( // count number of goals left and check whether there are ctx->num_goals_left = sok_ctx_count_goals_left(ctx); - // ctx->is_lost = sok_ctx_is_lost(ctx); + ctx->is_lost = sok_ctx_has_stuck_boxes(ctx); // return success return true; @@ -329,15 +331,6 @@ tile_is_box( } static bool -tile_is_goal( - const sok_ctx_t * const ctx, - const sok_pos_t pos -) { - const size_t num_goals = ctx->level.num_goals; - return pos_find(pos, ctx->level.goals, num_goals) < num_goals; -} - -static bool sok_ctx_push_move( sok_ctx_t * const ctx, const sok_dir_t dir, @@ -390,7 +383,7 @@ sok_ctx_move_box( // update box and goal count ctx->boxes[box_ofs] = new_pos; ctx->num_goals_left = sok_ctx_count_goals_left(ctx); - // ctx->is_lost = sok_ctx_has_corner_boxes(ctx); + ctx->is_lost = sok_ctx_has_stuck_boxes(ctx); // return success return true; @@ -407,14 +400,12 @@ sok_ctx_is_done( return ctx->num_goals_left == 0; } -/* - * bool - * sok_ctx_is_lost( - * const sok_ctx_t * const ctx - * ) { - * return ctx->is_lost; - * } - */ +bool +sok_ctx_is_lost( + const sok_ctx_t * const ctx +) { + return ctx->is_lost; +} bool sok_ctx_move( |