//CowBull.java /*** CowBull.c -- 電腦猜人想的 Bull & Cow game * @CopyLeft by tsaiwn@csie.nctu.edu.tw ****************************************/ import java.io.*; class CowBull { public static void main(String xx[ ]) { new CowBull( ); } CowBull( ) { prepareIO( ); play( ); } CowBull(BufferedReader cin, PrintStream cout) { this.cin = cin; this.cout = cout; play( ); } BufferedReader cin; PrintStream cout; void prepareIO( ) { cin = new BufferedReader( new InputStreamReader( System.in ) ); cout = new PrintStream( System.out); } /// int possible[ ] = new int[5040]; // global variable int npsible; // global variable 記著有幾個可能答案 // int rand( ) { return (int) (Math.random( ) * 32767 ); } int play(){ int n, tmp, nguess, nbull, ncow; int yn, myGuess; //long now= time(0); //srand( now &0xffff); /* randomize, see "man srand" */ boolean quit = false; while( ! quit ) { //again: npsible = prepare_all_possible_answer(); // 放在 possible[5040] nbull = ncow = nguess = 0; while(nbull != 4) { // 由所有可能答案中隨便挑一個當 myGuess, 並印出說猜該數 // n = rand() % npsible; /* 0.. npsible -1 */ tmp = possible[0]; possible[0] = possible[n]; possible[n] = tmp; myGuess = possible[0]; /* 永遠猜第 0 個比較好寫 */ cout.printf( "I guess your number" + " is %04d, ... ", myGuess); ++nguess; // 猜的次數 // 由 user 取得幾A放 nbull, 幾 B 放 ncow cout.print("\r\n # of A: "); nbull = getInt( ); if(nbull != 4) { cout.print("\r # of B: "); ncow = getInt( ); } //getAnswer(&nbull, &ncow); if(nbull == 4){ if(nguess<5)cout.printf( "才 %d 次", nguess); cout.printf("喔 Yeah 我猜到了!\n"); if(nguess>6)cout.printf("這麼衰..猜了 %d 次!\n", nguess); break; } /* 還沒猜對, 把不可能的答案刪除並修正 npsible */ npsible = reduceAnswers(myGuess, nbull, ncow); if(npsible <= 0){ cout.printf( "You 欺騙我!\n"); break; } } cout.printf("\n要不要繼續玩下一攤(yes, no)? "); yn = askPlayAgain(); if(yn == 0) quit = true; //goto again; } cout.printf( "Thank you and Bye!\n"); return 0; } //function to check if the user want to play again int askPlayAgain(){ /* return 1 if he/she said YES */ String tmp="no"; //static char tmp[99]; try { tmp = cin.readLine( ); // readLine(tmp); }catch(Exception e) { } if(tmp.length( ) == 0) return 0; if(tmp.charAt(0) == 'Y' || tmp.charAt(0) == 'y') return 1; if(tmp.charAt(0) == 'N' || tmp.charAt(0) == 'n') return 0; // if(toupper(tmp[0]) == 'N') return 0; cout.printf( "Please type N or Y: "); return askPlayAgain(); /* recursively call myself */ } /// function prepare_all_possible_answer(); int prepare_all_possible_answer(){ //想辦法 (用四層 for loop ) 把所有可能答案 放在 possible[5040] //共有 5040 個, 最小 0123, 最大 9876 //(因每位不能重複) //int * x = possible; /* 之後 x[0] 就是 possible[0] */ // 以下是原來給大家的例子 int p=0, i,k,m,n; for(i=0; i<=9; i++){ for(k=0; k<=9; k++){ if(k==i) continue; /* 第二位k與第一位數i相同的都不要 */ for(m=0; m<=9; m++){ if(m==k || m==i) continue; for(n=0; n<=9; n++){ if(n==m || n==k || n==i) continue; possible[p++] = i*1000+k*100+m*10+n; } } } } return p; } /// function reduceAnswers() int reduceAnswers(int myGuess, int nbull, int ncow){ // 刪除不可能之答案, 並將可能之答案放在 array 前端 // // 以下只做刪除不可能之答案 // /// 順便把可能答案往 array 前端移 : 留給大家想 .. int na=0, nb=0, i; int n= 0; /* possible[0] 是第一個可以蓋掉的 */ /* 所以由 possible[1] 開始看看有哪些是有可能的就留下來 */ for(i=1; i< npsible; i++){ //叫用以前的 checkAnswer(要稍微修正) 比較 myGuess 和 possible[i] //以便知道myGuess對於 possible[i]是幾A幾B // //若幾A幾B剛好與 nbull 和 ncow 完全相同表示為可能答案 // //否則都要消去 // int kkk = checkAnswer(myGuess, possible[i], na, nb, i); na = kkk/10; nb = kkk%10; if(na == nbull && nb==ncow){ possible[n] = possible[i]; /*可能的答案移到 array 較前面*/ ++n; /* n 指向下一個可蓋掉的元素 possible[n] */ } } npsible = n; return n; } /*** /// 要稍微修正checkAnswer 因以前是比兩個 array 現在是比兩個整數, 要先用 %10 的方法拆成四位數 // *************************************************/ int checkAnswer(int xx, int yy, int na, int nb, int item){ int x[ ]= new int[4], y[ ] = new int[4], i, j; na = nb =0; /* 要先把整數拆解成四位個位數 */ x[0] = xx % 10; y[0] = yy % 10; x[1] = (xx %100) /10; y[1] = (yy %100) /10; x[2] = (xx /100) %10; y[2] = (yy /100) %10; x[3] = xx /1000; y[3] = yy /1000; for(i=0; i<=3; i++){ if(x[i] == y[i]) ++(na); for(j=0; j<=3; j++) if(i!=j && x[i] == y[j]) ++(nb); } return na*10 + nb; } int getInt( ) { String s = "000"; try { s = cin.readLine( ); }catch(Exception e) { } int ans =0; if(s.length( ) == 0) return 0; ans = Integer.parseInt(s); return ans; } } // class