帮忙解释一下实在看不懂

猜数字,计算机随机生成1个3位或4位的十进制整数,各个数位上的数字各不相同,用户给出猜测,计算机回答XAYB(X个位置和数字猜中,Y个数字猜中但位置错误),重复用户猜计算机回答的过程,直到猜中为止(3A0B,4A0B)。

这里,将给出若干组相关的数据供猜测(即第i把猜123,第j把不可能是123)。比谁的程序猜测的总次数最少。

文件“猜数字测试代码.txt”是给学生的,函数int guess(int A,int B)是学生需要完成的,其中参数A和B就是计算机根据上次猜测返回的结果,若是3A0B(以猜3个数为例),表示新一把猜测的开始。目前,guess中的代码,可供人机交互,学生提交时应该删除。

代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define M 4 //猜几个数字
 //交换
 void swap(inta,intb)
 {
    int t=a;
        a=b;
        b=t;
 }
 //将数组随机打乱
 void random_shuffle(int
a,int n)
 {
    int i;
     for(i=0;i<n;i++)
    {
        int x=rand()%n;
        int y=rand()%n;
        if(x!=y) swap(a+x,a+y);
    }
 }
 //生成数位不重复的M位全部数据,存在数组a中,并打乱,备用
 int  gen(int
a)
 {
    int count=0,i,j;
    int max=1;
    for(i=0;i<M;++i,max
=10);
        for(i=0;i<max;++i)
        {
            int flag[10]={0};
            int t=i;
            for(j=0;j<M;++j)
                if(flag[t%10]) break;
                else flag[t%10]=1,t/=10;
    if(j==M)
        a[count++]=i;
    }
    random_shuffle(a,count);
    return count;
}
 void test(int answer,int player,int
A,int* B)
 {
    int i=0,j;
    int answer_a[M]={0},player_a[M]={0};
    A=B=0;
    while(answer||player)
    {
        answer_a[i]=answer%10;
        player_a[i++]=player%10;
        answer/=10;
        player/=10;
     }
    for(i=0;i<M;++i)
    for(j=0;j<M;++j)
        if(player_a[i]answer_a[j])
            if(i
j) ++A;
            else ++B;
}
 //参数AB是上一轮猜测的反馈,
 //如果得到猜中的信息表示下一把的开始
 int guess(int a,int n)
 {
 //你的工作在这个函数
        int A=M,B=0,OA;
        int count_cur=0;
        int i,j,num,p;
        char arr[5],new_arr[5],ch;
        int flag[4]={0};
        printf(“The answer is %d\n”,a[n]);//先给出答案,用以验证
        for(i=0,j=0;i<10;i++,++count_cur)
        {
            if(4==M)
                num=i
1111;
            else
                num=i
111;
            test(a[n],num,&A,&B);
            printf("%d:%0
d,%dA%dB\n",count_cur,M,num,A,B);
            if(A1) arr[j++]=i+48;
            if(M
j) break;
        }//经此for循环,得出要猜的数由哪些数字组成
        arr[M]=0;//尾0
        num=atoi(arr);
        //printf("%d",numA);
        test(a[n],num,&A,&B);
        count_cur++;
        printf("%d:%0
d,%dA%dB\n",count_cur,M,num,A,B);
        OA=A;//标记上一次猜测的数的位置与数都正确的个数
        if(AM&&B0)
        {
            printf(“答案是%s\n”,arr);
            return count_cur;
        }//如果猜测与答案一样,显示答案,返回猜测步数
        p=0;
        for(i=0;i<M;i=p)
        {
            strncpy(new_arr,arr,M);
            new_arr[M]=0;
            if(0flag[i])//定义数组flag初始为0,表示对应下标的位置不正确,正确了后置1
            {
                for(j=i+1;j<M;j++)
                {
                    if(0
flag[j])
                    {
                        new_arr[j]=arr[i];
                        num=atoi(new_arr);
                        //printf(“num=%d\n”,num);
                        count_cur++;
                        test(a[n],num,&A,&B);
                        printf("%d:%0
d,%dA%dB\n",count_cur,M,num,A,B);
                        if(A>OA) //arr[i]在此次j位上,交换
                        {
                            flag[j]=1;
                            ch=arr[j];
                            arr[j]=arr[i];
                            arr[i]=ch;
                            num=atoi(arr);
                            count_cur++;
                            test(a[n],num,&A,&B);//交换之后0A有可能在原基础上加1,也可能加二,所以直接调用test算出准确OA
                            printf("%d:%0*d,%dA%dB\n",count_cur,M,num,A,B);
                            OA=A;
                            p=i;
                            break;
                        }
                        else if(A<OA) //说明此位置原本数对应正确的位置,不可改变,对应下标置1
                        {   
                            flag[j]=1;
                            new_arr[j]=arr[j];
                        }
                    }
                }//找正确位置
                if(M==j)
                {
                    flag[i]=1;
                    p=i+1;
                }//一轮for循环,没找到正确位置,说明本身所在的位置是正确的。
            }
            else p=i+1;
            //printf(“p=%d\n”,p);
        }
        printf(“答案是%s\n”,arr);
        return count_cur;
 }
 int main()
 {
    int i;
 //初始生成数据
    int len;
    int a;
    int  n=3,nn=n;//玩n把
    int count=0;//总猜测次数
    for(len=1,i=0;i<M;++i)
    len
=10-i;
    a=(int *)malloc(sizeof(int)*len);   
    srand((unsigned)time(NULL));
    //srand(2);
    gen(a);
 //开玩
    while(n–)
    {
        int count_cur=0;
     //每把从猜中开始,例如玩4个数,4A0B为猜中,
//此时进入下一把,会有新的数供猜测
 //printf("%d\n",a[n]);
        count_cur=guess(a,n);
        printf(“此轮共%d步完成\n”,count_cur);
        count+=count_cur;
    }
    printf(“游戏结束,共计%d轮游戏,总消耗%d步\n”,nn,count);
    system(“pause”);
    return 0;
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值