猜数字小游戏

    最近,佳颖同学给我玩了一个小游戏,一个猜数字的小游戏。就是,先随机产生4个0-9之间不同的数字,然后玩家去猜,对于玩家每次猜的数字,系统会提示玩家XA和YB,其中,XA代表有X个数字和位置都猜对了,YB代表有Y个数字猜对了但位置不对。玩家根据系统的提示思考下一步要猜的数字,然后系统会接着给出提示。直到玩家猜出数字为止!
然后,我就写了一个这个游戏的页面。挂在自己的阿里云服务器上,所以没有域名哈。http://120.78.49.136/Uguess/index.php/Index/index
故事到这里就结束了吗,不是的。我感觉挺难猜的,还要去推理,所以索性就去写了一个C++代码,来提示我下一步应该要猜的数字。
解决这个问题的思路是:
由于答案可能是A(10,4)种排列中的一个,所以,先预处理出这5040个排列,然后假设第一次猜的是"1234",这样系统就会得到一个tip,然后将这个猜的数字和对应的tip保存起来。接着,就可以枚举每一个排列,并与猜过的数字以及相应的tip做匹配,找出与所有猜过的数字以及相应的tip能匹配的第一个排列作为提示。提示下一次用户应该猜什么。然后又获取这个数字相应的提示存储起来。不断进行这个过程,就可以猜出答案,是不是很暴力啊,哈哈哈哈。一般来说,6,7次就可以猜出来了。
下面是解决问题的C++代码。
#include<bits/stdc++.h>
using namespace std;
struct node
{
	string num,ans;
}a[15];
int aPos,win=0;
string allNum[50000];
int vis[15],allPos=0;
int judge(string a,string b,string ans)
{
	int cnt1=0,cnt2=0;
	for(int i=0;i<a.size();i++)
	{
		if(a[i]==b[i]) cnt1++;
	}
	for(int i=0;i<a.size();i++)
	{
		for(int j=0;j<b.size();j++)
		{
			if(a[i]==b[j]) cnt2++;
		}
	}
	cnt2-=cnt1;
	if(ans[0]-'0'==cnt1&&ans[2]-'0'==cnt2) return 1;
	return 0;
}
int check(string b)
{
	for(int i=0;i<aPos;i++)
	{
		if(judge(a[i].num,b,a[i].ans)==0) return 0; 
	}
	return 1;
}
string getNext()
{
	for(int i=0;i<allPos;i++)
	{
		string s=allNum[i];
		if(check(s.substr(0,4))) return s.substr(0,4);
	}
}

void dfs(int d,string s)
{
	if(d==4)
	{
		allNum[allPos++]=s;
		return ;
	}
	for(int i=0;i<10;i++)
	{
		if(!vis[i])
		{
			vis[i]=1;
			dfs(d+1,s+char(i+'0'));
			vis[i]=0;
		}
	}
}
void init()
{
	dfs(0,"");
	//for(int i=0;i<allPos;i++) cout<<allNum[i]<<endl;
	//cout<<allPos<<endl;
}
int main()
{
	init();
	string guess="1234",num,ans;
	while(!win)
	{
		cout<<"you can guess :"<<guess<<endl;
		//cin>>num;
		cout<<"next input a tip :";
		cin>>ans;
		a[aPos].num=guess;
		a[aPos].ans=ans;
		aPos++;
		guess=getNext();
	}
	return 0;	
} 

下面是一组实测

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值