這次換人想題目給電腦猜,而且保證七次內可以猜的出來,想下載的人請點我,以後要跟別人玩猜數字遊戲就拿著個當外掛就好了XDD
這次費了我很大的功夫在想演算法,對於一個超級不會玩猜數字遊戲的人,要他想演算法實在是太吃力了……其實若要我自己來猜的話大概都要猜個40、50次才答對……最後我忍不住去請教隔壁寢的猜數字大神才知道猜數字的訣竅。(人家猜個五六次就猜出來了!)
既然已經知道訣竅,只要把方法化為程式碼就大功告成啦XD
另外值得一提的是,我用了一個新的防呆措施,運用do{}while(); 先讀取再判斷,如果使用者亂打就再重複一直讀取,讀取至使用者打對為止,這個方法我覺得很簡潔^^(自以為)
至於怎麼刪去不可能的答案組合成新的答案庫,是先判斷所有的答案(如果是一開始,當然,就要判斷5040次),找尋不可能的答案,找到之後,就把這個答案之後所有的答案往前遞移一個答案,這和隨機不重複用的是一樣的方法。
總之我覺得這是個滿好玩的題目^^
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
void intro(void); //介紹文函數
void prepare(void); //準備工作之函數
void ask(void); //電腦問之函數
void answer(void); //人類答幾a幾b之函數
void think(void); //電腦思考之函數(其實就是從答案庫中排除不可能的答案)
void menu(void); //選單之函數
int answerBase[5040][4]; /*答案庫,會裝入所有重複的四位數,從1234到9876
5040是因為10*9*8*7,4是因為每組答案是一個四位數*/
int isOver,restart; //當作布林值,判斷是否遊戲結束以及是否要繼續玩
int remain; //答案庫裡面的答案數
int a,b; //拿來裝使用者回答的幾a幾b
int randNum; //裝亂數,隨機從答案庫裡面拿答案
int main(void){
intro();
while(1==1){
prepare();
while(!isOver){
ask();
answer();
if(isOver) break;
think();
printf("------------------\n");
}
menu();
if(!restart) break;
}
getchar();
return 0;
}
/****** 準備工作之函數 ******/
void prepare(void){
int i,tmp,unit_1,unit_10,unit_100,unit_1000;
remain=5040;
tmp=0; //tmp只是一個拿來計數變數
isOver=0; //判斷結束與否
for(i=0;i<10000;i++){ //這個for產生答案庫
unit_1 = (i/1)%10; //以下四行把四位數拆成四個各位數分別存到四個變數
unit_10 = (i/10)%10;
unit_100 = (i/100)%10;
unit_1000 = (i/1000)%10;
if(unit_1!=unit_10 && unit_1!=unit_100 && unit_1!=unit_1000 && unit_10!=unit_100 && unit_10!=unit_1000 && unit_100!=unit_1000){
answerBase[tmp][0] = unit_1000;
answerBase[tmp][1] = unit_100;
answerBase[tmp][2] = unit_10;
answerBase[tmp][3] = unit_1;
tmp++;
}
}
}
/****** 電腦問之函數 ******/
void ask(void){
int i;
printf("大兜蟲:請問是");
srand(time(0));
while(1==1){
randNum=0;
for(i=0;i<4;i++){
randNum *= 10;
randNum += rand()%10;
}
if(randNum<remain) break;
}
for(i=0;i<4;i++) printf("%d",answerBase[randNum][i]);
printf("?\n");
}
/****** 人類答之函數 ******/
void answer(void){
char input[500];
int right=0; //當布林值,判斷是否正確的輸入
do{ //取得a,b值
do{ //取得a值
printf("A:");
fgets(input,sizeof(input),stdin);
*(input+strlen(input)-1)='\0';
if(strlen(input)==1 && *input-'0'<= 9 && *input-'0'>=0){
a = *input-'0';
right = 1;
}else printf("輸入錯誤\n\n");
}while(!right);
do{ //取得b值
printf("B:");
fgets(input,sizeof(input),stdin);
*(input+strlen(input)-1)='\0';
if(strlen(input)==1 && *input-'0'<= 9 && *input-'0'>=0){
b = *input-'0';
right = 1;
}else printf("輸入錯誤\n\n");
}while(!right);
if(a+b>4){ //如果a和b相加大於4當然就錯啦~
printf("輸入錯誤\n\n");
right = 0;
}
}while(!right);
if(a==4){
printf("大兜蟲:耶~答對了!\n");
isOver=1;
}else if(remain==1){ //如果答案庫只剩一個答案,但是這答案還是錯的,就是玩家作弊!
printf("大兜蟲:你作弊!= =+\n");
isOver=1;
}
}
/****** 電腦思考之函數 ******/
void think(void){
int i,j,k,aa,bb;
int refer[4];
for(i=0;i<4;i++){
refer[i]=answerBase[randNum][i];
}
for(i=0;i<remain;i++){
aa = bb = 0; //填裝a值和b值,但要區別於之前的人類輸入的a值b值
for(j=0;j<4;j++){ //以下兩個for用來比對第i個答案和亂數取的答案的是幾a幾b
for(k=0;k<4;k++){
if(answerBase[i][j]==refer[k]){
if(j==k) aa++;
else bb++;
}
}
}
if(!((aa==a)&&(bb==b))){ //把a值b值相等的答案保留下來
for(j=i;j<remain;j++){ //開始搬運
for(k=0;k<4;k++){
answerBase[j][k]=answerBase[j+1][k];
}
}
remain--;
i--;
}
}
if(remain==0){ //發現沒有答案符合玩家想的數字,就是玩家作弊!
printf("大兜蟲:你作弊!= =+\n");
isOver=1;
}
}
/****** 選單之函數 ******/
void menu(void){
char input[500];
int right = 0;
do{
printf("大兜蟲:是否重新?y/n");
fgets(input,sizeof(input),stdin);
*(input+strlen(input)-1)='\0';
if(strlen(input)==1 && (*input == 'y' || *input == 'Y')){
printf("\n------------------\n");
restart = 1;
right = 1;
}else if(strlen(input)==1 && (*input == 'n' || *input == 'N')){
printf("大兜蟲:遊戲結束,拜拜~~");
restart = 0;
right = 1;
}else printf("輸入錯誤\n\n");
}while(!right);
}
/****** 介紹函數 ******/
void intro(void){
printf("***************************************************\n");
printf("***************************************************\n");
printf("** **\n");
printf("** 大兜蟲猜數字遊戲(猜人) ver1.0 **\n");
printf("** **\n");
printf("** 遊戲規則: **\n");
printf("** 1.每回合大兜蟲會猜一個四位數字 **\n");
printf("** 2.A的次數代表大兜蟲猜對了幾個數字且位置正確 **\n");
printf("** 3.B的次數代表大兜蟲猜對了幾個數字但位置不對 **\n");
printf("** 4.你必須告訴大兜蟲A和B的值 **\n");
printf("** 5.七回合內必可猜出答案 **\n");
printf("** 6.Enjoy! **\n");
printf("** **\n");
printf("***************************************************\n");
printf("***************************************************\n");
}