From a004ddf64ec6cfbec7ae1cee1805426baf7a75bf Mon Sep 17 00:00:00 2001 From: girst Date: Fri, 4 Jan 2019 18:30:07 +0100 Subject: [PATCH] implement getopt, restarting, help --- sol.c | 66 +++++++++++++++++++++++++++++++++++++++++++++-------------- sol.h | 32 ++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 16 deletions(-) diff --git a/sol.c b/sol.c index 230bee3..83c7001 100644 --- a/sol.c +++ b/sol.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -87,18 +88,56 @@ int (*action[NUM_PLACES][10])(int,int,int) = { // }}} int main(int argc, char** argv) { - (void) argc;(void) argv; + /* opinionated defaults: */ op.s = &unicode_large_color; #ifdef SPIDER - op.m = MEDIUM; //TODO: make configurable - op.m = EASY; + op.m = MEDIUM; #endif + + int optget; + opterr = 0; /* don't print message on unrecognized option */ + while ((optget = getopt (argc, argv, "+:hd:s:")) != -1) { + switch (optget) { +#ifdef SPIDER + case 'd': /* difficulty */ + if(!strcmp(optarg, "easy")) op.m = EASY; + if(!strcmp(optarg, "medium")) op.m = MEDIUM; + if(!strcmp(optarg, "hard")) op.m = NORMAL; + break; +#endif + case 's': /* scheme */ + if(!strcmp(optarg,"color")) op.s = &unicode_large_color; + if(!strcmp(optarg, "mono")) op.s = &unicode_large_mono; + if(!strcmp(optarg,"small")) op.s = &unicode_small_mono; + break; + case 'h': + case ':': //missing optarg + default: + fprintf (stderr, SHORTHELP LONGHELP KEYHELP, argv[0]); + return optget != 'h'; + } + } + + //TODO: signal setup, atexit() +newgame: screen_setup(1); - sol(); //TODO: restart, etc. - screen_setup(0); + + switch(sol()) { + case GAME_NEW: goto newgame; + case GAME_WON: + print_table(NO_HI, NO_HI); + win_anim(); + if (getchar()=='q') goto quit; + goto newgame; + case GAME_QUIT: goto quit; + } + +quit: + screen_setup(0); //TODO: handled by atexit() in the future + return 0; } -void sol(void) { +int sol(void) { deal(); int from, to, opt; @@ -109,17 +148,12 @@ void sol(void) { switch (action[from][to](from,to,opt)) { case OK: break; case ERR: visbell(); break; - case WON: - print_table(NO_HI, NO_HI); - win_anim(); - getchar(); /* consume char left by win_anim() */ - return; + case WON: return GAME_WON; } break; - case CMD_INVAL: - visbell(); - break; - case CMD_QUIT: return; + case CMD_INVAL: visbell(); break; + case CMD_NEW: return GAME_NEW; + case CMD_QUIT: return GAME_QUIT; } print_table(NO_HI, NO_HI); } @@ -460,6 +494,8 @@ from_l: print_table(&active, &inactive); case 'j': cursor_down (&active); goto from_l; case 'k': cursor_up (&active); goto from_l; case 'l': cursor_right(&active); goto from_l; + //TODO: first/last tableu (H/L? 0/^/$?) + //TODO: real cursor keys case ' ': /* continue with second cursor */ *from = active.pile; if (*from == STOCK) { diff --git a/sol.h b/sol.h index 50bbedf..2a787da 100644 --- a/sol.h +++ b/sol.h @@ -1,6 +1,31 @@ #ifndef __SOL_H__ #define __SOL_H__ +#define SHORTHELP "%s [OPTIONS]\n" +#ifdef KLONDIKE +#define LONGHELP_SPECIFIC "" +#define DIRECT_ADDR_KEYHELP \ + " 1 .. 7: directly address tableu\n" \ + " 8,9,0 : directly address stock/waste/foundation\n" +#elif defined SPIDER +#define LONGHELP_SPECIFIC \ + " -d(ifficulty) (eady|medium|hard)\n" +#define DIRECT_ADDR_KEYHELP \ + " 1 .. 0: directly address tableu\n" +#endif +#define LONGHELP \ + "OPTIONS:\n" \ + LONGHELP_SPECIFIC \ + " -s(cheme) (color|mono|small)\n" \ + " -h(elp)\n" \ + "\n" +#define KEYHELP \ + "Keybindings:\n" \ + " hjkl : move cursor\n" \ + " space : select at cursor\n" \ + " return: draw from stock\n" \ + DIRECT_ADDR_KEYHELP + #define DECK_SIZE 52 enum cards { NO_CARD, @@ -53,6 +78,11 @@ enum action_return { ERR, /*invalid move*/ WON, /*game won*/ }; +enum game_states { + GAME_NEW, + GAME_WON, + GAME_QUIT, +}; /* WARN: stock must always follow immediately after `TAB_*`! */ #define TAB_MAX (STOCK-1) @@ -103,7 +133,7 @@ struct cursor { const struct cursor no_hi = {-1, -1}; #define NO_HI &no_hi -void sol(void); +int sol(void); int find_top(card_t* pile); int first_movable(card_t* pile); void turn_over(card_t* pile); -- 2.39.3