zoukankan      html  css  js  c++  java
  • 劣质代码评析——《写给大家看的C语言书(第2版)》》附录B之21点程序(七)

    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("
    ");
    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("
    Play 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!
    
    ",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
    ","Jack");
    135.                 points[ACELOW] += 10;
    136.                 points[ACEHIGH] += 10;
    137.                 break;
    138.       case(12): printf("%s
    ","Queen");
    139.                 points[ACELOW] += 10;
    140.                 points[ACEHIGH] += 10;
    141.                 break;
    142.       case(13): printf("%s
    ","King");
    143.                 points[ACELOW] += 10;
    144.                 points[ACEHIGH] += 10;
    145.                 break;
    146.       default : points[ACELOW] += cardDrawn;
    147.                 if(cardDrawn==1)
    148.                 { 
    149.                    printf("%s
    ","Ace");
    150.                    points[ACEHIGH]+= 11;
    151.                 }
    152.                 else
    153.                 {  
    154.                   points[ACEHIGH]+=cardDrawn;
    155.                   printf("%d
    ",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
    
    ", total[PLAYER]);
    176.    }
    177.    else
    178.    {
    179.        printf("The house stands with a total of %d
    
    ", 
    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.
    ");
    190.        return ;
    191.    }
    192.    if ( (total[DEALER] > 21) && (total[PLAYER] > 21) )
    193.    { 
    194.       printf("%s", "Nobody wins.
    ");
    195.       return ; 
    196.    }
    197.    if ((total[DEALER] >= total[PLAYER])&& (total[DEALER] < 21))
    198.    { 
    199.       printf("The house wins.
    ");
    200.       return ; 
    201.    }
    202.    if ((total[PLAYER] > 21)&& (total[DEALER] < 21))
    203.    { 
    204.       printf("The house wins.
    ");
    205.       return ; 
    206.    }
    207.    printf("%s%c","You win!
    ",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("
    ");
    226.         i++; 
    227.    }
    228.    printf("
    
    *Step right up to the Blackjack tables*
    
    ");
    229.    return ;
    230. }
    View Code

      庄家抽牌结束后,就到了宣布胜负的时候。

    26. void findWinner(int total[2]);
    
    185. void findWinner(int total[2])
    186. {
    187.    if ( total[DEALER] ==  21 )
    188.    {
    189.        printf("The house wins.
    ");
    190.        return ;
    191.    }
    192.    if ( (total[DEALER] > 21) && (total[PLAYER] > 21) )
    193.    { 
    194.       printf("%s", "Nobody wins.
    ");
    195.       return ; 
    196.    }
    197.    if ((total[DEALER] >= total[PLAYER])&& (total[DEALER] < 21))
    198.    { 
    199.       printf("The house wins.
    ");
    200.       return ; 
    201.    }
    202.    if ((total[PLAYER] > 21)&& (total[DEALER] < 21))
    203.    { 
    204.       printf("The house wins.
    ");
    205.       return ; 
    206.    }
    207.    printf("%s%c","You win!
    ",BELL);
    208.    return;
    209. }

      这个函数写得比较乱,缺乏条理。改成下面的写法更清晰:

    void findWinner(int total[]);
    
    void findWinner(int total[])
    {
       if ( total[DEALER] == 21 )
       {
           printf("The house wins.
    ");
           return ;
       }
       
       if ( total[DEALER] > 21 )
       {
          if( total[PLAYER] > 21 )
          {
              printf("%s", "Nobody wins.
    ");
              return ;
          }
       }
       if ( total[DEALER] < 21 )
       {
          if( (total[PLAYER] > 21) )
           {
                printf("The house wins.
    ");
                return ;
           }
          if( (total[DEALER] >= total[PLAYER]) )
          {
              printf("The house wins.
    ");
              return ;
          }
       }
       
       printf("%s%c","You win!
    ",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() != '
    '){  //读完一行 
       } 
       
       if ( c=='y' || c == 'Y' ){
          return YES;
       }
       
       return NO;
    }
    

       main()的含义很清晰,应该不用解释。这就是结构化程序设计所谓的“自顶向下”的魅力。

    (未完待续)

  • 相关阅读:
    Java JMX 监管
    Spring Boot REST(一)核心接口
    JSR 规范目录
    【平衡树】宠物收养所 HNOI 2004
    【树型DP】叶子的颜色 OUROJ 1698
    【匈牙利匹配】无题II HDU2236
    【贪心】Communication System POJ 1018
    【贪心】Moving Tables POJ 1083
    Calling Extraterrestrial Intelligence Again POJ 1411
    【贪心】Allowance POJ 3040
  • 原文地址:https://www.cnblogs.com/pmer/p/3186634.html
Copyright © 2011-2022 走看看