0. #include <stdio.h>
1. #include <time.h>
2. #include <ctype.h>
3. #include <stdlib.h>
4. 5. #define BELL '\a'
6. #define DEALER 0
7. #define PLAYER 1
8. 9. #define ACELOW 0
10. #define ACEHIGH 1
11. 12. int askedForName = 0; 13. 14. void dispTitle(void); 15. void initCardsScreen(int cards[52],int playerPoints[2], 16. int dealerPoints[2], int total[2], 17. int *numCards); 18. int dealCard(int * numCards,int cards[52]); 19. void dispCard(int cardDrawn,int points[2]); 20. void totalIt(int points[2],int tatal[2],int who); 21. void dealerGetsCard(int *numCards,int cards[52], 22. int dealerPoints[2]); 23. void playerGetsCard(int *numCards,int cards[52], 24. int playerPoints[2]); 25. char getAns(char mesg[]); 26. void findWinner(int total[2]); 27. 28. main() 29. { 30. int numCards; 31. int cards[52],playerPoints[2],dealerPoints[2],total[2]; 32. char ans; 33. 34. do
35. { 36. initCardsScreen(cards,playerPoints,dealerPoints,total, &numCards); 37. dealerGetsCard(&numCards,cards, dealerPoints); 38. printf("\n"); 39. playerGetsCard(&numCards,cards,playerPoints); 40. playerGetsCard(&numCards,cards,playerPoints); 41. do
42. { 43. ans = getAns("Hit or stand (H/S)?"); 44. if ( ans == 'H' ) 45. { 46. playerGetsCard(&numCards,cards,playerPoints); 47. } 48. } 49. while( ans != 'S' ); 50. 51. totalIt(playerPoints,total,PLAYER); 52. do
53. { 54. dealerGetsCard(&numCards,cards,dealerPoints); 55. } 56. while (dealerPoints[ACEHIGH] < 17 ); 57. 58. totalIt(dealerPoints,total,DEALER); 59. findWinner(total); 60. 61. ans = getAns("\nPlay again(Y/N)?"); 62. } 63. while(ans=='Y'); 64. 65. return ; 66. 67. } 68. 69. void initCardsScreen( int cards[52],int playerPoints[2], 70. int dealerPoints[2], int total[2], 71. int *numCards ) 72. { 73. int sub,val = 1 ; 74. char firstName[15]; 75. *numCards=52; 76. 77. for(sub=0;sub<=51;sub++) 78. { 79. val = (val == 14) ? 1 : val; 80. cards[sub] = val; 81. val++; 82. } 83. 84. for(sub=0;sub<=1;sub++) 85. { 86. playerPoints[sub]=dealerPoints[sub]=total[sub]=0; 87. } 88. dispTitle(); 89. 90. if (askedForName==0) 91. { 92. printf("What is your first name?"); 93. scanf(" %s",firstName); 94. askedForName=1; 95. printf("Ok, %s,get ready for casino action!\n\n",firstName); 96. getchar(); 97. } 98. return; 99. } 100. 101. void playerGetsCard(int *numCards,int cards[52],int playerPoints[2]) 102. { 103. int newCard; 104. newCard = dealCard(numCards, cards); 105. printf("You draw:"); 106. dispCard(newCard,playerPoints); 107. } 108. 109. 110. void dealerGetsCard(int *numCards,int cards[52],int dealerPoints[2]) 111. { 112. int newCard; 113. newCard = dealCard(numCards,cards); 114. printf("The dealer draws:"); 115. dispCard(newCard,dealerPoints); 116. } 117. 118. int dealCard(int * numCards,int cards[52]) 119. { 120. int cardDrawn,subDraw; 121. time_t t; 122. srand(time(&t)); 123. subDraw = (rand()%(*numCards)); 124. cardDrawn = cards[subDraw]; 125. cards[subDraw] = cards[*numCards -1]; 126. (*numCards)-; 127. return cardDrawn; 128. } 129. 130. void dispCard(int cardDrawn, int points[2]) 131. { 132. switch(cardDrawn) 133. { 134. case(11): printf("%s\n","Jack"); 135. points[ACELOW] += 10; 136. points[ACEHIGH] += 10; 137. break; 138. case(12): printf("%s\n","Queen"); 139. points[ACELOW] += 10; 140. points[ACEHIGH] += 10; 141. break; 142. case(13): printf("%s\n","King"); 143. points[ACELOW] += 10; 144. points[ACEHIGH] += 10; 145. break; 146. default : points[ACELOW] += cardDrawn; 147. if(cardDrawn==1) 148. { 149. printf("%s\n","Ace"); 150. points[ACEHIGH]+= 11; 151. } 152. else
153. { 154. points[ACEHIGH]+=cardDrawn; 155. printf("%d\n",cardDrawn); 156. } 157. } 158. return ; 159. } 160. 161. void totalIt(int points[2],int total[2],int who) 162. { 163. if ( (points[ACELOW] == points[ACEHIGH]) 164. ||(points[ACEHIGH] > 21 )) 165. { 166. total[who] = points[ACELOW]; 167. } 168. else
169. { 170. total[who] = points[ACEHIGH]; 171. } 172. 173. if (who == PLAYER ) 174. { 175. printf("You have a total of %d\n\n", total[PLAYER]); 176. } 177. else
178. { 179. printf("The house stands with a total of %d\n\n", 180. total[DEALER]); 181. } 182. return; 183. } 184. 185. void findWinner(int total[2]) 186. { 187. if ( total[DEALER] == 21 ) 188. { 189. printf("The house wins.\n"); 190. return ; 191. } 192. if ( (total[DEALER] > 21) && (total[PLAYER] > 21) ) 193. { 194. printf("%s", "Nobody wins.\n"); 195. return ; 196. } 197. if ((total[DEALER] >= total[PLAYER])&& (total[DEALER] < 21)) 198. { 199. printf("The house wins.\n"); 200. return ; 201. } 202. if ((total[PLAYER] > 21)&& (total[DEALER] < 21)) 203. { 204. printf("The house wins.\n"); 205. return ; 206. } 207. printf("%s%c","You win!\n",BELL); 208. return; 209. } 210. 211. char getAns(char mesg[]) 212. { 213. char ans; 214. printf("%s", mesg); 215. ans = getchar(); 216. getchar(); 217. return toupper(ans); 218. } 219. 220. void dispTitle(void) 221. { 222. int i = 0 ; 223. while(i<25) 224. { 225. printf("\n"); 226. i++; 227. } 228. printf("\n\n*Step right up to the Blackjack tables*\n\n"); 229. return ; 230. }
庄家抽牌结束后,就到了宣布胜负的时候。
26. void findWinner(int total[2]); 185. void findWinner(int total[2]) 186. { 187. if ( total[DEALER] == 21 ) 188. { 189. printf("The house wins.\n"); 190. return ; 191. } 192. if ( (total[DEALER] > 21) && (total[PLAYER] > 21) ) 193. { 194. printf("%s", "Nobody wins.\n"); 195. return ; 196. } 197. if ((total[DEALER] >= total[PLAYER])&& (total[DEALER] < 21)) 198. { 199. printf("The house wins.\n"); 200. return ; 201. } 202. if ((total[PLAYER] > 21)&& (total[DEALER] < 21)) 203. { 204. printf("The house wins.\n"); 205. return ; 206. } 207. printf("%s%c","You win!\n",BELL); 208. return; 209. }
这个函数写得比较乱,缺乏条理。改成下面的写法更清晰:
void findWinner(int total[]); void findWinner(int total[]) { if ( total[DEALER] == 21 ) { printf("The house wins.\n"); return ; } if ( total[DEALER] > 21 ) { if( total[PLAYER] > 21 ) { printf("%s", "Nobody wins.\n"); return ; } } if ( total[DEALER] < 21 ) { if( (total[PLAYER] > 21) ) { printf("The house wins.\n"); return ; } if( (total[DEALER] >= total[PLAYER]) ) { printf("The house wins.\n"); return ; } } printf("%s%c","You win!\n",BELL); return; }
【重构】
从程序总体来看,无非是一个反复进行21点游戏的过程。
/* 21点游戏:对《写给大家看的C语言书》附录B之21点程序的重构 */ #include <stdio.h> typedef enum { NO , YES, } YESNO ; YESNO again( void ); void game_21( void ); int main( void ) { do{ game_21(); //一轮游戏 }while ( again() == YES ); return 0; } void game_21( void ) { //待完成 } YESNO again( void ) { int c; puts("继续游戏(Y/N)?"); c = getchar() ; while ( getchar() != '\n'){ //读完一行 } if ( c=='y' || c == 'Y' ){ return YES; } return NO; }
main()的含义很清晰,应该不用解释。这就是结构化程序设计所谓的“自顶向下”的魅力。
(未完待续)