【C语言】猜数游戏

系统随机产生四个不同的有序的数字 (从小到大排列),等待用户输入猜测的结果, 用A来表示数字正确且位置正确的个数 ,用B来表示数字正确但位置不正确的个数,给八次机会,猜中则游戏成功,机会用完则游戏失败

分析:1.需要一个数组存放生成的随机数,保证数据不重复且按从小到大排列

           2.需要另外一个数组存放用户的猜测结果

           3.需要一个变量记录已经猜了多少次

           4.将两个数组进行比较,统计A和B的个数并告知用户,方便其继续猜

           5.当用户全部猜中或机会用完时,游戏结束,退出

 

我第一次得到题目时编写的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {

	//提示游戏规则
	printf("****************************************************\n");
	printf("*********************游戏规则***********************\n");
	printf("系统将随机生成四个不同的有序数字(按从小到大排列)\n");
	printf("请输入您猜测的四个数字\n");
	printf("用A表示数字正确且位置正确的个数\n");
	printf("用B表示数字正确但位置不正确的个数\n");
	printf("一共有八次机会\n");
	printf("****************************************************\n");


    //产生不同的随机数
    srand(time(NULL));
    int number[4];
    number[0] = rand() %9+1;
    number[1] = rand() %9+1;
    number[2] = rand() %9+1;
    number[3] = rand() %9+1;
    while (number[1] == number[0]) {
        number[1] = rand() %9+1;
    }
    while (number[2] == number[1] || number[2] == number [0]) {
        number[2] = rand() %9+1;
    }
    while (number[3] == number[2] || number[3] == number [1] || number[3] ==number[0]) {
        number[3] = rand() %9+1;
    }
	//这一句是为了检查数据是否重复,真正编译时应该删掉
    printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);     
    
    
    //将随机数按从小到大排列
    for(int i = 0; i < 4; i++){
        for(int j = 0; j < i; j++)
        {
            if(number[i] < number[j]){
                number[i] = number[i] + number[j];
                number[j] = number[i] - number[j];
                number[i] = number[i] - number[j];
            }
        }  
    }
	 //这一句是为了检查数据是否正确排列,真正编译时应该删掉
    printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);  
       
    //输入数据并判断
    int guess[4];
    int count = 8;
    
    do{
        int countA = 0;
        int countB = 0;
    
	//提示用户输入数据
    printf("请输入四个1~9的数字(每输一个按一次回车):\n");
    for (int i = 0; i < 4; i++) {
        scanf("%d",&guess[i]);
        while (guess[i] < 1 || 9 < guess[i]) {
            printf("输入数据有误,请重新输入\n");
            scanf("%d",&guess[i]);
        }
    }
    printf("%4d %4d %4d %4d\n",guess[0],guess[1],guess[2],guess[3]);
    
    //判断数字、位置是否相同并计数
    for ( i = 0; i < 4; i++) {
        if (guess[i] == number[i]) {
            countA++;
            continue;
        }
        for (int j = 0; j < 4; j++) {
            if (i == j) {
                continue;
            } else if (guess[i] == number[j]){
                countB++;
            }
        }
    }
        printf("一共有 %dA,%dB\n",countA,countB);

        //判断游戏是否应该结束
        if (countA == 4) {
            printf("恭喜您!游戏成功\n");
            getchar();
            getchar();
            exit(EXIT_SUCCESS);
        }
        count--;
        printf("还有%d次机会\n",count);
		printf("*******************************************\n");
    }while (count > 0);
    
    printf("次数用完,游戏失败\n");
	printf("正确数字为:%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);
	getchar();
	getchar();
    return 0 ;
 
}

这个代码是存在很多不足的,我在经过这两天学习之后,主要进行了四个修改。

1.产生不同的随机数部分

