//bat2.c -- new version for Unix/any ANSI C version /********BATNUM -- BATtle of NUMbers, an old game ********/ /* by Wen-Nung Tsai */ #include #include #include #define repeat do{ #define until(expr) }while(! (expr)) #define then //////////// int myRand(int n) { return rand( ) % n; } void randomize( ) { } // use time( ) and srand( ) /////////////////////////////////////////////////////////// ////// typedef int bool; // C €£»{ΓΡ bool typedef unsigned char byte; // byte == unsigned char typedef char str40[41]; // str40 == char [41] const char winMSG[][5] = {"loss", "win "}; int totalStone, maxTake; int c1,c2; str40 tmpstr; /* used for gets */ char * pstr; bool userFirst, userWin, lastToWin; /* FLAGs */ void hello(void); void prepareGame(void); void askWhoFirst(void); void computerTurn(void); void userTurn(void); /*****************************************************************/ void hello(void) { printf(" Welcome to play BATNUM --- BATtle of NUMbers,\n"); printf(" ---------- by tsaiwn@csie.nctu\n"); }; void prepareGame(void) { totalStone = myRand(20) + 11; /* 11..30 */ maxTake = 3 + myRand(4); /* 3..6 */ lastToWin = 1; // assume YES if( myRand(100) < 50) then lastToWin = 0; }; void askWhoFirst(void) { printf("Initially, we have "); /* tell him the status */ printf("%d",totalStone); printf(" stones.\n"); printf("At least take 1. At most take %d.\n",maxTake); printf("The one who takes "); printf("last stone to %s.\n", winMSG[lastToWin]); printf( "You want to go first(N,Y)? "); /* default is No */ fgets(tmpstr, sizeof(tmpstr), stdin); c1 = tmpstr[0]; userFirst = 0; if(toupper(c1)=='Y') then userFirst = 1; if(! userFirst) then printf("OK. I go first.\n"); }; void computerTurn(void) { int meTake,tmp; tmp = totalStone; if(! lastToWin) then tmp = tmp-1; /* take last stone to loss */ meTake = tmp % (1+ maxTake); /* try my best to WIN */ if( meTake == 0) then meTake = 1; /* seems that I will loss this game */ totalStone = totalStone - meTake; printf("I take %d.\n",meTake); if( totalStone==0) then { /* last stone took by computer */ printf("I just took the last stone.\n"); userWin = 1; /* assume take last to loss */ if(lastToWin) then userWin = 0; /* I won */ } else { printf("There "); if(totalStone>1)then printf("are "); else printf("is "); printf("%d",totalStone); printf(" stone"); if(totalStone>1)then printf("s"); printf(" left.\n"); };/*if totalSt..*/ }; void userTurn(void) { long lnumber; char * endptr; int canTake,heTake,errorcode; bool askBefore; canTake = maxTake; askBefore = 0; if(canTake > totalStone) then canTake = totalStone; repeat if(askBefore) then printf(" Error, "); printf("How many you take(1..%d)? ",canTake); gets(tmpstr); // fgets is better askBefore = 1; lnumber = strtol(tmpstr, &endptr, 10); // atol(tmpstr); heTake = (int) lnumber; until( (heTake >=1) && (heTake <= canTake) ); /*accept only legal move*/ totalStone = totalStone - heTake; }; void playGame(void) { if (! userFirst) then computerTurn(); while( totalStone > 0) { userTurn(); if( totalStone==0) then { printf("You just took the last stone.\n"); userWin = 0; /* assume take last to loss */ if(lastToWin) then userWin = 1; }; if( totalStone > 0) then computerTurn(); }; /* take turn until no more stone */ /* no more stone, game over */ }; int main(void) { /* main */ randomize(); repeat hello(); prepareGame(); askWhoFirst(); playGame(); if( userWin) then printf("Congratulations! You Win!\n"); else printf("Ar-Ha! I win!\n"); printf("Play more(Y,N)? "); fgets(tmpstr, sizeof(tmpstr), stdin); c1 = tmpstr[0]; until( toupper(c1)== 'N'); printf("Bye Bye!\n"); return 0; } // main