题目
请利用 setitimer() 和 sigaction() 函数编写一个小游戏,该游戏随机在 5 ~ 15 秒之内开始,开始后随机从 ’w’, ‘s’, ‘a’, ‘d’ 中选取 4 个字母显示在屏幕上,玩家需要迅速正确键入字母并回车以赢得并退出游戏,否则 3 秒后游戏将重新选取 4 个字母显示,无穷地循环下去。
点拨
源代码
#include <chrono>
#include <cstdio>
#include <cstring>
#include <fcntl.h>
#include <random>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
using namespace std;
using namespace std::chrono;
using flag_t = int;
uniform_real_distribution<double> random_start_time(5, 15);
uniform_int_distribution<unsigned> random_char_pos(0, 3);
mt19937_64 re(high_resolution_clock::now().time_since_epoch().count());
const char chr[] = { "wsad" };
const __time_t time_limit_sec = 3;
const size_t letter_count = 4;
const size_t input_capacity = 1024;
const struct timeval waitintv = { time_limit_sec, 0 };
const struct timeval onceintv = { 0, 0 };
const struct itimerval itvw = { waitintv, waitintv };
const struct itimerval notimer = { onceintv, onceintv };
void game_start(int);
void lose_game(int);
const struct sigaction no_act = { nullptr, {}, 0, nullptr };
const struct sigaction start_act = { game_start, {}, 0, nullptr };
const struct sigaction lose_act = { lose_game, {}, 0, nullptr };
char required[letter_count + 2] = { " \n" }, input[input_capacity];
bool won = false, again;
void game_start(int) {
puts("GAME START\n");
}
void lose_game(int) {
puts("YOU LOSE.\n");
again = true;
}
int main() {
flag_t flag = fcntl64(STDIN_FILENO, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl64(STDIN_FILENO, F_SETFL, flag);
const struct timeval startintv = { random_start_time(re), 0 };
const struct itimerval itvs = { onceintv, startintv };
setitimer(ITIMER_REAL, &itvs, nullptr);
sigaction(SIGALRM, &start_act, nullptr);
pause();
setitimer(ITIMER_REAL, &itvw, nullptr);
sigaction(SIGALRM, &lose_act, nullptr);
for (; won == false; ) {
for (size_t i = 0; i < letter_count; ++i) required[i] = chr[random_char_pos(re)];
again = false;
printf("Input: %s\n", required);
for (; again == false; ) {
fgets(input, input_capacity, stdin);
if (strcmp(input, required) == 0) {
won = true;
break;
}
}
}
puts("YOU WIN!");
return 0;
}