/********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 not ! #define mod % #define and && #define ord #define repeat do{ #define until(expr) }while(! (expr)) #define false 0 #define true 1 #define then #define begin { #define end } #define ELSE ;else #define procedure void #define write cprintf #define writeln cprintf #define readln gets /* note taht cgets has different syntax */ #define ReadKey getch() typedef int bool; typedef unsigned char byte; typedef char str40[41]; const char whowin[][5] = {"loss", "win "}; /* var */ int totalStone, maxtotake; int c1,c2; str40 tmpstr; /* used for readln */ char * pstr; bool user_first, user_win, last_to_win; /* FLAGs */ procedure hello(void); procedure prepare_stone(void); procedure ask_who_go_first(void); procedure computer_turn(void); procedure user_turn(void); /*****************************************************************/ procedure hello(void) begin writeln(" Welcome to play BATNUM --- BATtle of NUMbers,\n\r"); writeln(" ---------- by tsaiwn@csie.nctu\n\r"); end; procedure prepare_stone(void) begin totalStone = random(20) + 11; /* 11..30 */ maxtotake = 3 + random(4); /* 3..6 */ last_to_win = true; if( random(100) < 50) then last_to_win = false; end; procedure ask_who_go_first(void) begin write("Initially, we have "); /* tell him the status */ textcolor(YELLOW); write("%d",totalStone); normvideo(); writeln(" stones.\n\r"); writeln("At least take 1. At most take %d.\n\r",maxtotake); write("The one who takes "); textcolor(LIGHTRED+BLINK); writeln("last stone to %s.\n\r", whowin[last_to_win]); normvideo(); write( "You want to go first(N,Y)? "); /* default is No */ c1 = ReadKey; if(ord(c1)==0)then c2 = ReadKey; writeln("%c\n\r",c1); user_first = false; if(toupper(c1)=='Y') then user_first = true; if(not user_first) then writeln("OK. I go first.\n\r"); end; procedure computer_turn(void) /*var */ begin int metake,tmp; tmp = totalStone; if(not last_to_win) then tmp = tmp-1; /* take last stone to loss */ metake = tmp mod (1+ maxtotake); /* try my best to WIN */ if( metake == 0) then metake = 1; /* seems that I will loss this game */ totalStone = totalStone - metake; writeln("I take %d.\n\r",metake); if( totalStone==0) then begin /* last stone took by computer */ writeln("I just took the last stone.\n\r"); user_win = true; /* assume take last to loss */ if(last_to_win) then user_win = false; /* I won */ end else begin write("There "); if(totalStone>1)then write("are ") ELSE write("is "); textcolor(YELLOW); write("%d",totalStone); normvideo(); write(" stone"); if(totalStone>1)then write("s"); writeln(" left.\n\r"); end;/*if totalS..*/ end; procedure user_turn(void) begin long lnumber; char * endptr; int num_can_be,heTake,errorcode; bool ask_before; num_can_be = maxtotake; ask_before = false; if(num_can_be > totalStone) then num_can_be = totalStone; repeat if(ask_before) then write(" Error, "); write("How many you take(1..%d)? ",num_can_be); readln(tmpstr); ask_before = true; /* val(tmpstr,heTake, errorcode); /***/ lnumber = strtol(tmpstr, &endptr, 10); heTake = (int) lnumber; until( (heTake >=1) and (heTake <= num_can_be) ); /* accept only legal move */ totalStone = totalStone - heTake; end; procedure play_BATNUM(void) begin if (not user_first) then computer_turn(); while( totalStone > 0) begin user_turn(); if( totalStone==0) then begin writeln("You just took the last stone.\n\r"); user_win = false; /* assume take last to loss */ if(last_to_win) then user_win = true; end; if( totalStone > 0) then computer_turn(); end; /* take turn until no more stone */ /* game over */ end; int main(void) { /* main */ randomize(); repeat window(1,1,80,25); clrscr(); hello(); window(40,3,77,9); prepare_stone(); ask_who_go_first(); window(1,5,39,24); play_BATNUM(); if( user_win) then writeln("Congratulations! You Win!\n\r") ELSE begin writeln("Ar-Ha! I win!\n\r"); sound(350); delay(500); sound(300); delay(400); sound(250); delay(500); nosound(); delay(500); end; write("Play more(Y,N)? "); c1 = ReadKey; if(ord(c1)==0)then c2 = ReadKey; printf("%c\n\r\n\r",c1); until( toupper(c1)== 'N'); writeln("Bye Bye!\n\r"); normvideo(); return 0; }