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) 自动版的主要内容,如果未能解决你的问题,请参考以下文章

c++ 珠玑妙算(mastermind) 自动版

c++ 珠玑妙算(mastermind) 自动版

C++ AI解珠玑妙算(mastermind)算法

C++ AI解珠玑妙算(mastermind)算法

C++ AI解珠玑妙算(mastermind)算法

C++ AI解珠玑妙算(mastermind)算法