游戏规则
玩家先输入四个数字,与系统产生的四个1-9之间的不重复的且从小到大排序随机数进行比较,如果错误,根据显示的结果再次进行猜测,直至正确。
游戏原理
1.产生四个1-9之间的不重复的随机数。
2.将其从小到大排序。
3.与玩家输入的数字进行比较。
4.如果有n个数字正确且位置正确的数,则输出nA,如果有m个数字正确,位置不正确的数,则输出mB。
若玩家第一次猜错,则可以根据nAmB这个结果进行合理分析并再次猜测。
实现
先写好头文件
/#include <stdio.h>
/#include <stdlib.h>
/#include <time.h>
生成随机数
步骤
1生成数组
2产生随机数的同时去比较是否重复
3如果重复就重新再产生一个随机数
4如果不重复就保存
5每次i的值正好可以用来判断已经有几个了
首先定义一个数组并初始化,再生成随机数
注:有关生成随机数的内容在‘C语言基础练习-随机数’里面详细介绍过,这里便不再复述。
代码如下
int array[4] = {};
srand(time(NULL));
for (int i = 0; i < 4; i++){
int temp = rand() % 9 + 1;
if (i == 0){//第一个 直接保存
array[i] = temp;
}else{
//判断前面是否已经存在了
int j = 0;
for(; j <i; j++){
//比较j对应的值和temp是否相同
if(array[j] == temp){
//重复了
// printf("重复了:%d\n",temp);
break;
}
}
//判断是怎么出来的
if (j == i){
//将i前面的比较一遍都没发现重复的
//保存temp值
array[i] = temp;
}else{
//重复了
//重新回到当前这一次
i--;
}
}
}
- 虽然说随机数在前面的笔记中有介绍过,但是这里有一个新的要求,就是四个数中不能有相同的数字。
- 所以在保存生成的这个数之前,要先判断这个数与之前的数是否相同,若相同,就不能保存,然后重新生成再进行判断,直至生成的数与前面的不同,再保存到数组中。
- 由代码可知,首先判断这个数是否是第一个生成的数,因为第一个生成的数前面没有数字。所以直接保存即可。
- 从第二个数字起,就要进行是否相同的判断。
这里假设已经生成了第四个数字,现在要将其与前三个数进行对比。定义一个整型j,且j = 0,此时i = 3,要将第四个数从第一个数开始进行判断,就用一个for循环,进行次数控制并连续判断,只要进行了i -1次判断且判断数字都不相同,生成的这个数即可保存到数组,如若顺序判断中一旦相同,即停止判断,退出当前for循环。 - 当退出当前for循环后,若数字有相同的,会再次进行最外层的for循环中的i++从而,而此时i=3,再次生成一个随机数后,i就等于4了,就不会再生成随机数,所以我们在内层for循环执行完或break出来之后,若要再次生成随机数就要进行一下i - -。
if (j == i){
array[i] = temp;
}else{
i--;
}
将数组排序
排序的方法有很多,在这里我们使用冒泡排序将数组按从小到大排好序
(由于在上一篇笔记中介绍过冒泡排序,这里就直接放上代码)
代码如下
int i,j,t; //从小到大排序 ;冒泡排序
for(i = 0;i < 3;i++){ //控制遍历次数 有N个数,遍历N-1次;
for(j =0;j < 4 -i -1;j++){
if(array[j] > array[j + 1]){
t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
}
由于这个游戏是让玩家猜数,所以并不需要输出生成的数组,但是在边写代码的时候,可以输出这个数组以便检查是否存在bug。
输出的代码如下
//输出
for (int i = 0; i< 4; i++){
printf("%d ", array[i]);
}
printf("\n");
用户输入,游戏“开始”
用户输入
int input[4],shu;
printf("请输入四个数字\n");
for(int a = 0;a < 4;a++){ //用另外一个数组储存输入的数字
scanf("%d",&shu);
input[a] = shu;
}
这里需要注意的是,要用另一个数组来储存用户输入的数字。即代码中的input。
计算n、m
即在nAmB中的n、m。并判断是否全对,若不对,则告知玩家nAmB,并再次进行猜测,直至猜对。
由上述可得,整个输入及计算过程要放在while(1)的循环里。
计算过程有两种方法。
方法一
分别计算A,B的值
代码如下
首先计算A的值
int num = 0,space1 = 0,a = 0,space2;
for(int i = 0;i < 4;i++){ //算出数字和位置都正确的个数
if(input[a] == array[i]){
num++;
}
a++;
}
再计算数字正确的个数
a = 0;
while(a < 4){ //算出数字正确的个数
for(i = 0;i < 4;i++){
if(input[a] == array[i]){
space1++;
}
}
a++;
}
在计算B之前,应将a重新变为0,因为在计算A的值之后,a 变成了3。
计算B的值
space2 = space1 - num;//算出数字正确,位置不正确的个数 ,即B的值
printf("%dA%dB\n",num,space2);
if(num == 4){
printf("猜测正确!");
break;
}
用一个if语句,使猜对后跳出while循环。
方法二
A,B一起计算.
代码如下
while(1){
//提示输入
printf("请输入猜测的数字:");
for (int i = 0; i < 4; i++) {
scanf("%d", &input[i]);
}
//
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (org[i] == input[j]) {
//数字存在 判断位置
if (i == j){
aCount++;
}else{
bCount++;
}
}
}
}
//提示用户结果
printf("%dA%dB\n", aCount, bCount);
//判断是否正确
if( aCount == 4){
printf("全对!!!!\n");
break;
}else{
aCount = 0;
bCount = 0;
}
}
- 玩家输入后,首先判断是否有相同的数字存在。
- 若存在,则判断位置。
- 若判断位置正确,就意味着这个数位置,数字都正确,则aCount++。
- 若判断位置不正确,就意味着这个数位置不正确但数字正确,就bCount++。
- 最后如果aCount != 4。玩家再次进行猜测,而此时aCount, bCount都要进行清零才能重新正常地进行下一次猜测。
由上述可得,方法二相当于是方法一的优化版,因为方法二的计算过程更加直观,简洁。
将方法一改为函数版
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int array[4] = {};
srand(time(NULL));
for (int i = 0; i < 4; i++){
int temp = rand() % 9 + 1;
if (i == 0){//第一个 直接保存
array[i] = temp;
}else{
//判断前面是否已经存在了
int j = 0;
for(; j <i; j++){
//比较j对应的值和temp是否相同
if(array[j] == temp){
//重复了
// printf("重复了:%d\n",temp);
break;
}
}
//判断是怎么出来的
if (j == i){
//将i前面的比较一遍都没发现重复的
//保存temp值
array[i] = temp;
}else{
//重复了
//重新回到当前这一次
i--;
}
}
}
int i,j,t; //从小到大排序 ;冒泡排序
for(i = 0;i < 3;i++){ //控制遍历次数 有N个数,遍历N-1次;
for(j =0;j < 4 -i -1;j++){
if(array[j] > array[j + 1]){
t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
}
while(1){
int input[4],shu;
printf("请输入四个数字\n");
for(int a = 0;a < 4;a++){ //用另外一个数组储存输入的数字
scanf("%d",&shu);
input[a] = shu;
}
int num = 0,space1 = 0,a = 0,space2;
for(int i = 0;i < 4;i++){ //算出数字和位置都正确的个数
if(input[a] == array[i]){
num++;
}
a++;
}
a = 0;
while(a < 4){ //算出数字正确的个数
for(i = 0;i < 4;i++){
if(input[a] == array[i]){
space1++;
}
}
a++;
}
space2 = space1 - num;//算出数字正确,位置不正确的个数
printf("%dA%dB\n",num,space2);
if(num == 4){
printf("猜测正确!");
break;
}
}
return 0;
}
函数版
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void randomNumber(int array[4]);// 生成随机数
void bubbleSort(int array[4]);//排序
int game(int array[4]);//进行游戏
int main(){
int array[4] = {};
randomNumber(array);
bubbleSort(array);//()中的array是指针,指向array这个数组的首地址,这样做可以直接访问地址,修改数据
while(1){
game(array);
if(game(array) == 4){
printf("猜测正确!");
break;
}
}
return 0;
}
void randomNumber(int array[4]){
srand(time(NULL));
for (int i = 0; i < 4; i++){
int temp = rand() % 9 + 1;
if (i == 0){//第一个 直接保存
array[i] = temp;
}else{
//判断前面是否已经存在了
int j = 0;
for(; j <i; j++){
//比较j对应的值和temp是否相同
if(array[j] == temp){
//重复了
// printf("重复了:%d\n",temp);
break;
}
}
//判断是怎么出来的
if (j == i){
//将i前面的比较一遍都没发现重复的
//保存temp值
array[i] = temp;
}else{
//重复了
//重新回到当前这一次
i--;
}
}
}
}
void bubbleSort(int array[4]){
int i,j,t; //从小到大排序 ;冒泡排序
for(i = 0;i < 3;i++){ //控制遍历次数 有N个数,遍历N-1次;
for(j =0;j < 4 -i -1;j++){
if(array[j] > array[j + 1]){
t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
}
}
int game(int array[4]){
int input[4],shu;
printf("请输入四个数字\n");
for(int a = 0;a < 4;a++){ //用另外一个数组储存输入的数字
scanf("%d",&shu);
input[a] = shu;
}
int num = 0,space1 = 0,a = 0,space2;
for(int i = 0;i < 4;i++){ //算出数字和位置都正确的个数
if(input[a] == array[i]){
num++;
}
a++;
}
a = 0;
while(a < 4){ //算出数字正确的个数
for(int m = 0;m < 4;m++){
if(input[a] == array[m]){
space1++;
}
}
a++;
}
space2 = space1 - num;//算出数字正确,位置不正确的个数
printf("%dA%dB\n",num,space2);
return(num);
}
//若要输出原来的四个数字,则在array和while之间加入以下代码
/* for (int i = 0; i< 4; i++){
printf("%d ", array[i]);
}
printf("\n");
*/
- 如果使用DEV C++,srand(time(NULL));中可以自动转换,若用Visual studio,则需进行强制转换。srand((unsigned int)time(NULL));
- 在Visual studio中,输入需要使用vs封装的scanf。scanf_s("%d",&shu);
作者有话说
- 到此,这个demo就做完啦!
- 通过这个demo,对各种循环语句运用更加熟练了
- 并且意识到要用自定义函数来单独进行某个功能的重要性
- 还有......熟能生巧!