2 * "THE BEER-WARE LICENSE" (Revision 42):
3 * <tobias.rehbein@web.de> wrote this file. As long as you retain this notice
4 * you can do whatever you want with this stuff. If we meet some day, and you
5 * think this stuff is worth it, you can buy me a beer in return.
24 #define MIN(a, b) ((a) < (b)) ? a : b
26 static const char *OGG123
= "/usr/local/bin/ogg123";
34 static void init_options(struct options
*opts
);
35 static int new_turn(struct oggfile
*oggfiles
, struct options
*opts
);
36 static void parse_options(struct options
*opts
, int argc
, char **argv
);
39 main(int argc
, char **argv
)
41 char filename
[FILENAMELEN
];
44 struct oggfile oggfiles
[CHOICES
];
50 if (setlocale(LC_ALL
, "") == NULL
)
51 warnx("could not set locale");
54 parse_options(&opts
, argc
, argv
);
56 * After this point the global options structure is considered read
64 while (fgets(filename
, FILENAMELEN
, stdin
) != NULL
) {
65 if ((newline
= strchr(filename
, '\n')) != NULL
)
68 if (oggfile_create(&oggfiles
[oggfileno
], filename
) == 0)
71 if (oggfileno
== opts
.choices
) {
73 if (new_turn(oggfiles
, &opts
))
86 new_turn(struct oggfile
*oggfiles
, struct options
*opts
)
88 static int first_invocation
= 0;
89 static struct ui_model model
;
94 assert(oggfiles
!= NULL
);
97 if (!first_invocation
) {
100 /* abusing the correct variable as a temporary variable */
101 for (correct
= 0; correct
< opts
->players
; correct
++) {
102 model
.scores
[correct
] = 0;
107 model
.current_player
= ((model
.turn
- 1) % opts
->players
);
108 model
.oggfiles
= oggfiles
;
109 correct
= rand() % opts
->choices
;
110 model
.correct
= &oggfiles
[correct
];
111 ui_display_quiz(&model
, opts
);
112 player_play(model
.correct
, opts
);
115 guess
= ui_get_answer();
118 } while (guess
< '1' || guess
> '0' + opts
->choices
);
119 model
.guess
= &oggfiles
[guess
- '1'];
120 if (model
.guess
== model
.correct
)
121 model
.scores
[model
.current_player
] += MIN(opts
->time
, time(NULL
) - start
);
123 model
.scores
[model
.current_player
] += opts
->time
;
124 ui_display_result(&model
, opts
);
131 init_options(struct options
*opts
)
133 assert(opts
!= NULL
);
135 opts
->time
= TIMEOUT
;
136 opts
->choices
= CHOICES
;
137 opts
->players
= PLAYERS
;
138 SAFE_STRNCPY(opts
->ogg123
, OGG123
, OPTIONLEN
);
142 parse_options(struct options
*opts
, int argc
, char **argv
)
146 assert(opts
!= NULL
);
148 assert(argv
!= NULL
);
150 struct option longopts
[] = {
151 {"time", required_argument
, NULL
, 't'},
152 {"choices", required_argument
, NULL
, 'c'},
153 {"players", required_argument
, NULL
, 'p'},
154 {"ogg123", required_argument
, NULL
, 'o'},
155 {"help", no_argument
, NULL
, 'h'}
158 while ((ch
= getopt_long(argc
, argv
, "t:c:p:o:e:h", longopts
, NULL
)) != -1)
161 opts
->time
= (int)strtol(optarg
, (char **)NULL
, 10);
164 opts
->choices
= (int)strtol(optarg
, (char **)NULL
, 10);
165 if (opts
->choices
< 1 || opts
->choices
> CHOICES
)
166 errx(1, "choices must not exceed %d", CHOICES
);
169 opts
->players
= (int)strtol(optarg
, (char **)NULL
, 10);
170 if (opts
->players
< 1 || opts
->players
> PLAYERS
)
171 errx(1, "players must not exceed %d", PLAYERS
);
174 if (strlen(optarg
) >= OPTIONLEN
)
175 errx(1, "length of argument 'o' must not exceed %d bytes", OPTIONLEN
);
176 SAFE_STRNCPY(opts
->ogg123
, optarg
, OPTIONLEN
);
180 puts("oggquiz [-t | --time seconds] [-c | --choices choices] [-p | --players players]");
181 puts(" [-o | --ogg123 command]");
182 puts("oggquiz {-h | --help}");