• 劣质代码评析——《写给大家看的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()的含义很清晰,应该不用解释。这就是结构化程序设计所谓的“自顶向下”的魅力。

    (未完待续)

  • 相关阅读:
    百度Tera数据库介绍——类似cassandra,levelDB
    Cassandra——类似levelDB的基于p2p架构的分布式NOSQL数据库
    Greenplum——升级的分布式PostgresSQL
    Neo4j图数据库简介和底层原理
    445. Add Two Numbers II ——while s1 or s2 or carry 题目再简单也要些测试用例
    22. Generate Parentheses——本质:树,DFS求解可能的path
    LevelDb简单介绍和原理——本质:类似nedb,插入数据文件不断增长(快照),再通过删除老数据做更新
    es根据磁盘使用情况来决定是否分配shard
    ES mlockall作用——preventing that memory from being paged to the swap area
    我相信我会反击!围绕艰苦的开局迫使程序员初尝体验
  • 原文地址:https://www.cnblogs.com/pmer/p/3186634.html
Copyright © 2020-2023  润新知