这是整个代码最傻的部分,我第一次编写时考虑使用for循环比较下标来保证数据不重复,但一直没办法实现,所以用了一个很傻的方法来使它不重复,实际上是不可取的。后来发现可以通过与一个临时变量比较来实现,代码如下:

 //产生不同的随机数
	srand(time(NULL));
    int number[4];
    
    for (int i = 0; i < 4; i++) {
        //定义一个temp存放随机数
        int temp = rand() %9+1;
        
        //判断是否为第一个数
        if (i == 0) {
            //是第一个数,直接存放
            number[i] = temp;
        } else {
            
            //不是,将temp与先前的数进行比较
            for (int j = 0; j < i; j++) {
                if (number[j] == temp ) {
                    //相同,退出循环,重新生成temp
                    i--;
                    break;
                } else{
                    //不同,直接存放
                    number[i] = temp;
                }
            }
        }
    }
    
    printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);

用这个方法就不会显得那么傻,而且可以借鉴到其他地方

 

2.判断数字、位置是否相同并计数部分

这一部分乍一看没问题,其实可以更加简化,也更方便理解,代码如下:

        //判断数字、位置是否相同并计数
        for (i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {            
                //判断数字是否相同
                if (guess[i] == number[j]){
                    //数字相同,判断位置是否相同
                    if (i == j) {
                        //位置相同,A+1
                        countA++;
                    } else{
                       //位置不同,B+1
                        countB++;
                    }
                }
            }
        }
        printf("一共有 %dA,%dB\n",countA,countB);
        

 

3.将随机数按从小到大排列部分

这个部分主要是在两个数据交换位置时,通过两个数据相互加减的方法来交换虽然不需要引入第三个变量,但是增加了运算,使效率变低,也显得不够简单,因此最后改为引入第三个变量进行交换。

4.对countA、countB的定义部分

将 int countA和int countB放进了do...while循环中,造成了重复定义,这实际上是不够严谨的,于是将这两个变量的定义提到外部,并在循环的最后将其清零。

修改后的所有代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
    
    //提示游戏规则
    printf("****************************************************\n");
    printf("*********************游戏规则***********************\n");
    printf("系统将随机生成四个不同的有序数字(按从小到大排列)\n");
    printf("请输入您猜测的四个数字\n");
    printf("用A表示数字正确且位置正确的个数\n");
    printf("用B表示数字正确但位置不正确的个数\n");
    printf("一共有八次机会\n");
    printf("****************************************************\n");
    
    
    //产生不同的随机数
    srand(time(NULL));
    int number[4];
    
    for (int i = 0; i < 4; i++) {
        //定义一个temp存放随机数
        int temp = rand() %9+1;
        
        //判断是否为第一个数
        if (i == 0) {
            //是第一个数,直接存放
            number[i] = temp;
        } else {
            
            //不是,将temp与先前的数进行比较
            for (int j = 0; j < i; j++) {
                if (number[j] == temp ) {
                    //相同,退出循环,重新生成temp
                    i--;
                    break;
                } else{
                    //不同,直接存放
                    number[i] = temp;
                }
            }
        }
    }
    //这一句是为了检查数据是否重复,真正编译时应该删掉
    printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);
    
    //将随机数按从小到大排列
    for( i = 0; i < 4; i++){
        for(int j = 0; j < i; j++)
        {
            if(number[i] < number[j]){
                //使用第三方变量更方便,也更有效率
                int temp = 0;
                temp = number[i];
                number[i] = number[j];
                number[j] = temp;
            }
        }
    }
    //这一句是为了检查是否正确排序,真正编译时应该删掉
    printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);
    
        
    //输入数据并判断
    int guess[4];
    int count = 8;
    int countA = 0;
    int countB = 0;
    
    do{
        /*
        int countA = 0;
        int countB = 0;   定义只定义一次,所以应该在外部定义
         */   
        
        //提示用户输入数据
        printf("请输入四个1~9的数字:\n");
        for (int i = 0; i < 4; i++) {
            scanf("%d",&guess[i]);
            
            //判断数据是否在1-9区间内
            while (guess[i] < 1 || 9 < guess[i]) {
                printf("输入数据有误,请重新输入\n");
                scanf("%d",&guess[i]);
            }
        }
        printf("%4d %4d %4d %4d\n",guess[0],guess[1],guess[2],guess[3]);
        
        //判断数字、位置是否相同并计数
        for (i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                //判断数字是否相同
                if (guess[i] == number[j]){
                    //数字相同,判断位置是否相同
                    if (i == j) {
                        //位置相同,A+1
                        countA++;
                    } else{
                        //位置不同,B+1
                        countB++;
                    }
                }
            }
        }
        printf("一共有 %dA,%dB\n",countA,countB);
        
        //判断是否全部猜中
        //全部猜中,游戏结束
        if (countA == 4) {
            printf("恭喜您!游戏成功\n");
            getchar();
            getchar();
            exit(EXIT_SUCCESS);
        }
        
        //没猜中,次数-1,A、B清零
        count--;
        countA = 0;
        countB = 0;
        printf("还有%d次机会\n",count);
    }while (count > 0);
    
    //机会用完,游戏结束
    printf("次数用完,游戏失败。\n");
    getchar();
    getchar();
    return 0 ;
    
}

