//bat3.c  -- @CopyLeft by tsaiwn@csie.nctu.edu.tw
//BATtle of NUMbers ;  接近完成版, 目前沒有防呆, 電腦也不一定會贏
#define repeat  do {
#define until(x)   } while(! (x) )
#define bool  int
#define TRUE (38==38)   // good idea, works even in Java Language
#define FALSE (38==49)   // C 不認識 true / false

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_STONE 31
#define MIN_STONE 15
#define MAX_TAKE 9
// 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's turn? who is taking the stone? 輪到誰?

void hello( ), prepareGame( ), playGame( );
bool askUserFirst( ), askPlayAgain( );
void userTurn( ), computerTurn( );

int main( ) {
   hello( ); 
   srand(time(0));   // randomize; make it TRUE random
   repeat
      prepareGame( );
      userFirst = askUserFirst( );
      playGame( );
      playAgain = askPlayAgain( );
   until( ! playAgain );
   printf("Thank you for your play.\n");
   return 0;
}
void hello( ) {  
}
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("\nThere are %d stones.\n", nStone);
   printf("At least take 1, at most %d stones.\n", maxTake);
   printf("The one who take the last one will ");
   printf("%s\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( ) {
   int userWin=1; // assume user win
   if(userFirst) userTurn( );
   else printf(" OK. I go first.\n");
   while(nStone > 0 ) {
      computerTurn( );
      if(nStone <= 0) break; // gameOver
      userTurn( );
   } // game Over when leave the while Loop
   userWin = 1; // assume you win
   if(lastToWin && (who == COMPUTER) ) userWin = 0; // user 輸!
   if( (!lastToWin) && (who == USER) ) userWin = 0; // user 也是輸
   if(userWin) printf(" Congratulations! You win!\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 legale ?
   // .. 若不符規定則要求 USER 重新輸入
   // .. 也可寫成若輸入負數表示 give up, 就結束此 game :-(
   nStone -= nTake;
   if(nStone == 0) printf(" You just took the last stone.\n");
   else printf(" %d stone(s) left.\n", nStone);
   return;
} // userTurn
void computerTurn( ) {
   int nTake = 1;
   who = COMPUTER;  // now is COMPUTER 's turn 記住輪到 COMPUTER
   nTake = 1 + nStone % maxTake;   // 隨便拿
   // 請改為可以贏就要贏
   // 必贏的策略?  須考慮拿最後一個贏還是輸
   if(nTake == 0) nTake = 1;  // at least have to take one
   if(nTake > nStone) nTake = nStone; // 沒那麼多! 只剩 nStone 個
   nStone -= nTake;  // 阿就拿走 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.\n");
   else printf(" Now %d stone(s) left.\n", nStone);
} // computerTurn
