c++ 珠玑妙算(mastermind) 自动版
Posted 传说C罗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++ 珠玑妙算(mastermind) 自动版相关的知识,希望对你有一定的参考价值。
珠玑妙算游戏规则:随机生成一串长度为4的密码,每一位由0~9中的任意数字组成,同一个数字运行多位重复使用。举例:1234,4352,4232,3233......;
程序由三个函数组成:
string set():返回一个随机生成是字符串,也就是四位数的密码。
bool eval(string code,string guess,int &rr,int &rw):接收密码和猜测,判断真猜中数和伪猜中数,如果真猜中数为4返回真,其他返回假。其中code为游戏生成的密码,guess为玩家给出的猜测。rr为真猜中数,rw为伪猜中数。
string AI(int rr,int rw): 该函数为AI解题函数。每次被呼叫时,会通过参数中的真伪猜中数来判断出新的猜测,然后会以string的形式返回该猜测。具体算法在我的上一篇博客。
程序:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <iomanip>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
//Function Prototypes
string AI(int,int);
bool eval(string,string,int &,int &);
string set();
int main(int argc, char** argv) {
//Set the random number seed
srand(static_cast<unsigned int>(time(0)));
//Declare variables
string code,guess; //code to break, and current guess
int rr,rw; //right digit in right place vs. wrong place
int nGuess; //number of guesses
//Initialize Values
nGuess=0;
code=set();
rr=rw=0;
//Loop until solved and count to find solution
do{
nGuess++;
guess=AI(rr,rw);
}while(eval(code,guess,rr,rw));
//Check evaluation
cout<<nGuess<<" "<<code<<" "<<guess<<endl;
//Exit the program
return 0;
}
string AI(int rr,int rw){
static const int SIZE=10000;//How many guesses to save
static string gHistory[SIZE];//guess history
static int rHistory[SIZE];//result history
static int hisCount=0;// history counter
static string sGuess="0000"; //Size the guest string
static int guessNum=0;
static char bit[4];
static int bitSize=4;
static int bitNum=0;
static vector<string> guessBase;
static bool once=true;
static bool beforeSecondStep=false;
//第一步:迭代返回0-9,求出四位数字
if(bitNum<4)
{
if(rr>0)
{
for(int i=0;i<rr;i++)
{
bit[bitNum]=sGuess[1];
bitNum++;
}
}
if(bitNum<4)
{
for(int i=0;i<4;i++)
{
sGuess[i]=guessNum+'0';
}
}
}
//当四位数字都找到时,进入第二步:
if(bitNum>=4)
{
vector<string>::iterator it;
if(once) //进入第二步后,首先把四位数字全排列,所有排列组合将被存入名为guessbase的容器中
{ //由此到156行为全排列算法
for(int i=0;i<4;i++)
{
for(int j=i+1;j<4;j++)
{
if(bit[i]==bit[j])
{
bitSize--;
}
}
}
for(int i=0;i<4;i++)
{
for(int j=0;j<3;j++)
{
if(bit[j]>bit[j+1])
{
char temp;
temp=bit[j];
bit[j]=bit[j+1];
bit[j+1]=temp;
}
}
}
string stemp=bit;
guessBase.push_back(stemp);
for(int i=3;i>0;i--) //permutation the bit[]
{
if(bit[i-1]<bit[i])
{
char minIdx=i;
for(int j=i;j<4;j++)
{
if(bit[j]>bit[i-1])
{
if(bit[j]<=bit[minIdx])
{
minIdx=j;
}
}
}
char temp;
temp=bit[minIdx];
bit[minIdx]=bit[i-1];
bit[i-1]=temp;
for(int j=i,k=3;j<k;j++,k--)
{
temp=bit[j];
bit[j]=bit[k];
bit[k]=temp;
}
stemp=bit;
guessBase.push_back(stemp);
i=4;
}
}
once=false;
}
//全排列结束,返回guessbase容器里的第一个元素,然后擦除
if(beforeSecondStep==false)
{
sGuess=guessBase[0];
it=guessBase.begin();
it=guessBase.erase(it);
beforeSecondStep=true;
}
else //下面进入到划分环节
{
gHistory[hisCount]=sGuess;
rHistory[hisCount]=rr;
hisCount++;
switch(rr) //当真猜中数为0和2时进行划分,其他猜中数不划分
{
case 0:
for(it=guessBase.begin();it!=guessBase.end();)
{
string temp=*it;
if(temp[0]==sGuess[0]||temp[1]==sGuess[1]||temp[2]==sGuess[2]||temp[3]==sGuess[3])
{
it=guessBase.erase(it);
}
else
{
it++;
}
}
break;
case 2:
if(bitSize==4||bitSize==3)
{
for(int i=0;i<hisCount;i++)
{
int rNum=0;
int idx=0;
if(rHistory[i]==2)
{
for(int j=0;j<4;j++)
{
if(gHistory[i][j]==sGuess[j])
{
rNum++;
idx=j;
}
}
if(rNum==1)
{
for(it=guessBase.begin();it!=guessBase.end();)
{
string temp=*it;
if(temp[idx]!=sGuess[idx])
{
it=guessBase.erase(it);
}
else
{
it++;
}
}
}
}
}
}
break;
default:
break;
}
sGuess=guessBase[0];
it=guessBase.begin();
it=guessBase.erase(it);
}
}
guessNum++;
//Return the result
return sGuess;
}
bool eval(string code,string guess,int &rr,int &rw){
string check=" ";
rr=0,rw=0;
//Check how many are right place
for(int i=0;i<code.length();i++){
if(code[i]==guess[i]){
rr++;
check[i]='x';
guess[i]='x';
}
}
//Check how many are wrong place
for(int j=0;j<code.length();j++){
for(int i=0;i<code.length();i++){
if((i!=j)&&(code[i]==guess[j])&&(check[i]==' ')){
rw++;
check[i]='x';
break;
}
}
}
//Found or not
if(rr==4)return false;
return true;
}
string set(){
string code="0000";
for(int i=0;i<code.length();i++){
code[i]=rand()%10+'0';
}
return code;
}
以上是关于c++ 珠玑妙算(mastermind) 自动版的主要内容,如果未能解决你的问题,请参考以下文章