公牛和母牛竞猜游戏《c++程序设计原理与实践》第5章习题12,13

原题目:

程序随机生成4个 0到 9之间的整数,作为神秘数字。玩家通过反复的猜测找到这4个数。并且要求先后顺序也要正确,数值和位置都正确是公牛,数值正确,位置不对是母牛。

例如:神秘数字是 1234 ,而玩家猜测的是 1355,程序的反馈结果是“一头公牛 一头母牛”。

通过网上的资料追加要求:如果相同的母牛重复出现多次只能算一个母牛,不能重复计次

例如:神秘数字是 1234 ,玩家猜测的是 2222,程序的反馈是“一头公牛 一头母牛”,而不是“一头公牛 三头母牛”。


解题思路:

1,为了方便玩家对4个数字的输入,可以把数字存储为字符串类型,这样数字输入时中间不用留空格,能一次性对4个数字全部读取。

2,公牛和母牛很容易辨别,关键是相同的母牛多次出现只能计一次,不能重复计次。

3,为了避免相同母牛的重复计次,只需要在确定该数值是母牛后,把神秘数字里面与该值相同的数屏蔽掉,这样下次再遇到这个数值时就会跳过,不会重复计次了。

4,屏蔽时为了不改变其它数值的位置,可以把该值设置为0到9以外的任意一个字符(我设为一个空格)。

5,第3,4步修改的不能是神秘数字的原数据,因为这样会对公牛的确认造成麻烦,所以要有一个神秘数字的复本,确认母牛时和神秘数字的复本比较,确认公牛时直接和原数据比较。

特别提醒:本代码只是简单的暴力求解,不含任何算法,不含任何特殊的数据结构。因为我是新手,网上那些什么哈希表等方法,我都是看不懂的。


代码如下:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<stdexcept>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#include<limits>
using namespace std;

int get_niu(string secret,string guess) //计算公牛和母牛数量的函数
{
    int ox,cow;
    ox=cow=0;
    string c;
    c=secret;
    for(int i=0; i<4; i++)
    {
        if(guess[i]==secret[i]) //和secret字符串比较,来确定公牛
            ox++;
        else
        {
            for(int n=0; n<4; n++) //不是公牛就和secret的复本c比较,来确定是否是母牛
            {
                if(guess[i]== c[n]) //如果是母牛,则母牛数量+1,并且再次遇到这个值时跳过检测
                {
                    cow++;
                    c[n]=' ';
                    for(int j=n+1; j<4; j++)
                        if(c[j]==guess[i])
                            c[j]=' ';
                    break;
                }
            }
        }
    }
    if(ox==4)
        cout<<"\n4头公牛\n";
    else
        cout<<endl<<ox<< "头公牛 "<<cow<< "头母牛\n";
    return ox;
}

int main()
{
    cout<<"\t\t公牛和母牛\n\n";
    srand(time(NULL)); //置随机数种子
    
    cout<< "输入任意字符开始游戏,q退出\n";
    char n;
    while(cin>>n)
    {
        cin.ignore(numeric_limits<streamsize>::max(),'\n'); //清空输入行
        if(n=='q')
            return 0;
        string secret;
        for(int i=0; i<4; i++) //设置4个随机数 并存储为secret字符串
           secret+= char(rand()%10+48);
        cout<<"显示本局的神秘数字,便于调试程序\n";
        cout<<"神秘数字为:"<<secret<<"\n\n";

        cout<< "是哪4个数?请输入(数字之间不要空格):";
        string guess;
        while(1)
        {
            cin>>guess;
            cin.clear(); //清除cin的错误标记
            cin.sync();  //清空输入缓冲区
            if(guess.size()!=4)
            {
                cout<< "长度不对,请重新输入(4个数字之间不留空格):";
                continue;
            }
            if(get_niu(secret,guess)==4)
                break;
            cout<< "再猜(数字之间不要空格):";
        }
        cout<< "\n恭喜你全部猜中!输入任意字符开始下一局,q退出\n";
    }
}


运行结果:



新知识总结:

1,cin.clear()  清空 cin 的错误标记

      cin.ignore(numeric_limits<streamsize>::max(),'\n')  清空输入行

      cin.sync()    清空输入缓冲区

2,参数为向量的函数声明:   void  abc(vector<int>& a,vector<char>& b)

引用时格式:  abc(a,b)  其中a,b为向量。 

3,string abc       abc就是一个空字符串

abc= "Hello world"

string efg

efg= abc      efg内容是“Hello world” ,在不改变 efg 数据的时候,efg 指向的内存地址和 abc 内存地址相同 (浅复制)

只有在改变efg 数据时,才会真正复制abc 的内容到新的 内存地址,不改变abc原数据。

4,random(n)   取随机数 范围:0到 n-1 之间

      random(m,n) 取随机数 范围:m 到 n-1 之间  ,需要编译器支持C++11 标准。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值