Simon 记忆测试游戏
编写一个简单的 simon 游戏,这是一个记忆测试游戏。计算机会在屏幕将一串数字显示很短时间,玩家必须在数字消失之前记住他们,然后输入这串数字。每次过关后,计算机会显示更长一串数字,让玩家继续玩下去,玩家尽可能使这个过程重复更多次数。
分析
程序的逻辑很简单,程序必须产生一连串 0~9 的整数,使它们在屏幕上显示一秒钟,之后删除它们。
解决方案
步骤 1:确定代码基本功能块,包括游戏的主循环
#include <stdio.h> /* 使用 input 和 output */
#include <ctype.h> /* 使用 toupper() function */
#include <stdbool.h> /* 使用 bool, true, false */
#include <stdlib.h> /* 使用 rand() 和 srand() */
#include <time.h> /* 使用 time() 和 clock() */
int main(void)
{
/* 记录是否要玩另一个游戏 */
char another_game = 'Y';
/* 如果输入正确的序列,则为true,否则为false */
int correct = false;
/* 成功输入的序列数 */
int counter = 0;
int sequence_length = 0; /* 序列中的位数 */
time_t seed = 0; /* 随机数序列的种子值 */
int number = 0; /* 存储输入数字*/
time_t now = 0; /* 存储随机值的当前时间种子 */
int time_taken = 0; /* 游戏时间(秒) */
/* 描述游戏是如何进行的 */
printf("\n准备玩简单的Simon游戏, ");
printf("观察屏幕上的数字序列.");
printf("\n小心观察,因为数字只显示出来几秒");
printf("\n计算机将删除它们,然后提示您输入相同的序列.");
printf("\n当你这样做时,你必须在数字之间加空格. \n");
printf("\n祝你好运!\n按回车键开始\n");
scanf("%c", &another_game);
/* 一个外循环迭代就是一个游戏 */
do
{
correct = true; /* 默认情况下,表示输入的顺序正确 */
counter = 0; /* 初始化成功尝试次数的计数*/
sequence_length = 2; /* 数字序列的初始长度*/
time_taken = clock(); /* 在游戏开始时记录当前时间*/
/* 只要序列输入正确,内环就继续 */
while(correct)
{
/* 每三次成功尝试,增加序列长度 */
sequence_length += counter++ % 3 == 0;
/* 将seed设置为自1970年1月1日以来的秒数 */
seed = time(NULL);
now = clock(); /* 记录序列的开始时间 */
/* 生成数字序列并显示数字 */
srand((unsigned int)seed); /* 初始化随机序列 */
for(int i = 1; i <= sequence_length; i++)
printf("%d ", rand() % 10); /* 输出随机数字 */
/* 等一秒 */
for( ; clock() - now < CLOCKS_PER_SEC; );
/* 现在重写数字序列 */
printf("\r"); /* 转到行首 */
for(int i = 1; i <= sequence_length; i++)
printf(" "); /* 输出空白 覆盖 */
if(counter == 1) /* 只输出第一次尝试的消息 */
printf("\n现在输入序列-不要忘记空格\n");
else
printf("\r"); /* 回到行首 */
/* 对照原始数字检查输入序列 */
srand((unsigned int)seed); /* 重新启动随机序列 */
for(int i = 1; i <= sequence_length; i++)
{
scanf("%d", &number); /* 读取输入数字 */
if(number != rand() % 10) /* 与随机数比较 */
{
correct = false; /* 输入错误 */
break; /* 无需进一步检查... */
}
}
printf("%s\n", correct ? "对的!" : "错的!");
}
/* 计算玩游戏的总时间(秒)*/
time_taken = (clock() - time_taken) / CLOCKS_PER_SEC;
/* 输出游戏分数 */
printf("\n\n 你的分数是 %d", --counter * 100 / time_taken);
fflush(stdin);
/* 检查是否需要新游戏*/
printf("\n你想再玩一次吗 (y/n)? ");
scanf("%c", &another_game);
}
while(toupper(another_game) == 'Y');
return 0;
}Code language: PHP (php)
程序分解:游戏循环控制
- 首先完成游戏是否继续玩,输入 y 则继续,输入 n 则结束。
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char isPlayAgain = 'Y';
do
{
printf("\n玩了一次游戏");
fflush(stdin); //清空输入缓冲区,通常是为了确保不影响后面的数据读取
printf("\n你想再玩一次吗 (y/n)? ");
scanf("%c", &isPlayAgain);
}
while(tolower(isPlayAgain) == 'y');
printf("\n游戏结束");
return 0;
}Code language: PHP (php)
Code::Blocks 语法纠错功能(红色波浪线)
菜单栏 Plugins(插件)下拉找到 Manage Plugins,点开找到 SpellChecker,将它设置为 Disable 即可。
程序分解:Simon 游戏逐步实现
1. 游戏循环控制
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char isPlayAgain = 'Y';
do
{
printf("\n玩了一次游戏");
fflush(stdin); //清空输入缓冲区,通常是为了确保不影响后面的数据读取
printf("\n你想再玩一次吗 (y/n)? ");
scanf("%c", &isPlayAgain);
}
while(tolower(isPlayAgain) == 'y');
printf("\n游戏结束");
return 0;
}Code language: PHP (php)
2. 输出随机序列
#include <stdio.h>
#include <ctype.h>
#include <time.h>
int main(void)
{
time_t seed = 0; //随机数序列的种子值
char isPlayAgain = 'Y';
int seqLength = 2; //一开始数字序列长度为2 后面 根据猜对情况 每次递增1
do
{
//将seed设置为自1970年1月1日以来的秒数 存储起来后面有用
seed = time(NULL);
srand((unsigned int)seed); //初始化随机序列
//输出随机数字
for(int i = 1; i <= seqLength; i++)
{
printf("%d ", rand() % 10); //只输出1到9
}
fflush(stdin);
printf("\n你想再玩一次吗 (y/n)? ");
scanf("%c", &isPlayAgain);
}
while(tolower(isPlayAgain) == 'y');
return 0;
}Code language: PHP (php)
3. 显示一秒后隐藏序列
#include <stdio.h>
#include <ctype.h>
#include <time.h>
int main(void)
{
time_t seed = 0;
char isPlayAgain = 'Y';
int seqLength = 2;
time_t now = 0;
do
{
seed = time(NULL);
srand((unsigned int)seed);
now = clock();
for(int i = 1; i <= seqLength; i++)
{
printf("%d ", rand() % 10);
}
//等一秒
for( ; clock() - now < CLOCKS_PER_SEC; );
//现在重写数字序列
printf("\r");
for(int i = 1; i <= seqLength; i++)
{
printf(" ");
}
fflush(stdin);
printf("\n你想再玩一次吗 (y/n)? ");
scanf("%c", &isPlayAgain);
}
while(tolower(isPlayAgain) == 'y');
return 0;
}Code language: PHP (php)
4. 随机数种子复用验证
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t seed = time(NULL);
srand((unsigned int)seed);
printf("第一次输出\n");
for(int i = 1; i <= 5; i++)
{
printf("%d ", rand() % 10);
}
printf("\n");
srand((unsigned int)seed);
printf("第二次输出\n");
for(int i = 1; i <= 5; i++)
{
printf("%d ", rand() % 10);
}
printf("\n");
return 0;
}Code language: PHP (php)
5. 检查用户输入
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
int main(void)
{
time_t seed = 0;
char isPlayAgain = 'Y';
int seqLength = 2;
time_t now = 0;
int number = 0;
int correct = true;
do
{
seed = time(NULL);
srand((unsigned int)seed);
now = clock();
for(int i = 1; i <= seqLength; i++)
{
printf("%d ", rand() % 10);
}
for( ; clock() - now < CLOCKS_PER_SEC; );
printf("\r");
for(int i = 1; i <= seqLength; i++)
{
printf(" ");
}
printf("\r");
//对照原始数字检查输入序列
srand((unsigned int)seed);
for(int i = 1; i <= seqLength; i++)
{
scanf("%d", &number);
if(number != rand() % 10)
{
correct = false;
break;
}
}
printf("%s\n", correct ? "对的!" : "错的!");
fflush(stdin);
printf("\n你想再玩一次吗 (y/n)? ");
scanf("%c", &isPlayAgain);
}
while(tolower(isPlayAgain) == 'y');
return 0;
}Code language: PHP (php)
6. 加入内层循环,答错才退出
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
int main(void)
{
time_t seed = 0;
char isPlayAgain = 'Y';
int seqLength = 2;
time_t now = 0;
int number = 0;
int correct = true;
do
{
while(correct)
{
seed = time(NULL);
srand((unsigned int)seed);
now = clock();
for(int i = 1; i <= seqLength; i++)
{
printf("%d ", rand() % 10);
}
for( ; clock() - now < CLOCKS_PER_SEC; );
printf("\r");
for(int i = 1; i <= seqLength; i++)
{
printf(" ");
}
printf("\r");
srand((unsigned int)seed);
for(int i = 1; i <= seqLength; i++)
{
scanf("%d", &number);
if(number != rand() % 10)
{
correct = false;
break;
}
}
printf("%s\n", correct ? "对的!" : "错的!");
}
fflush(stdin);
printf("\n你想再玩一次吗 (y/n)? ");
scanf("%c", &isPlayAgain);
}
while(tolower(isPlayAgain) == 'y');
return 0;
}Code language: PHP (php)
7. 每答对三次递增序列长度
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
int main(void)
{
time_t seed = 0;
char isPlayAgain = 'Y';
int seqLength = 2;
time_t now = 0;
int number = 0;
int correct = true;
int counter = 0;
do
{
while(correct)
{
if(counter > 0 && counter % 3 == 0)
{
seqLength++;
}
seed = time(NULL);
srand((unsigned int)seed);
now = clock();
for(int i = 1; i <= seqLength; i++)
{
printf("%d ", rand() % 10);
}
for( ; clock() - now < CLOCKS_PER_SEC; );
printf("\r");
for(int i = 1; i <= seqLength; i++)
{
printf(" ");
}
printf("\r");
srand((unsigned int)seed);
for(int i = 1; i <= seqLength; i++)
{
scanf("%d", &number);
if(number != rand() % 10)
{
correct = false;
break;
}
}
printf("%s\n", correct ? "对的!" : "错的!");
if(correct)
{
counter++;
}
}
fflush(stdin);
printf("\n你想再玩一次吗 (y/n)? ");
scanf("%c", &isPlayAgain);
}
while(tolower(isPlayAgain) == 'y');
return 0;
}Code language: PHP (php)
8. 计算分数
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
int main(void)
{
time_t seed = 0;
char isPlayAgain = 'Y';
time_t now = 0;
int number = 0;
do
{
int seqLength = 2;
int correct = true;
int counter = 0;
int timeStart = clock();
while(correct)
{
if(counter > 0 && counter % 3 == 0)
{
seqLength++;
}
seed = time(NULL);
srand((unsigned int)seed);
now = clock();
for(int i = 1; i <= seqLength; i++)
{
printf("%d ", rand() % 10);
}
for( ; clock() - now < CLOCKS_PER_SEC; );
printf("\r");
for(int i = 1; i <= seqLength; i++)
{
printf(" ");
}
printf("\r");
srand((unsigned int)seed);
for(int i = 1; i <= seqLength; i++)
{
scanf("%d", &number);
if(number != rand() % 10)
{
correct = false;
break;
}
}
printf("%s\n", correct ? "对的!" : "错的!");
if(correct)
{
counter++;
}
}
int timeSpan = (clock() - timeStart) / CLOCKS_PER_SEC;
printf("\n\n 你的分数是 %d", counter * 100 / timeSpan);
fflush(stdin);
printf("\n你想再玩一次吗 (y/n)? ");
scanf("%c", &isPlayAgain);
}
while(tolower(isPlayAgain) == 'y');
return 0;
}Code language: PHP (php)
练习题
练习 1:乘法表
#include <stdio.h>
int main(void)
{
int size = 0;
printf("请输入乘法表的大小: ");
scanf("%d", &size);
for(int i = 1; i <= size; i++)
{
for(int j = 1; j <= size; j++)
{
printf("%d\t", i * j);
}
printf("\n");
}
return 0;
}Code language: PHP (php)
练习 2:输出可打印字符(0~127)
#include <stdio.h>
#include <ctype.h>
int main(void)
{
for(int code = 0; code <= 127; code++)
{
if(isgraph(code))
{
printf("code: %3d -> %c\n", code, (char)code);
}
}
return 0;
}Code language: PHP (php)
练习 3:空白字符输出名称
#include <stdio.h>
#include <ctype.h>
int main(void)
{
for(int code = 0; code <= 127; code++)
{
if(isgraph(code))
{
printf("code: %3d -> %c\n", code, (char)code);
}
else if(code == '\n')
{
printf("code: %3d -> newline\n", code);
}
else if(code == '\t')
{
printf("code: %3d -> tab\n", code);
}
else if(code == ' ')
{
printf("code: %3d -> space\n", code);
}
}
return 0;
}Code language: PHP (php)
练习 4:修改猜谜游戏(基于 rand 值域)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int chosen = 0;
int guess = 0;
int limit = RAND_MAX / 100; //利用rand()整个值域来确定随机数值
srand(time(NULL));
chosen = rand() % limit + 1;
printf("猜一个 1 到 %d 之间的数字: ", limit);
while(1)
{
scanf("%d", &guess);
if(guess == chosen)
{
printf("猜中了!\n");
break;
}
else if(guess < chosen)
{
printf("太小了,再试: ");
}
else
{
printf("太大了,再试: ");
}
}
return 0;
}Code language: PHP (php)
练习 5:猜谜游戏允许继续玩
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
int main(void)
{
char playAgain = 'Y';
while(toupper(playAgain) == 'Y')
{
int chosen = 0;
int guess = 0;
int limit = 20;
srand(time(NULL));
chosen = rand() % limit + 1;
printf("\n猜一个 1 到 %d 之间的数字: ", limit);
while(1)
{
scanf("%d", &guess);
if(guess == chosen)
{
printf("猜中了!\n");
break;
}
else
{
printf("错了,再试一次 (输入0放弃本轮): ");
if(guess == 0)
{
printf("正确答案是 %d\n", chosen);
break;
}
}
}
printf("继续玩下一轮? (Y/N): ");
scanf(" %c", &playAgain);
}
return 0;
}Code language: PHP (php)
Previous: continue 语句
Next: 数组