Essential C++ 第一章,猜数代码分析ch1.cpp

 d
  1. /**************************************************
  2.  * Essential C++ -- Stanley Lippman
  3.  * Addison-Wesley 
  4.  * ISBN 0-201-48518-4
  5.  * homepage: www.objectwrite.com
  6.  * email: slippman@objectwrite.com
  7.  *************************************************/
  8. #include "ch1.h"
  9. pvec Fibonacci_gen_elems( int pos ) 
  10.     static vector<unsigned int> _elems;
  11.     if ( ! check_integrity( pos ))
  12.          return 0;
  13.     if ( _elems.empty() )
  14.        { _elems.push_back( 1 ); _elems.push_back( 1 ); }
  15.     if ( _elems.size() < pos )
  16.     {
  17.             int ix = _elems.size();
  18.             int n_2 = _elems[ ix-2 ], 
  19.                 n_1 = _elems[ ix-1 ];
  20.             int elem;
  21.             for ( ; ix < pos; ++ix ){
  22.                     elem = n_2 + n_1; 
  23.                     _elems.push_back( elem );
  24.                     n_2 = n_1; n_1 = elem;
  25.             }
  26.      }
  27.      return &_elems;
  28. }  
  29.    
  30. pvec Pell_gen_elems( int pos )    
  31.     static vector< unsigned int> _elems;
  32.     if ( ! check_integrity( pos ))
  33.          return 0;
  34.     if ( _elems.empty() )
  35.        {  _elems.push_back( 1 ); _elems.push_back( 2 ); }
  36.     if ( _elems.size() < pos )
  37.     {
  38.             int ix = _elems.size();
  39.             int n_2 = _elems[ ix-2 ], 
  40.                 n_1 = _elems[ ix-1 ];
  41.             int elem;
  42.             for ( ; ix < pos; ++ix ){
  43.                     elem = n_2 + 2 * n_1; 
  44.                     _elems.push_back( elem );
  45.                     n_2 = n_1; n_1 = elem;
  46.             }
  47.      }
  48.      return &_elems;
  49. }
  50.    
  51. pvec Lucas_gen_elems( int pos ) 
  52. {    
  53.     static vector<unsigned int> _elems;
  54.     if ( ! check_integrity( pos ))
  55.          return 0;
  56.     if ( _elems.empty() )
  57.        {  _elems.push_back( 1 ); _elems.push_back( 3 ); }
  58.     if ( _elems.size() < pos )
  59.     {
  60.             int ix = _elems.size();
  61.             int n_2 = _elems[ ix-2 ], 
  62.                 n_1 = _elems[ ix-1 ];
  63.             int elem;
  64.             for ( ; ix < pos; ++ix ){
  65.                     elem = n_2 +  n_1; 
  66.                     _elems.push_back( elem );
  67.                     n_2 = n_1; n_1 = elem;
  68.             }
  69.      }
  70.      return &_elems;
  71. }    
  72.    
  73. pvec Triangular_gen_elems( int pos ) 
  74. {
  75.     static vector<unsigned int> _elems;
  76.     if ( ! check_integrity( pos ))
  77.          return 0;
  78.     if ( _elems.size() < pos )
  79.     {
  80.         int ix = _elems.size() ? _elems.size()+1 : 1;
  81.         for ( ; ix <= pos; ++ix )
  82.               _elems.push_back( ix*(ix+1)/2 );
  83.     }
  84.     return &_elems;
  85. }
  86. pvec Square_gen_elems( int pos ) 
  87. {
  88.     static vector<unsigned int> _elems;
  89.     if ( ! check_integrity( pos ))
  90.          return 0;
  91.     if ( _elems.size() < pos )
  92.     {
  93.         int ix = _elems.size() ? _elems.size()+1 : 1;
  94.         for ( ; ix <= pos; ++ix )
  95.               _elems.push_back( ix*ix );
  96.     }
  97.     return &_elems;
  98. }   
  99.     
  100. pvec Pentagonal_gen_elems( int pos ) 
  101. {
  102.     static vector<unsigned int> _elems;
  103.     if ( ! check_integrity( pos ))
  104.          return 0;
  105.     if ( _elems.size() < pos )
  106.     {
  107.         int ix = _elems.size() ? _elems.size()+1 : 1;
  108.         for ( ; ix <= pos; ++ix )
  109.               _elems.push_back( ix*(3*ix-1)/2 );
  110.     }
  111.     return &_elems;
  112. }
  113. pfunc gen_elems[] = 
  114. { 0,
  115.   Fibonacci_gen_elems,
  116.   Pell_gen_elems,
  117.   Lucas_gen_elems,
  118.   Triangular_gen_elems,
  119.   Square_gen_elems,
  120.   Pentagonal_gen_elems
  121. };
  122. const char *name_seq[] = { "Invalid Sequence",
  123.    "Fibonacci""Pell""Lucas",
  124.    "Triangular""Square""Pentagonal"
  125. };
  126. int level_size[] = { 8, 8, 32, 128, 512 };
  127. const char* wrong_msg[] = {
  128.  "Oops! Nice guess but not quite it.",
  129.  "Hmm. Sorry. Wrong again.",
  130.  "Ah, this is harder than it looks, isn't it?",
  131.  "It must be getting pretty frustrating by now!"
  132. };
  133. void display_statistics( user_profile *puser )
  134. {
  135.     cout << "Game Statistics for " << puser->name << "/n/t"
  136.          << "# guesses: " << puser->guesses << "/n/t"
  137.          << "# correct: " << puser->correct << "/n/t"
  138.          << "% correct: " 
  139.          << (static_cast<float>( puser->correct ) / static_cast<float>( puser->guesses )) * 100 << endl;
  140. }
  141. bool greet_user( user_profile *puser )
  142. {
  143.       cout << "Hi. What's your name? ";
  144.       string nm;
  145.       cin >> nm;
  146.       if ( nm.empty() || nm[ 0 ] == ' ' ){
  147.            cout << "ok. I guess you don't want to play. See ya!/n";
  148.            return false;
  149.       }
  150.       cout << "Hi, " << nm
  151.            << " Would you like to play Guess the Sequence? (y/n) ";
  152.       char ch;
  153.       cin >> ch;
  154.       if ( ch != 'y' && ch != 'Y' ){
  155.            cout << "ok. I'm sorry you don't want to play./n";
  156.            return false;
  157.       }
  158.       cout << "/n/n" << "Hey, that's great, " << nm << "./n"
  159.            << "We'll start in just a moment./nIt/'s simple, really!/n"
  160.            << "I will print out two elements of a sequence/n"
  161.            << "You just answer with the element value that comes next!/n/n";
  162.       cout << "Oh, by the way, do you consider yourself a/n/t"
  163.            << "beginner     -- enter 1/n/t"
  164.            << "intermediate -- enter 2/n/t"
  165.            << "advanced     -- enter 3/n/t"
  166.            << "guru         -- enter 4/n/t" << endl;
  167.       int level;
  168.       cin >> level;
  169.       if ( level < 1 || level > 4) level = 4;
  170.       init_user( puser, nm, level );
  171.       return true;
  172. }
  173. void print_seq( user_profile *puser )
  174. {
  175.     for ( int i = 0; i < puser->cur_seq_vec->size(); ++i )
  176.           cout << (*puser->cur_seq_vec)[i] << ' ';
  177.     cout << endl;
  178. }
  179. void display_seq( user_profile *puser )
  180. {
  181.     pvec p = seq_vec( puser ); 
  182.     cout << "The first two elements of the series are: "
  183.          << (*p)[ puser->pos-3 ] << ", " << (*p)[ puser->pos-2 ] 
  184.          << "/nWhat is the next element? ";
  185. }
  186. void set_up_index( user_profile *puser )
  187. {
  188.     static string wherefrom( "set_up_index" );
  189.     // randomly pick a position within the sequence
  190.     puser->pos = rand() % ( level_size[ puser->level ] );
  191.     // position represents 
  192.     if ( puser->pos < 3 ) puser->pos += 3;
  193.     
  194.     set_seq_vec( puser, (*gen_elems[ puser->cur_seq ])( puser->pos ));
  195.     trace( wherefrom, "new position: ", puser->pos );
  196. }
  197. void reset_seq( user_profile *puser )
  198. {
  199.     static string wherefrom( "reset_seq" );
  200.     int new_seq = gen_seq_id( reinterpret_cast<unsigned int>( puser ));
  201.     if ( new_seq == puser->cur_seq )
  202.          new_seq = new_seq < ns_cnt ? new_seq+1 : 1;
  203.     puser->cur_seq = static_cast<num_sequence>( new_seq );
  204.     set_up_index( puser );
  205.     print_seq( puser );
  206.     trace( wherefrom, "new sequence: ", name_seq[ puser->cur_seq ]);
  207. }
  208. void init_user( user_profile *puser, const string& nm, int level )
  209. {
  210.     static string wherefrom( "init_user" );
  211.     puser->name = nm;
  212.     puser->guesses = 0;
  213.     puser->correct = 0;
  214.     puser->level = level;
  215.     reset_seq( puser );
  216.     trace( wherefrom, nm, puser->cur_seq, level );
  217. }   
  218. bool correct_guess( user_profile *puser, int guess )
  219. {
  220.     pvec p = seq_vec( puser ); 
  221.     if ( guess == (*p)[ puser->pos-1 ] )
  222.          return true;
  223.     return false;
  224. }
  225. void play_game( user_profile *puser )
  226. {
  227.     bool next_seq  = true;      // show next sequence?
  228.     bool go_for_it = true;      // user wants to guess?
  229.     bool got_it    = false;     // user guessed correctly?
  230.     int  num_tries;             // number of tries per sequence
  231.     while ( next_seq == true )
  232.     {
  233.         num_tries = 0;
  234.         display_seq( puser );
  235.         while (( got_it == false ) &&
  236.                ( go_for_it == true ))
  237.         {
  238.              unsigned int usr_guess;
  239.              cin >> usr_guess;
  240.               if ( correct_guess( puser, usr_guess ))
  241.               {
  242.                   bump_correct( puser );
  243.                   got_it = true;
  244.                   cout << "Hey, most excellent! /n/t"
  245.                        << usr_guess << " is element # "
  246.                        << puser->pos << " of the " 
  247.                        << name_seq[ puser->cur_seq ] << " sequence./n";
  248.               }
  249.               else 
  250.               {
  251.                   bump_guess( puser );
  252.                   cout << wrong_msg[ num_tries < ns_wrong_msg ? num_tries : ns_wrong_msg-1 ]
  253.                        << " Would you like to try again? (y/n) ";
  254.                   char usr_rsp;
  255.                   cin >> usr_rsp;
  256.  
  257.                   if ( usr_rsp == 'N' || usr_rsp == 'n' )
  258.                        go_for_it = false;
  259.                   else { ++num_tries; cout << "Your next guess? "; }
  260.               }
  261.         } 
  262.         cout << "Want to try another sequence? (y/n) ";
  263.         char try_again;
  264.         cin >> try_again;
  265.         if ( try_again == 'N' || try_again == 'n' )
  266.              next_seq = false;
  267.         else { got_it = false; reset_seq( puser ); }
  268.     }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值