其实这个程序还有不完善的地方,比如说没有考虑用户输入相同数字时的处理等,但题目所需要的功能已经实现,玩一玩还是挺有意思的

guessing and betting number game The user starts with 100 dollars, and is able to bet and guess until they quit or have no more money. In each turn, they are asked for a bet. If they enter 0, then the program should give a farewell message and quit. The bet must be positive and within their available balance, If they enter incorrectly, the program should set the bet to their balance and tell them this. Once a bet is entered, they must pick a number between 1 and 10 (you do not need to errorcheck or correct this). This guess is then compared to a number the computer randomly generates each time (also between 1 and 10). If the guess is correct, the user wins the amount of their bet. If the guess is incorrect, the user will lose their bet divided by 5 and multiplied by the distance from the correct number - e.g. if the bet is 50, the computer’s number is 5 and the user guesses 7, then the user will lose 20 dollars( 50/5 * (7-5) = 20 ). However, they should not lose more than their balance, so if their balance is 50, the bet is 40, the computer’s number is 1 and the user guesses 10, (40/5 * (10-1) = 72 > 50 )then they should lose 50. After each turn, the program should display that turn's winnings (or loss amount) and the new balance,and then repeat the game until the user either quits or has no money left. Dollar values should be formatted in the standard way with two decimal places and a $ in front. Sample output from the program is below. You should make your program match this exactly (except for your name). An appropriate welcome message with your name in it should be shown at the start of the program. Assignment 1 : Guessing Game Written by yourname Please enter your bet (up to $100.00): $50 Guess a number between 1 and 10: 5 Correct! You win $50.00 Your new balance is $150.00 Please enter your bet (up to $150.00): $200 Your bet is $150.00 Guess a number between 1 and 10: 6 Wrong! The computer chose: 4 You lose $60.00 Your new balance is $90.00 Please enter your bet (up to $90.00): $80 Guess a number between 1 and 10: 1 Wrong! The computer chose: 7 You lose $90.00 Thank you for playing! Press any key to continue . . . Another Sample: CP1200 Guessing Game Written by Lindsay Ward Please enter your bet (up to $100.00): $-20 Your bet is $100.00 Guess a number between 1 and 10: 5 Wrong! The computer chose: 2 You lose $60.00 Your new balance is $40.00 Please enter your bet (up to $40.00): $10.50 Guess a number between 1 and 10: 12 Wrong! The computer chose: 2 You lose $21.00 Your new balance is $19.00 Please enter your bet (up to $19.00): $0 Thank you for playing! Press any key to continue . . . srand( static_cast<int>(time(0))) ; 初始化 computerNumber = 1 + rand( ) % 10 ; 产生随机数 cout << fixed << setprecision(2) ; 控制输出显示2位小数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值