題目: 寫個可以讓User與電腦對玩BATNUM的程式 (比NIM簡單)
Due: 即日起七天內  (其實看完題目大約半小時就可做完:)
Purpose:  
       也是練習使用亂數,與了解策略遊戲(Strategy game) 
  (1)透過這個練習,你將更了解程式庫 rand( ) 和 srand( ) 的用途與用法, 
    以及更熟悉 PRNG (Pseudo Random Number Generator)與程式庫 time(0) 用途;
  (2)了解策略遊戲(Strategy game)與如何在可以贏的時候做出贏的策略!
  (3)這BATNUM 只要用到取餘數 %, 比 NIM 遊戲用 xor 運算的應用簡單。
 
Description:
    類似NIM,  BATNUM (BATtle of NUMbers) 也是兩人對玩的策略遊戲!(比NIM簡單)
但是只有一堆石頭,兩個玩家輪流抓,可以規定抓最後一個的贏或是輸。
規則是至少要抓一個,最多則可事先隨便規定(可由電腦亂數產生)。 
棋類遊戲需要往前想很多步(建立遊戲樹),
NIM 與 BATNUM 這類的策略遊戲則只要"掐指一算"做出決策,
許多這種策略遊戲是不公平的遊戲,因為一開始輸贏就已經定案!
請自己用 google.com 查詢 BATNUM 相關資料(以及 NIM 資料 :-)

玩法(Game Rules)是: 
       一開始有一堆石頭,不一定幾個石頭,
    然後由兩人輪流拿,每次至少要抓一個,
    至多則可事先隨便規定(可由電腦亂數產生)。
      可規定拿到最後一個的贏,
      也可規定拿到最後一個的輸。 
贏家策略(Strategy to win):
  這個遊戲有個很簡單的贏家策略(拿最後的贏或輸都類似): 
    假設石頭總數是 n, 最多可以拿 tMax 個, 最少當然是拿一個;
      Let k = n;
      if(拿最後一個是輸) k = k -1;
      k = k % (1 + tMax);
      if(k == 0) k = 1;  // 輸定了, 先拿一個拖延時間
      阿就是拿走 k 個!

    (注意若拿最後一個是輸要先把總數減去一再做 % 運算)

Hints:關於個檔案簡易說明請看 00BATNUM.htm
   (1)可以玩玩我寫好的執行檔  batnumTC.exe 
      該檔案是用 Turbo C++產生的, 原始檔是 batnumTC.c 或 batnumTC.txt
      另外 bat6ok.exe 也是可以與電腦對玩的執行檔案。
   (2)已經會寫就自己從 0 開始寫, 不然就先看看 bat00.htm 
      看完就拿  bat0.c  當作初稿開始寫,
      仍不知道怎沒寫? 那改拿 bat2.c  去改吧。
      不過若規定拿到最後一個的是輸, 只要注意最後一步略作調整!!
   (3)再不然, 看看  bat3.c  這接近完成版,
      但是這時電腦是隨便拿, 也沒防呆機制。
   (4)至於  bat5.c  仍沒有防呆, 但電腦會想辦法贏!
   (5)如同往常,只要看不懂的都要舉手抓助教來問, 一定要想辦法弄懂!
      若助教也不會請記下他/她姓名偷偷告訴我, 扣薪水:-(
   (6)也可以測試這網路版的(Java) batnum.zip 
         java -jar batnum.zip 
      然後其他人只要用 telnet 工具連入該機器的 port 3388 就可玩!
      自己則開另一窗 telnet 127.0.0.1 3388  就可玩!
   (7) bat6ok.c 是參考解答, 請先不要偷看:-)
 
進階練習:
   ==> 學 Java 的可用 Java 寫出網路版。
 (註: 我給的 betNet.zip 只有 Java class 執行檔) 




//BATNUM  --  BATtle of NUMbers   數字大戰

 int nStone, maxTake;  // 總石頭數, 最多可拿幾個?
   boolean lastToWin = true; // 拿最後一個贏還是輸?
int main( ) {
   //BATtle of NUMbers
   hello( ); // welcome message
   playAgain = true;
   while(playAgain) {
      prepareGame( );
      userFirst = askUserFirst( );
      playGame( );
      playAgain = askPlayAgain( );
   }
   print("Bye bye\n"); return 0;
} // main
======================
void hello( ) {
   // welcome message and/or game rules
}
void prepareGame( ) {
    // 用亂數 生出 遊戲所需的各個 Global variables
    //nStone = 用亂數取得 15 .. 31;
    //maxTake = 用亂數取得 3..7 ;
    //用亂數決定 lastToWin 是 true 還是 false

}
boolean askUserFirst( ) {
   // 若 USER 要先拿, 就傳回 1 
   return (38==38);  // YES / TRUE
}
boolean askPlayAgain( ) {
   // 問user 並讀入答案, 若 USER 要繼續玩, 就傳回 true 
   return false;  // NO / FALSE 表示不完了 :-) 
}
void userTurn( ) {
   // nTake = 問 USER 要拿幾個;
   // 檢查 nTake 是否合乎規定? 若不符合則要求 user 重新輸入 
   // 然後當然要從 nStone 減去 nTake
}
void computerTurn( ) {
  // 先寫隨便拿但要合乎規定, 就是取 1..min(maxTake, nStone) 的亂數 
  // 再想出可贏就會贏的策略 (很簡單 :-)
  // Hint: 拿 max(1, (nStone - xxx) % (1+maxTake) ) 就會贏
  //    其中 xxx 是  0  if lastToWin is true
  ///        xxx 是  1  if lastToWin == false
}
void playGame( ) {
  // user and the computer take Turn until no more stones left
  // if(userFirst) userTurn( );
  // Loop until no more stone
  //   computerTurn( ); 
  //   if no more stone then leave the Loop;
  //   userTurn( );
  // end Loop
  // Judge the game result and print some message..
  // 如何判斷誰輸誰贏? 須知道誰拿走最後一個! 
  // 注意拿最後一個是輸還是贏? 
  //   (lastToWin == true 表示拿到最後一個的贏 )
} // playGame