//bat6ok.c -- @CopyLeft by tsaiwn@csie.nctu.edu.tw //BATtle of NUMbers //modified by __學號__ _姓_名_ and __學號__ _姓_名_ /// // 若用 Java 則須用 class 包起來; class名稱須與檔案名稱相同 ! // 且 main 必須 public static void main(String xxx[ ]) { #define repeat do { #define until(x) } while(! (x) ) #include #include #include #define MAX_STONE 31 #define MIN_STONE 18 #define MAX_TAKE 9 //Java 內以上須用這樣 public final static int MAX_TAKE = 9; #ifndef __cplusplus typedef enum {false=0, true } bool; // C 不認識 這些 #endif // define some global variables for the Game int nStone; // number of Stone int maxTake; // max stone to take for some game bool lastToWin; // Win or Lose if took last one stone? bool userFirst, playAgain; /// enum player {USER, COMPUTER}; // 這樣寫後面可以用USER/COMPUTER enum player who; // who is taking the stone? 輪到誰? // Java 的 enum 請看本檔案最後的補充 ! void hello( ), prepareGame( ), playGame( ); bool askUserFirst( ), askPlayAgain( ); void userTurn( ), computerTurn( ); void randomize( ) { srand(time(0)); } // 抓時間來當作亂數種子 int main( ) { hello( ); randomize( ); // randomize; make it true random repeat prepareGame( ); userFirst = askUserFirst( ); playGame( ); playAgain = askPlayAgain( ); until( ! playAgain ); printf("Thank you for your play.\r\n"); return 0; } void hello( ) { printf("Welcome to the BATNUM game ...\r\n"); } void prepareGame( ) { char msg[ ][88]={"Lose the game.", "win the game."}; nStone = MIN_STONE + rand( ) % (MAX_STONE-MIN_STONE+1); maxTake = 3 + rand( ) % (MAX_TAKE -3 +1); // 3.. lastToWin = rand( )%2 == 1; // half chance 一半的機會 printf("\r\nThere are %d stones.\r\n", nStone); printf("At least take 1, at most %d stones.\r\n", maxTake); printf("The one who take the last stone will "); printf("%s\r\n", msg[lastToWin]); // 拿最後一個輸還是贏? #ifdef DEBUG printf("lastToWin=%d\n", lastToWin); #endif } // prepareGame bool askUserFirst( ) { static char buf[99]; fprintf(stderr, "Do you want to go first(Y, N)? "); fgets(buf, sizeof(buf), stdin); if(buf[0]=='N' || buf[0]=='n') return false; //no if(buf[0]==0) return false; // no! C不認識 true/false return true; // Yes otherwise } bool askPlayAgain( ) { static char buf[99]; fprintf(stderr, " Play again(Y, N)? "); fgets(buf, sizeof(buf), stdin); if(buf[0]=='N' || buf[0]=='n') return false; //no if(feof(stdin)) return false; // EOF encounted return true; // Yes } // askPlayAgain void playGame( ) { bool userWin=true; // assume user win if(userFirst) userTurn( ); else printf(" OK. I go first.\r\n"); while(nStone > 0 ) { computerTurn( ); if(nStone <= 0) break; // gameOver userTurn( ); } // game Over when leave the while Loop userWin = true; // assume you win if(lastToWin && (who == COMPUTER) ) userWin = false; // user 輸! if( (!lastToWin) && (who == USER) ) userWin = false; // user 也是輸 if(userWin) printf(" Congratulations! You win!\r\n"); else printf(" Sorry, I won! Ha ha!\n"); } // playGame void userTurn( ) { int nTake, canTake; static char buf[99]; who = USER; // now USER 's turn 記住輪到 USER canTake = maxTake; // 照規定最多只能拿取 maxTake if(nStone < maxTake) canTake = nStone; // 沒那麼多了 printf(" How many you want to take(1..%d)? ", canTake); fgets(buf, sizeof(buf), stdin); nTake = (int)atol(buf); // check if the nTake is legal ? // .. 若不符規定則要求 USER 重新輸入 // .. 也可寫成若輸入負數表示 give up, 就結束此 game :-( while(nTake < 1 || nTake > canTake) { // illegal printf(" ?? Error, please re-type(1..%d)? ", canTake); fgets(buf, sizeof(buf), stdin); nTake = (int)atol(buf); } nStone -= nTake; if(nStone == 0) printf(" You just took the last stone.\r\n"); else printf(" %d stone(s) left.\r\n", nStone); return; } // userTurn void computerTurn( ) { int nTake = 1; who = COMPUTER; // now is COMPUTER 's turn 記住輪到 COMPUTER // 必贏的策略? 須考慮拿最後一個贏還是輸 nTake = nStone; if(!lastToWin) nTake--; // 拿最後一個是輸ㄝ, 留一個給對手 nTake = nTake % (1+maxTake); if(nTake == 0) nTake = 1; // 電腦會輸, 先賴皮拿一個等對手拿錯:-) if(nTake > nStone) nTake = nStone; // 沒那麼多! (不可能發生) /// nStone -= nTake; // 拿走啊 printf(" I take %d stone", nTake); if(nTake > 1) printf("s"); // 複數 printf(" this time."); if(nStone == 0) printf(" I just took the last stone.\r\n"); else printf(" Now %d stone(s) left.\r\n", nStone); } // computerTurn /// === === END of the program BATNUM === === /*** 關於 Java 的 enum: 在 C/C++ 的 enum 其實是整數, 可 Java 不是! Java 的 enum 是會變成 class ! 請編譯完後看看目錄中多出的 class 檔! 以下是個簡單範例, 可編譯並且執行: //gg.java -- test enum in Java, by tsaiwn@csie.nctu.edu.tw //avac gg.java //java gg //javap gg$player class gg { enum player {USER, COMPUTER}; public static void main(String xx[ ]) { player yy = player.USER; System.out.println("user="+yy); if(yy == player.USER) System.out.println("YES yy is player.USER"); else System.out.println("NO hahaha!"); }//main } // class gg *************************************************************/