一、遊戲介紹
猜數字(又稱 Bulls and Cows )是一種古老的的密碼破譯類益智類小遊戲,起源於20世紀中期,一般由兩個人或多人玩,也可以由一個人和電腦玩。一方出數字,一方猜。出數字的人要想好一個沒有重複數字的4個數,不能讓猜的人知道。猜的人就可以開始猜。每猜一個數字,出數者就要根據這個數字給出幾A幾B,其中A前面的數字表示位置正確的數的個數,而B前的數字表示數字正確而位置不對的數的個數。如正確答案爲 5234,而猜的人猜 5346,則是 1A2B,其中有一個5的位置對了,記爲1A,而3和4這兩個數字對了,而位置沒對,因此記爲 2B,合起來就是 1A2B。接着猜的人再根據出題者的幾A幾B繼續猜,直到猜中(即 4A0B)爲止。
二、算法
程序首先生成四個互不相同的位於0-9之間的隨機數,根據輸入的數據,將兩者進行對比,給出A和B的值。
程序使用std::array<uchar,4>
來存儲這四個數字,並且定義一個結構體Result
來存儲A和B的值。將這些數據及相應的操作整合到GDigit
類中
三、程序代碼
1、GDigit.h
該文件包含結構體Result
、GDigit
類及其它必要的數據結構的定義。
/* the definition of GDigit class
* writen by Liangjin Song on 20200122
*/
#ifndef GDIGIT_H
#define GDIGIT_H
#include <array>
using uchar=unsigned char;
using Digit=std::array<uchar,4>;
struct Result{
uchar A;
uchar B;
};
class GDigit
{
private:
Digit digit;
public:
GDigit()=default;
~GDigit()=default;
public:
// initial the digits
void initial();
// check if the four numbers are different from each other
bool different(Digit& guess) const;
// check the result
Result check(Digit& guess) const;
// get the digit
const Digit& get() const {return digit;}
bool finish(Digit& guess) const {return digit[0]==guess[0] && digit[1]==guess[1] && digit[2]==guess[2] && digit[3]==guess[3];}
};
#endif // GDIGIT_H
2、GDigit.cpp
該文件包含GDigit
類的具體實現。
/* the definition of GDigit class
* writen by Liangjin Song on 20200122
*/
#include "GDigit.h"
#include <random>
#include <ctime>
void GDigit::initial()
{
// initialize four numbers, and
// make the four numbers different from each other.
using engine=std::default_random_engine;
using uniform=std::uniform_int_distribution<int>;
// the first number
engine rnd((unsigned)time(NULL));
uniform dis(0,9);
engine rndp((unsigned)time(NULL));
uniform disp(10,20);
int i, loop=disp(rndp);
for(i=0;i<loop;++i){
dis(rnd);
}
digit[0]=dis(rnd);
// the second number
do{
digit[1]=dis(rnd);
}while(digit[1]==digit[0]);
// the third number
do{
digit[2]=dis(rnd);
}while(digit[2]==digit[0] || digit[2]==digit[1]);
// the forth number
do{
digit[3]=dis(rnd);
}while(digit[3]==digit[0] || digit[3]==digit[1] || digit[3]==digit[2]);
}
bool GDigit::different(Digit& guess) const
{
// check if the four numbers are different from each other
bool same;
same=guess[0]==guess[1] || guess[0]==guess[2] || guess[0]==guess[3];
same=same || guess[1]==guess[2] || guess[1]==guess[3];
same=same || guess[2]==guess[3];
return !same;
}
Result GDigit::check(Digit& guess) const
{
// check the result
Result res;
res.A=0;
res.B=0;
uchar i,j;
for(i=0; i<4; ++i){
for(j=0; j<4; ++j){
if(guess[j]==digit[i]){
if(i==j){
++res.A;
}
else{
++res.B;
}
}
}
}
return res;
}
3、main.cpp
C++控制檯程序的main函數。
/* main function
* writen by Liangjin Song on 20200122
*/
#include "GDigit.h"
#include <iostream>
using namespace std;
int main()
{
GDigit gdigit;
gdigit.initial();
Digit guess;
Result res;
do{
do{
cout<<"Please input four unique digits:"<<endl;
cin>>guess[0]>>guess[1]>>guess[2]>>guess[3];
for(auto &i : guess){
i-=0x30;
}
}while(!gdigit.different(guess));
res=gdigit.check(guess);
cout<<static_cast<int>(res.A)<<"A"<<static_cast<int>(res.B)<<"B"<<endl;
}while(!gdigit.finish(guess));
cout<<endl;
return 0;
}
四、運行結果
控制檯下的運行效果如下。
五、圖形界面
使用MFC製作圖形界面,代碼鏈接爲:猜數字遊戲MFC源代碼,其運行效果如下圖。
六、注意
程序使用了C++11特性,編譯器需支持C++11。