//batnum.c -- new version /********BATNUM -- BATtle of NUMbers, an old game ********/ /* by Wen-Nung Tsai. Written in Turbo C. */ /* tcc batnum.c */ /* TurBo C++ only ******/ #include #include /* 以下這 conio.h 只有 Turbo C++ 才有 */ #include #define repeat do{ #define until(expr) }while(! (expr)) #define then 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) { cprintf(" Welcome to play BATNUM --- BATtle of NUMbers,\n\r"); cprintf(" ---------- by tsaiwn@csie.nctu\n\r"); }; void prepareGame(void) { totalStone = random(20) + 11; /* 11..30 */ maxTake = 3 + random(4); /* 3..6 */ lastToWin = 1; // assume YES if( random(100) < 50) then lastToWin = 0; }; void askWhoFirst(void) { cprintf("Initially, we have "); /* tell him the status */ textcolor(YELLOW); cprintf("%d",totalStone); normvideo(); cprintf(" stones.\n\r"); cprintf("At least take 1. At most take %d.\n\r",maxTake); cprintf("The one who takes "); textcolor(LIGHTRED+BLINK); cprintf("last stone to %s.\n\r", winMSG[lastToWin]); normvideo(); cprintf( "You want to go first(N,Y)? "); /* default is No */ c1 = getch(); if(c1==0)then c2 = getch(); cprintf("%c\n\r",c1); userFirst = 0; if(toupper(c1)=='Y') then userFirst = 1; if(! userFirst) then cprintf("OK. I go first.\n\r"); }; 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; cprintf("I take %d.\n\r",meTake); if( totalStone==0) then { /* last stone took by computer */ cprintf("I just took the last stone.\n\r"); userWin = 1; /* assume take last to loss */ if(lastToWin) then userWin = 0; /* I won */ } else { cprintf("There "); if(totalStone>1)then cprintf("are "); else cprintf("is "); textcolor(YELLOW); cprintf("%d",totalStone); normvideo(); cprintf(" stone"); if(totalStone>1)then cprintf("s"); cprintf(" left.\n\r"); };/*if totalS..*/ }; 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 cprintf(" Error, "); cprintf("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 { cprintf("You just took the last stone.\n\r"); userWin = 0; /* assume take last to loss */ if(lastToWin) then userWin = 1; }; if( totalStone > 0) then computerTurn(); }; /* take turn until no more stone */ /* game over */ }; int main(void) { /* main */ randomize(); repeat window(1,1,80,25); clrscr(); hello(); window(40,3,77,9); prepareGame(); askWhoFirst(); window(1,5,39,24); playGame(); if( userWin) then cprintf("Congratulations! You Win!\n\r"); else { cprintf("Ar-Ha! I win!\n\r"); sound(350); delay(500); sound(300); delay(400); sound(250); delay(500); nosound(); delay(500); }; cprintf("Play more(Y,N)? "); c1 = getch(); if(c1==0)then c2 = getch(); // Function key? printf("%c\n\r\n\r",c1); until( toupper(c1)== 'N'); cprintf("Bye Bye!\n\r"); normvideo(); return 0; } // main