diff --git a/src/2048_engine.c b/src/2048_engine.c index 470db61..2a93fe8 100644 --- a/src/2048_engine.c +++ b/src/2048_engine.c @@ -131,20 +131,26 @@ void merge(struct gamestate *g, direction d, void (*callback)(struct gamestate * #undef merge_if_equal } -int moves_available(struct gamestate *g) +/* Return -1 on lose condition, 1 on win condition, 0 on + * haven't ended */ +int end_condition(struct gamestate *g) { + int ret = -1; + int x, y; for (x = 0; x < g->opts->grid_width; ++x) { for (y = 0; y < g->opts->grid_height; ++y) { + if (g->grid[x][y] >= g->opts->goal) + return 1; if (!g->grid[x][y] || ((x + 1 < g->opts->grid_width) && (g->grid[x][y] == g->grid[x+1][y])) || ((y + 1 < g->opts->grid_height) && (g->grid[x][y] == g->grid[x][y+1]))) - return 1; + ret = 0; } } - return 0; + return ret; } void random_block(struct gamestate *g) @@ -262,7 +268,7 @@ void reset_highscore(void) void print_usage(void) { printf( - "usage: 2048 [-cCrh] [-b ] [-s ]\n" + "usage: 2048 [-cCaArh] [-g ] [-b ] [-s ]\n" "\n" "controls\n" " hjkl movement keys\n" @@ -271,6 +277,7 @@ void print_usage(void) "options\n" " -s set the grid side lengths\n" " -b set the block spawn rate\n" + " -g set a new goal (default 2048)\n" " -a enable animations (default)\n" " -A disable animations\n" " -c enable color support\n" @@ -283,7 +290,7 @@ void print_usage(void) struct gameoptions* parse_options(struct gameoptions *opt, int argc, char **argv) { int c; - while ((c = getopt(argc, argv, "aArcChs:b:")) != -1) { + while ((c = getopt(argc, argv, "aArcChg:s:b:")) != -1) { switch (c) { case 'a': opt->animate = 1; @@ -297,6 +304,9 @@ struct gameoptions* parse_options(struct gameoptions *opt, int argc, char **argv case 'C': opt->enable_color = 0; break; + case 'g': + opt->goal = strtol(optarg, NULL, 10); + break; case 's':; /* Stick with square for now */ int optint = strtol(optarg, NULL, 10); diff --git a/src/2048_engine.h b/src/2048_engine.h index cb9b277..55ba72b 100644 --- a/src/2048_engine.h +++ b/src/2048_engine.h @@ -37,7 +37,7 @@ struct gamestate { struct gameoptions* parse_options(struct gameoptions*, int, char**); void gravitate(struct gamestate*, direction, void (*callback)(struct gamestate*)); void merge(struct gamestate*, direction, void (*callback)(struct gamestate*)); -int moves_available(struct gamestate *); +int end_condition(struct gamestate *); void random_block(struct gamestate *); int gamestate_tick(struct gamestate*, direction, void (*callback)(struct gamestate*)); void gamestate_clear(struct gamestate*);; diff --git a/src/2048_rewrite.c b/src/2048_rewrite.c index fc4eee2..80f3f60 100644 --- a/src/2048_rewrite.c +++ b/src/2048_rewrite.c @@ -99,15 +99,13 @@ void draw_screen(struct gamestate *g) #ifdef VT100_COMPATIBLE printf("\033[2J\033[H"); #endif - - printf("HISCORE: %ld |", g->score_high); - printf("| SCORE: %ld ", g->score); - if (g->score_last) printf("(+%ld)", g->score_last); - printf("\n"); + char *scr = g->score_last ? "SCORE: %d (+%d)\n" : "SCORE: %d\n"; + printf(scr, g->score, g->score_last); + printf("HISCR: %ld\n", g->score_high); // alter this grid_size + 1 to match abitrary grid size - iterate(g->opts->grid_width, printf("------")); - printf("-\n"); + iterate((g->print_width + 2) * g->opts->grid_width + 1, printf("-")); + printf("\n"); int x, y; for (y = 0; y < g->opts->grid_height; y++) { printf("|"); @@ -115,12 +113,13 @@ void draw_screen(struct gamestate *g) if (g->grid[x][y]) printf("%*ld |", g->print_width, g->grid[x][y]); else - printf(" |"); + printf("%*s |", g->print_width, ""); } printf("\n"); } - iterate(g->opts->grid_width, printf("------")); - printf("-\n\n"); + + iterate((g->print_width + 2) * g->opts->grid_width + 1, printf("-")); + printf("\n\n"); } #endif /* CURSES */ @@ -141,6 +140,13 @@ int main(int argc, char **argv) while (1) { draw_screen(g); + int e; + if ((e = end_condition(g))) { + drawstate_clear(); + printf(e > 0 ? "You win\n" : "You lose\n"); + goto endloop; + } + /* abstract getting keypress */ int ch; do { @@ -148,11 +154,6 @@ int main(int argc, char **argv) if (ch == 'q') { goto endloop; } } while (strchr("hjkl", ch) == NULL); - if (!moves_available(g)) { - printf("You lose\n"); - break; - } - gamestate_tick(g, ch, g->opts->animate ? ddraw : NULL); } endloop: