146 lines
4.9 KiB
C
146 lines
4.9 KiB
C
// 编程设计打字游戏:
|
||
// 1)随机函数
|
||
// A.srand((unsigned)time(NULL));
|
||
// 以当前时间为准,设置随机种子
|
||
// 注意:此函数,在每次开始游戏后调用一次即可
|
||
// B.ch = rand();
|
||
// 注意:rand()函数,每调用一次,产生一个随机数字
|
||
|
||
// 2)获得键值函数
|
||
// ch=mygetch(); //无需按下回车,可直接获得键盘上按下的键值
|
||
|
||
// 还可以自己封装一个无阻塞,无回显的getch,实现如下:
|
||
// #include <termios.h>
|
||
// #include <unistd.h>
|
||
// char
|
||
// mygetch()
|
||
// {
|
||
// struct termios oldt, newt;
|
||
// char ch;
|
||
// tcgetattr(STDIN_FILENO, &oldt);
|
||
// newt = oldt;
|
||
// newt.c_lflag &= ~(ICANON | ECHO);
|
||
// tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||
// ch = getchar();
|
||
// tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||
// return ch;
|
||
// }
|
||
// 3)时间函数
|
||
// start_time=time(NULL);
|
||
// edn_time = time(NULL);
|
||
// //可以返回系统当前时间,以秒为单位
|
||
|
||
// 4)system("clear");//清空屏幕
|
||
|
||
// 5)所需头文件
|
||
// #include <time.h>
|
||
// #include <math.h>
|
||
// #include <stdio.h>
|
||
// #include <stdlib.h>
|
||
|
||
#include <time.h>
|
||
#include <math.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <termios.h>
|
||
#include <unistd.h>
|
||
|
||
char mygetch();
|
||
void help();
|
||
|
||
int main()
|
||
{
|
||
int NUMS_OF_CHARS = 11; // 字符总数
|
||
char ch; // 键盘输入字符
|
||
char str[11] = ""; // 题目字符数组
|
||
int i;
|
||
int cnt; // 正确数
|
||
time_t start_time, end_time; // 开始,结束时间
|
||
|
||
help(); // 首次进入游戏时主动显示游戏提示
|
||
ch = mygetch(); // 按任意键开始游戏
|
||
while (1)
|
||
{
|
||
|
||
// help(); // 首次进入游戏时主动显示游戏提示 (这里如果解注释,则会每次都显示帮助信息)
|
||
// ch = mygetch(); // 按任意键开始游戏
|
||
|
||
srand((unsigned)time(NULL)); // 设置随机种子
|
||
for (i = 0; i < NUMS_OF_CHARS - 1; i++)
|
||
{
|
||
switch (rand() % 3) // 根据每一次的随机值安顿好当前位置的字符类型
|
||
{
|
||
case 0:
|
||
str[i] = rand() % 10 + '0'; // 0-9的数字
|
||
break;
|
||
case 1:
|
||
str[i] = rand() % 26 + 'a'; // a-z的数字
|
||
break;
|
||
case 2:
|
||
str[i] = rand() % 26 + 'A'; // A-Z的数字
|
||
break;
|
||
}
|
||
}
|
||
|
||
// str[NUMS_OF_CHARS - 1] = '\0'; // 末位补上结束符
|
||
printf("%s\n", str);
|
||
cnt = 0; // 计数器初始化为 0
|
||
for (i = 0; i < NUMS_OF_CHARS - 1; i++)
|
||
{
|
||
ch = mygetch(); // 获取每一次的按键输入
|
||
if (i == 0) // 如果第一次按下任意键,则开始计时
|
||
start_time = time(NULL);
|
||
if (ch == str[i])
|
||
{
|
||
cnt++; // 当按下的键和题目数组对应位置的值一致时,成功计数器加一
|
||
printf("%c", ch); // 打印正确键入的字符
|
||
continue; // 继续下一位置的字符输入
|
||
}
|
||
else
|
||
{
|
||
printf("*"); // 如果输入的键和题目不匹配,则显示为 *
|
||
continue;
|
||
}
|
||
}
|
||
|
||
end_time = time(NULL); // 全部输入结束后,记录结束时间
|
||
printf("\n你的打字正确率为 %d %c\n", cnt * 100 / (NUMS_OF_CHARS - 1), '%');
|
||
printf("总共用时为 %lld 秒\n", (long long int)end_time - start_time);
|
||
while (1) // 再次获取一下键盘输入
|
||
{
|
||
ch = mygetch();
|
||
if (ch == 32)
|
||
{
|
||
system("clear"); // 清空屏幕
|
||
break; // 按 SPACE (ASCII=32) 跳出小循环,进入大循环,即重新一轮游戏
|
||
}
|
||
else if (ch == 27)
|
||
return 0; // 按下 ESC (ASCII=27) 键退出游戏 (return 0 --- 程序结束)
|
||
}
|
||
}
|
||
return 0; // 程序结束
|
||
}
|
||
|
||
char mygetch() // 无阻塞,无回显的getch
|
||
{
|
||
struct termios oldt, newt;
|
||
char ch;
|
||
tcgetattr(STDIN_FILENO, &oldt);
|
||
newt = oldt;
|
||
newt.c_lflag &= ~(ICANON | ECHO);
|
||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||
ch = getchar();
|
||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||
return ch;
|
||
}
|
||
|
||
void help() // 游戏提示信息
|
||
{
|
||
printf("\n *******************************************");
|
||
printf("\n *请按所给字母敲击键盘! *");
|
||
printf("\n *请按任意键开始测试,按下首字母时开始计时!*");
|
||
printf("\n *输入出错则以 * 表示 *");
|
||
printf("\n *按空格键继续游戏 (新一轮游戏) *");
|
||
printf("\n *按 ESC 退出游戏 *");
|
||
printf("\n *******************************************\n");
|
||
} |