/* bullcow4.c -- 這是 BULL& COW 程式 -- 電腦想, 人來猜 這程式在這: ftp.csie.nctu.edu.tw 程式設計 /pub/CSIE/course/cs2/bullcow4.c 或是由本系 ccsun?? 直接 cp /net/ftp/pub/CSIE/course/cs2/bullcow4.c . 自己寫不下出的才看...其實只是把之前給大家的兩程式整合: * * * 整合 bullcow2.c + bullcow3.c gcc bullcow4.c ./a.out * * * 重點: How to generate a random number in 0..9 ? How to generate four different digits? How to find out ?A ?B *************************************************/ #include #include #include #define repeat do{ #define until(x) }while(!(x)) char myNum[6], yourGuess[6]; char yesno[33]; int nbull, ncow; void think(char[]); /* 這要傳參數 */ void getAnswer(); /* 這不傳, 用 global 變數 yourGuess[] */ void checkAnswer(char[], char* , int *nb, int* nc); int isError(char*); int main() { printf("這是公牛母牛遊戲, 請輸入 4位不同數字猜我想的數\n"); printf("我將告訴你幾隻公牛 幾隻母牛\n"); printf("公牛 means 數字對位置也對\n"); printf("母牛 means 數字對但位置不對\n"); printf("輸入負數表示放棄, 不玩了\n"); repeat printf("讓我想好四位數字...\n"); think(myNum); // 填入 myNum while(1) { printf("Your guess:"); do { getAnswer(); // readinto yourGuess }while( isError(yourGuess) ); // till a legal answer if( feof(stdin) || (yourGuess[0] == '-' ) ){ printf("答案是 ... %s\n", myNum); clearerr(stdin); /* reset */ break; } checkAnswer(myNum, yourGuess, &nbull, &ncow); if(nbull == 4){ printf("恭喜猜對了\n"); break; } printf("%d 隻公牛, %d 隻母牛\n", nbull,ncow); } printf(" 繼續玩(yes/no)? "); gets(yesno); /* 讀取回答進 yesno */ until( (yesno[0] == 'n') || (yesno[0]=='N') ); printf("\nBye\n"); } /*********END of Main Program *************/ /****** ** 函數 think() 用來想一個四位不重複的數字 ** 用 rand() 或 random() 生出亂數, see "man rand", "man random" ** 函數 getAnswer() 用來讀入一個四位不重複的數字, 放 yourGuess[] 中 不傳參數, 直接用 yourGuess (global 變數) 你要用像 think(myNum) 那樣有參數的寫法也可以啦 ** 函數 checkAnswer() 也很簡單 用 loop 比比看到底 前兩參數 (都是 char array) 中有幾位數字同且位置同 又有幾位數的數字同但是位置不同 更進一步練習題: 寫一個電腦會猜人想的 公牛母牛遊戲 **** 再來, 寫成人和電腦輪流對猜 *******************************************************************/ void getAnswer() { printf("Guess:"); fgets(yourGuess,5,stdin); /** fgets(buf, k, ... reads k-1 char **/ } /*******************************************************/ void checkAnswer(char x[], char*y , int *nb, int*nc) { /** dummy array 寫成 char x[] 或 char*x 都一樣意思 **/ int i,k; *nb = *nc =0; for(i=0; i<=3; i++){ /* 算出公牛 */ if(x[i] == y[i]) *nb = *nb +1; /* 再來算母牛 */ for(k=0; k<=3; k++) if(x[i]==y[k]) *nc += 1; } *nc -= *nb; /* 扣掉多算的 */ } /*******************************************************/ int myRandom(); /* declare */ void think(char *myNum) { int k, x, seed; myNum[4] = 0; /* same as '\0' */ /****** 去掉這列再 run 看看 ****** 會變成 true random 而不是 pseudo random seed = (int) time(0) & 0xffff; // 抓系統時間並只留下右邊 16 bits srand( seed ); /*** set seed, see "man srand", "man 3 time" ***/ /*** time() returns the time since 00:00:00 GMT, Jan. 1, 1970, measured in seconds. **************************/ #ifdef DEBUG printf("seed=%d===\n", seed); /***/ #endif myNum[0] = myRandom(); /* myRandom() 會傳回 0..9 之一 */ repeat x= myRandom(); until (x != myNum[0]); myNum[1] = x; x= myRandom(); while( x== myNum[0] || x == myNum[1]) /* 注意條件 */ x= myRandom(); myNum[2] = x; repeat x= myRandom(); until ( (x != myNum[0]) && x!= myNum[1] && x!= myNum[2]); myNum[3] = x; for(k=0; k<=3; k++) myNum[k] += '0'; /* convert to ASCII */ printf("我想好的是: %s\n", myNum); } int myRandom(){ int ans= rand(); /* C 的標準 function */ return ans % 10; /* 0..9 */ } int isError(char* x){ /* 看輸入有沒非數字或是有沒相同數字 */ return 0; /* assume no error */ }