D:\> linenum < bat0.c
01 //bat0.c -- prototype by tsaiwn@csie.nctu.edu.tw
02 //BATtle of NUMbers
03 // === 以下是要 讓 do{...}while(x); 可寫成repeat...until(!(x));
04 #define repeat do {
05 #define until(x) } while(! (x) )
06 #define bool int
07 //^^^^^^^^^^^^^^^^^^ 因為 C 不認識 bool, 用 int 代替;也可用enum
08 #include <stdio.h>
09 #include <stdlib.h>
10 #include <time.h>
11 //
12 // define some global variables for the Game
13 int nStone; // number of Stone
14 int maxTake; // max stone to take
15 bool userFirst, playAgain; // 是否 USER 先拿? 是否要繼續玩?
16 // more variable needed? 想到再補上來
17 //
18 // 先把用到的各小弟 (function; 函數; 函式) 宣告在這 ..
19 void hello( ), prepareGame( ), playGame( ); // 看名稱就知道意思
20 bool askUserFirst( ), askPlayAgain( );
21 void userTurn(void), computerTurn(void); // take turn to play
22 //
23 int main( ) { // 把工作都儘量分給 function, 讓 main 看起來很乾爽!
24 hello( );
25 // 必要時可做 srand(time(0)); //用時間做亂數種子, 就是 randomize
26 repeat
27 prepareGame( );
28 userFirst = askUserFirst( );
29 playGame( );
30 playAgain = askPlayAgain( );
31 until( ! playAgain );
32 printf("Thank you for your play.\n");
33 return 0;
34 } // main
35
36 void hello( ) {
37 // welcome message and/or game rules
38 }
39 void prepareGame( ) {
40 // 用亂數 rand( )生出 遊戲所需的各個 Global variables
41 }
42 bool askUserFirst( ) {
43 // 若 USER 要先拿, 就傳回 1
44 return (38==38); // YES / TRUE; 因為 C 不認識 true/false
45 }
46 bool askPlayAgain( ) {
47 // 若 USER 要繼續玩, 就傳回 1
48 return (38==49); // NO / FALSE; 因為 C 不認識 true/false
49 }
50 void userTurn( ) {
51 // 問 USER 要拿幾個存入 nTake, 但要 check 是否合乎規定!
52 // 然後當然要從 nStone 減去 nTake
53 }
54 void computerTurn( ) {
55 // 先寫隨便拿但要合乎規定, 再想出可贏就會贏的策略 (很簡單 :-)
56 }
57 void playGame( ) {
58 // user and the computer take Turn until no more stones left
59 // if(userFirst) userTurn( );
60 // Loop until no more stone
61 // computerTurn( );
62 // if no more stone then leave the Loop;
63 // userTurn( );
64 // end Loop
65 // Judge the game result and print some message..
66 // 如何判斷誰輸誰贏? 須知道誰拿走最後一個! 拿最後一個是輸還是贏?
67 } // playGame
D:\> linenum < bat2.c
01 //bat2.c -- @CopyLeft by tsaiwn@csie.nctu.edu.tw
02 //BATtle of NUMbers; ==> try this: TCC -DDEBUG bat2.c
03 #define repeat do {
04 #define until(x) } while(! (x) )
05 #define bool int
06 #define TRUE (38==38) // good idea, works even in Java Language
07 #define FALSE (38==49) // C 不認識 true / false
08
09 #include <stdio.h>
10 #include <stdlib.h>
11 #include <time.h>
12
13 #define MAX_STONE 31
14 #define MIN_STONE 15
15 #define MAX_TAKE 9
16
17 // define some global variables for the Game
18 int nStone; // number of Stone
19 int maxTake; // max stone to take for some game
20 bool lastToWin; // Win or Lose if took last one stone?
21 bool userFirst, playAgain;
22 ///
23 enum player {USER, COMPUTER}; // 這樣寫後面可以用USER/COMPUTER
24 enum player who; // who's turn? who is taking the stone? 輪到誰?
25
26 void hello( ), prepareGame( ), playGame( );
27 bool askUserFirst( ), askPlayAgain( );
28 void userTurn( ), computerTurn( );
29
30 int main( ) {
31 hello( );
32 srand(time(0)); // randomize; make it TRUE random
33 repeat
34 prepareGame( );
35 userFirst = askUserFirst( );
36 playGame( );
37 playAgain = askPlayAgain( );
38 until( ! playAgain );
39 printf("Thank you for your play.\n");
40 return 0;
41 }
42 void hello( ) {
43 }
44 void prepareGame( ) {
45 char msg[ ][88]={"Lose the game.", "win the game."};
46 nStone = MIN_STONE + rand( ) % (MAX_STONE-MIN_STONE+1);
47 maxTake = 3 + rand( ) % (MAX_TAKE -3 +1); // 3..
48 lastToWin = (rand( )%2 == 1); // half chance 一半的機會
49 printf("\nThere are %d stones.\n", nStone);
50 printf("At least take 1, at most %d stones.\n", maxTake);
51 printf("The one who take the last one will ");
52 printf("%s\n", msg[lastToWin]); // 拿最後一個輸還是贏?
53 #ifdef DEBUG
54 printf("lastToWin=%d\n", lastToWin);
55 #endif
56 } // prepareGame
57 bool askUserFirst( ) {
58 static char buf[99];
59 fprintf(stderr, "Do you want to go first(Y, N)? ");
60 fgets(buf, sizeof(buf), stdin);
61 if(buf[0]=='N' || buf[0]=='n') return FALSE; //no
62 if(buf[0]==0) return FALSE; // no! C不認識 true/false
63 return TRUE; // Yes otherwise
64 }
65 bool askPlayAgain( ) {
66 static char buf[99];
67 fprintf(stderr, " Play again(Y, N)? ");
68 fgets(buf, sizeof(buf), stdin);
69 if(buf[0]=='N' || buf[0]=='n') return FALSE; //no
70 if(feof(stdin)) return FALSE; // EOF encounted
71 return TRUE; // Yes
72 } // askPlayAgain
73 void playGame( ) {
74 int userWin=1; // Local variable is enough here
75 if(userFirst) userTurn( ); // userFirst 是 global variable
76 else printf(" OK. I go first.\n");
77 while(nStone > 0 ) {
78 computerTurn( );
79 if(nStone <= 0) break; // gameOver
80 userTurn( );
81 } // game Over when leave the while Loop
82 userWin = 1; // assume USER win
83 if(lastToWin && (who == COMPUTER) ) userWin = 0; // 這樣 USER 輸!
84 if( (!lastToWin) && (who == USER) ) userWin = 0; // USER 也是輸
85 if(userWin) printf(" Congratulations! You win!\n");
86 else printf(" Sorry, I won! Ha ha!\n");
87 } // playGame
88 void userTurn( ) {
89 int nTake, canTake; // canTake 是要算出這次可拿幾個?
90 static char buf[99];
91 who = USER; // now USER 's turn 記住輪到 USER
92 canTake = maxTake; // 照規定最多只能拿取 maxTake
93 if(nStone < maxTake) canTake = nStone; // 沒那麼多了
94 printf(" How many you want to take(1..%d)? ", canTake);
95 //讀取 USER 要拿幾個, then check if the nTake is leagle ?
96 // .. 若不符規定則要求 USER 重新輸入, 直到 nTake 合乎規定
97 // .. 也可寫成若輸入負數表示 USER give up, 就結束此 game :-(
98 nStone -= nTake; // 阿就拿走 nTake 個啊
99 if(nStone == 0) printf(" You just took the last stone.\n");
100 else printf(" %d stone(s) left.\n", nStone);
101 return;
102 } // userTurn
103 void computerTurn( ) {
104 int nTake = 1;
105 who = COMPUTER; // now is COMPUTER 's turn 記住輪到 COMPUTER
106 nTake = 1 + nStone % maxTake; // 隨便拿
107 if(nTake > nStone) nTake = nStone; // 沒那麼多! 只剩 nStone 個
108 // 請改為可以贏就要贏
109 // 必贏的策略? 須考慮拿最後一個贏還是輸
110 /// 這策略很簡單! 先令 nTake = nStone;
111 /// 然後若拿最後一個是輸則令 nTake = nTake - 1; 表留一個給對手拿
112 /// 再來, 令 nTake = nTake % (1+maxTake); 這樣拿就會贏
113 /// 若是算出 nTake 為 0 則表示必輸的, 就先拿一個等對手出錯!
114 /// ///
115 nStone -= nTake; // 阿就拿走 nTake 個啊
116 // print out some message
117 return;
118 } // computerTurn
D:\> linenum < bat6ok.c
01 //bat6ok.c -- @CopyLeft by tsaiwn@csie.nctu.edu.tw
02 //BATtle of NUMbers
03 //modified by __學號__ _姓_名_ and __學號__ _姓_名_
04 ///
05 // 若用 Java 則須用 class 包起來; class名稱須與檔案名稱相同 !
06 // 且 main 必須 public static void main(String xxx[ ]) {
07 #define repeat do {
08 #define until(x) } while(! (x) )
09
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <time.h>
13
14 #define MAX_STONE 31
15 #define MIN_STONE 18
16 #define MAX_TAKE 9
17 //Java 內以上須用這樣 public final static int MAX_TAKE = 9;
18
19 #ifndef __cplusplus
20 typedef enum {false=0, true } bool; // C 不認識 這些
21 #endif
22
23 // define some global variables for the Game
24 int nStone; // number of Stone
25 int maxTake; // max stone to take for some game
26
27 bool lastToWin; // Win or Lose if took last one stone?
28 bool userFirst, playAgain;
29 ///
30 enum player {USER, COMPUTER}; // 這樣寫後面可以用USER/COMPUTER
31 enum player who; // who is taking the stone? 輪到誰?
32 // Java 的 enum 請看本檔案最後的補充 !
33 void hello( ), prepareGame( ), playGame( );
34 bool askUserFirst( ), askPlayAgain( );
35 void userTurn( ), computerTurn( );
36 void randomize( ) { srand(time(0)); } // 抓時間來當作亂數種子
37
38 int main( ) {
39 hello( );
40 randomize( ); // randomize; make it true random
41 repeat
42 prepareGame( );
43 userFirst = askUserFirst( );
44 playGame( );
45 playAgain = askPlayAgain( );
46 until( ! playAgain );
47 printf("Thank you for your play.\r\n");
48 return 0;
49 }
50
51 void hello( ) {
52 printf("Welcome to the BATNUM game ...\r\n");
53 }
54
55 void prepareGame( ) {
56 char msg[ ][88]={"Lose the game.", "win the game."};
57 nStone = MIN_STONE + rand( ) % (MAX_STONE-MIN_STONE+1);
58 maxTake = 3 + rand( ) % (MAX_TAKE -3 +1); // 3..
59 lastToWin = rand( )%2 == 1; // half chance 一半的機會
60 printf("\r\nThere are %d stones.\r\n", nStone);
61 printf("At least take 1, at most %d stones.\r\n", maxTake);
62 printf("The one who take the last stone will ");
63 printf("%s\r\n", msg[lastToWin]); // 拿最後一個輸還是贏?
64 #ifdef DEBUG
65 printf("lastToWin=%d\n", lastToWin);
66 #endif
67 } // prepareGame
68
69 bool askUserFirst( ) {
70 static char buf[99];
71 fprintf(stderr, "Do you want to go first(Y, N)? ");
72 fgets(buf, sizeof(buf), stdin);
73 if(buf[0]=='N' || buf[0]=='n') return false; //no
74 if(buf[0]==0) return false; // no! C不認識 true/false
75 return true; // Yes otherwise
76 }
77
78 bool askPlayAgain( ) {
79 static char buf[99];
80 fprintf(stderr, " Play again(Y, N)? ");
81 fgets(buf, sizeof(buf), stdin);
82 if(buf[0]=='N' || buf[0]=='n') return false; //no
83 if(feof(stdin)) return false; // EOF encounted
84 return true; // Yes
85 } // askPlayAgain
86
87 void playGame( ) {
88 bool userWin=true; // assume user win
89 if(userFirst) userTurn( );
90 else printf(" OK. I go first.\r\n");
91 while(nStone > 0 ) {
92 computerTurn( );
93 if(nStone <= 0) break; // gameOver
94 userTurn( );
95 } // game Over when leave the while Loop
96 userWin = true; // assume you win
97 if(lastToWin && (who == COMPUTER) ) userWin = false; // user 輸!
98 if( (!lastToWin) && (who == USER) ) userWin = false; // user 也是輸
99 if(userWin) printf(" Congratulations! You win!\r\n");
100 else printf(" Sorry, I won! Ha ha!\n");
101 } // playGame
102
103 void userTurn( ) {
104 int nTake, canTake;
105 static char buf[99];
106 who = USER; // now USER 's turn 記住輪到 USER
107 canTake = maxTake; // 照規定最多只能拿取 maxTake
108 if(nStone < maxTake) canTake = nStone; // 沒那麼多了
109 printf(" How many you want to take(1..%d)? ", canTake);
110 fgets(buf, sizeof(buf), stdin);
111 nTake = (int)atol(buf);
112 // check if the nTake is legal ?
113 // .. 若不符規定則要求 USER 重新輸入
114 // .. 也可寫成若輸入負數表示 give up, 就結束此 game :-(
115 while(nTake < 1 || nTake > canTake) { // illegal
116 printf(" ?? Error, please re-type(1..%d)? ", canTake);
117 fgets(buf, sizeof(buf), stdin);
118 nTake = (int)atol(buf);
119 }
120 nStone -= nTake;
121 if(nStone == 0) printf(" You just took the last stone.\r\n");
122 else printf(" %d stone(s) left.\r\n", nStone);
123 return;
124 } // userTurn
125
// ( 下頁還有 )
126 void computerTurn( ) {
127 int nTake = 1;
128 who = COMPUTER; // now is COMPUTER 's turn 記住輪到 COMPUTER
129 // 必贏的策略? 須考慮拿最後一個贏還是輸
130 nTake = nStone;
131 if(!lastToWin) nTake--; // 拿最後一個是輸ㄝ, 留一個給對手
132 nTake = nTake % (1+maxTake);
133 if(nTake == 0) nTake = 1; // 電腦會輸, 先賴皮拿一個等對手拿錯:-)
134 if(nTake > nStone) nTake = nStone; // 沒那麼多! (不可能發生)
135 ///
136 nStone -= nTake; // 拿走啊
137 printf(" I take %d stone", nTake);
138 if(nTake > 1) printf("s"); // 複數
139 printf(" this time.");
140 if(nStone == 0) printf(" I just took the last stone.\r\n");
141 else printf(" Now %d stone(s) left.\r\n", nStone);
142 } // computerTurn
143 /// === === END of the program BATNUM === ===
144 /*** 關於 Java 的 enum: 在 C/C++ 的 enum 其實是整數, 可 Java 不是!
145 Java 的 enum 是會變成 class ! 請編譯完後看看目錄中多出的 class 檔!
146 以下是個簡單範例, 可編譯並且執行:
147 //gg.java -- test enum in Java, by tsaiwn@csie.nctu.edu.tw
148 //avac gg.java
149 //java gg
150 //javap gg$player
151 class gg {
152 enum player {USER, COMPUTER};
153 public static void main(String xx[ ]) {
154 player yy = player.USER;
155 System.out.println("user="+yy);
156 if(yy == player.USER)
System.out.println("YES yy is player.USER");
157 else System.out.println("NO hahaha!");
158 }//main
159 } // class gg
160 *************************************************************/
01 //bat6ok.java -- modified from bat6ok.c
02 //javac bat6ok.java
03 //java bat6ok
04 ///////////////////////////////////////////////////
05 //bat6ok.c -- @CopyLeft by tsaiwn@csie.nctu.edu.tw
06 //BATtle of NUMbers
07 //modified by __學號__ _姓_名_ and __學號__ _姓_名_
08 ///
09 // 若用 Java 則須用 class 包起來; class名稱須與檔案名稱相同 !
10 // 且 main 必須 public static void main(String xxx[ ]) {
11 import java.io.*;
12 import java.util.*;
13
14 class bat6ok { // filename should be the same as class name
15
16 public final static int MAX_STONE = 31;
17 public final static int MIN_STONE = 18;
18 public final static int MAX_TAKE = 9;
19
20 // define some global variables for the Game
21 int nStone; // number of Stone
22 int maxTake; // max stone to take for some game
23
24 boolean lastToWin; // Win or Lose if took last one stone?
25 boolean userFirst, playAgain;
26 ///
27 enum player {USER, COMPUTER}; // 這樣寫後面可以用USER/COMPUTER
28 player who; // who is taking the stone? 輪到誰? 注意 Java 寫法 !
29
30 public static void main(String xxx[ ]) {
31 bat6ok ggyy = new bat6ok( );
32 ggyy.main( );
33 }
34 bat6ok( ) { // constructor
35 prepareIO( );
36 }
37 BufferedReader cin=null;
38 PrintStream cout=null;
39
40 void prepareIO( ) {
41 try {
42 cin = new BufferedReader(
43 new InputStreamReader( System.in ) );
44 cout = System.out;
45 }catch(Exception e) { }
46 }
47
48 int main( ) { // 原來的 main( ); Note that it has different prototype
49 hello( );
50 randomize( ); // randomize; make it true random
51 do {
52 prepareGame( );
53 userFirst = askUserFirst( );
54 playGame( );
55 playAgain = askPlayAgain( );
56 } while( playAgain );
57 cout.printf("Thank you for your play.\r\n");
58 return 0;
59 }
60
61 int rand( ) {
62 return (int) (32767* Math.random( ) );
63 }
64 void srand(int seed) {
65 } // not necessary :-)
66 void randomize( ) {
67 srand((int)System.currentTimeMillis( ) );
68 }
69
70 void hello( ) {
71 cout.printf("Welcome to the BATNUM game ...\r\n");
72 }
73
74 void prepareGame( ) {
75 String msg[ ]={"Lose the game.", "win the game."};
76 nStone = MIN_STONE + rand( ) % (MAX_STONE-MIN_STONE+1);
77 maxTake = 3 + rand( ) % (MAX_TAKE -3 +1); // 3..
78 lastToWin = rand( )%2 == 1; // half chance 一半的機會
79 cout.printf("\r\nThere are %d stones.\r\n", nStone);
80 cout.printf("At least take 1, at most %d stones.\r\n", maxTake);
81 cout.printf("The one who take the last stone will ");
82 int kkk; kkk = 0;
83 if(lastToWin) kkk = 1;
84 cout.printf("%s\r\n", msg[kkk]); // 拿最後一個輸還是贏?
85 } // prepareGame
86
87 boolean askUserFirst( ) {
88 cout.printf( "Do you want to go first(Y, N)? ");
89 String buf = null;
90 try {
91 buf = cin.readLine( );
92 } catch(Exception e) { }
93 if(buf == null) return false;
94 if(buf.length( )==0) buf = "n";
95 if(buf.charAt(0)=='N' || buf.charAt(0)=='n') return false; //no
96 if(buf.charAt(0)==0) return false; // no!
97 return true; // Yes otherwise
98 }
99
100 boolean askPlayAgain( ) {
101 cout.printf( "Do you want to go first(Y, N)? ");
102 String buf = null;
103 try {
104 buf = cin.readLine( );
105 } catch(Exception e) { }
106 if(buf == null) return false;
107 if(buf.length( )==0) buf = "n";
108 if(buf.charAt(0)=='N' || buf.charAt(0)=='n') return false; //no
109 if(buf.charAt(0)==0) return false; // no!
110 return true; // Yes
111 } // askPlayAgain
112
113 void playGame( ) {
114 boolean userWin=true; // assume user win
115 if(userFirst) userTurn( );
116 else cout.printf(" OK. I go first.\r\n");
117 while(nStone > 0 ) {
118 computerTurn( );
119 if(nStone <= 0) break; // gameOver
120 userTurn( );
121 } // game Over when leave the while Loop
122 userWin = true; // assume you win
123 if(lastToWin && (who == player.COMPUTER) ) userWin = false; // user 輸!
124 if( (!lastToWin) && (who == player.USER) ) userWin = false; // user 也是輸
125 if(userWin) cout.printf(" Congratulations! You win!\r\n");
126 else cout.printf(" Sorry, I won! Ha ha!\n");
127 } // playGame
128
129 void userTurn( ) {
130 int nTake, canTake;
131 String buf;
132 who = player.USER; // now USER 's turn 記住輪到 USER
133 canTake = maxTake; // 照規定最多只能拿取 maxTake
134 if(nStone < maxTake) canTake = nStone; // 沒那麼多了
135 cout.printf(" How many you want to take(1..%d)? ", canTake);
136 try {
137 buf = cin.readLine( );
138 if(buf==null) buf="0";
139 nTake = Integer.parseInt(buf);
140 }catch(Exception e) { nTake = 0; }
141 while(nTake < 1 || nTake > canTake) { // illegal
142 cout.printf(" ?? Error, please re-type(1..%d)? ", canTake);
143 try {
144 buf = cin.readLine( );
145 if(buf==null) buf="0";
146 if(buf.length( )==0) buf = "0";
147 nTake = Integer.parseInt(buf);
148 }catch(Exception e) { nTake = 0; }
149 }
150 nStone -= nTake;
151 if(nStone == 0) cout.printf(" You just took the last stone.\r\n");
152 else cout.printf(" %d stone(s) left.\r\n", nStone);
153 return;
154 } // userTurn
155
156 void computerTurn( ) {
157 int nTake = 1;
158 who = player.COMPUTER; // now is COMPUTER 's turn 記住輪到 COMPUTER
159 // 必贏的策略? 須考慮拿最後一個贏還是輸
160 nTake = nStone;
161 if(!lastToWin) nTake--; // 拿最後一個是輸ㄝ, 留一個給對手
162 nTake = nTake % (1+maxTake);
163 if(nTake == 0) nTake = 1; // 電腦會輸, 先賴皮拿一個等對手拿錯:-)
164 if(nTake > nStone) nTake = nStone; // 沒那麼多! (不可能發生)
165 ///
166 nStone -= nTake; // 拿走啊
167 cout.printf(" I take %d stone", nTake);
168 if(nTake > 1) cout.printf("s"); // 複數
169 cout.printf(" this time.");
170 if(nStone == 0) cout.printf(" I just took the last stone.\r\n");
171 else cout.printf(" Now %d stone(s) left.\r\n", nStone);
172 } // computerTurn
173
174 } // class bat6ok
175 /// === === END of the program BATNUM === ===
*** 提醒要 Stepwise refinement 逐步改進 !
|
|
|
|